12a48dd7cSBALATON Zoltan /*
2fa446fc5SBALATON Zoltan * QEMU PowerPC 4xx embedded processors SDRAM controller emulation
3fa446fc5SBALATON Zoltan *
4fa446fc5SBALATON Zoltan * DDR SDRAM controller:
5fa446fc5SBALATON Zoltan * Copyright (c) 2007 Jocelyn Mayer
6fa446fc5SBALATON Zoltan *
7fa446fc5SBALATON Zoltan * Permission is hereby granted, free of charge, to any person obtaining a copy
8fa446fc5SBALATON Zoltan * of this software and associated documentation files (the "Software"), to deal
9fa446fc5SBALATON Zoltan * in the Software without restriction, including without limitation the rights
10fa446fc5SBALATON Zoltan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11fa446fc5SBALATON Zoltan * copies of the Software, and to permit persons to whom the Software is
12fa446fc5SBALATON Zoltan * furnished to do so, subject to the following conditions:
13fa446fc5SBALATON Zoltan *
14fa446fc5SBALATON Zoltan * The above copyright notice and this permission notice shall be included in
15fa446fc5SBALATON Zoltan * all copies or substantial portions of the Software.
16fa446fc5SBALATON Zoltan *
17fa446fc5SBALATON Zoltan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18fa446fc5SBALATON Zoltan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19fa446fc5SBALATON Zoltan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20fa446fc5SBALATON Zoltan * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21fa446fc5SBALATON Zoltan * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22fa446fc5SBALATON Zoltan * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23fa446fc5SBALATON Zoltan * THE SOFTWARE.
24fa446fc5SBALATON Zoltan *
252a48dd7cSBALATON Zoltan * DDR2 SDRAM controller:
262a48dd7cSBALATON Zoltan * Copyright (c) 2012 François Revol
272a48dd7cSBALATON Zoltan * Copyright (c) 2016-2019 BALATON Zoltan
282a48dd7cSBALATON Zoltan *
292a48dd7cSBALATON Zoltan * This work is licensed under the GNU GPL license version 2 or later.
302a48dd7cSBALATON Zoltan */
312a48dd7cSBALATON Zoltan
322a48dd7cSBALATON Zoltan #include "qemu/osdep.h"
332a48dd7cSBALATON Zoltan #include "qemu/units.h"
342a48dd7cSBALATON Zoltan #include "qapi/error.h"
35fa446fc5SBALATON Zoltan #include "qemu/log.h"
36cc37d98bSRichard Henderson #include "qemu/error-report.h"
372a48dd7cSBALATON Zoltan #include "exec/address-spaces.h" /* get_system_memory() */
382a48dd7cSBALATON Zoltan #include "hw/irq.h"
392a48dd7cSBALATON Zoltan #include "hw/qdev-properties.h"
402a48dd7cSBALATON Zoltan #include "hw/ppc/ppc4xx.h"
412a48dd7cSBALATON Zoltan #include "trace.h"
422a48dd7cSBALATON Zoltan
432a48dd7cSBALATON Zoltan /*****************************************************************************/
442a48dd7cSBALATON Zoltan /* Shared functions */
452a48dd7cSBALATON Zoltan
46080741abSBALATON Zoltan /*
47080741abSBALATON Zoltan * Split RAM between SDRAM banks.
48080741abSBALATON Zoltan *
49080741abSBALATON Zoltan * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
50080741abSBALATON Zoltan * and must be 0-terminated.
51080741abSBALATON Zoltan *
52080741abSBALATON Zoltan * The 4xx SDRAM controller supports a small number of banks, and each bank
53080741abSBALATON Zoltan * must be one of a small set of sizes. The number of banks and the supported
54080741abSBALATON Zoltan * sizes varies by SoC.
55080741abSBALATON Zoltan */
ppc4xx_sdram_banks(MemoryRegion * ram,int nr_banks,Ppc4xxSdramBank ram_banks[],const ram_addr_t sdram_bank_sizes[],Error ** errp)56286787f1SBALATON Zoltan static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
57080741abSBALATON Zoltan Ppc4xxSdramBank ram_banks[],
58286787f1SBALATON Zoltan const ram_addr_t sdram_bank_sizes[],
59286787f1SBALATON Zoltan Error **errp)
60080741abSBALATON Zoltan {
61286787f1SBALATON Zoltan ERRP_GUARD();
62080741abSBALATON Zoltan ram_addr_t size_left = memory_region_size(ram);
63080741abSBALATON Zoltan ram_addr_t base = 0;
64080741abSBALATON Zoltan ram_addr_t bank_size;
65080741abSBALATON Zoltan int i;
66080741abSBALATON Zoltan int j;
67080741abSBALATON Zoltan
68080741abSBALATON Zoltan for (i = 0; i < nr_banks; i++) {
69080741abSBALATON Zoltan for (j = 0; sdram_bank_sizes[j] != 0; j++) {
70080741abSBALATON Zoltan bank_size = sdram_bank_sizes[j];
71080741abSBALATON Zoltan if (bank_size <= size_left) {
72080741abSBALATON Zoltan char name[32];
73080741abSBALATON Zoltan
74080741abSBALATON Zoltan ram_banks[i].base = base;
75080741abSBALATON Zoltan ram_banks[i].size = bank_size;
76080741abSBALATON Zoltan base += bank_size;
77080741abSBALATON Zoltan size_left -= bank_size;
78080741abSBALATON Zoltan snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
79080741abSBALATON Zoltan memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram,
80080741abSBALATON Zoltan ram_banks[i].base, ram_banks[i].size);
81080741abSBALATON Zoltan break;
82080741abSBALATON Zoltan }
83080741abSBALATON Zoltan }
84080741abSBALATON Zoltan if (!size_left) {
85080741abSBALATON Zoltan /* No need to use the remaining banks. */
86080741abSBALATON Zoltan break;
87080741abSBALATON Zoltan }
88080741abSBALATON Zoltan }
89080741abSBALATON Zoltan
90080741abSBALATON Zoltan if (size_left) {
91080741abSBALATON Zoltan ram_addr_t used_size = memory_region_size(ram) - size_left;
92080741abSBALATON Zoltan GString *s = g_string_new(NULL);
93080741abSBALATON Zoltan
94080741abSBALATON Zoltan for (i = 0; sdram_bank_sizes[i]; i++) {
95080741abSBALATON Zoltan g_string_append_printf(s, "%" PRIi64 "%s",
96080741abSBALATON Zoltan sdram_bank_sizes[i] / MiB,
97080741abSBALATON Zoltan sdram_bank_sizes[i + 1] ? ", " : "");
98080741abSBALATON Zoltan }
99286787f1SBALATON Zoltan error_setg(errp, "Invalid SDRAM banks");
100286787f1SBALATON Zoltan error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n",
101080741abSBALATON Zoltan nr_banks, nr_banks == 1 ? "" : "s", s->str);
102286787f1SBALATON Zoltan error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n",
103080741abSBALATON Zoltan used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
104080741abSBALATON Zoltan
105080741abSBALATON Zoltan g_string_free(s, true);
106286787f1SBALATON Zoltan return false;
107080741abSBALATON Zoltan }
108286787f1SBALATON Zoltan return true;
109080741abSBALATON Zoltan }
110080741abSBALATON Zoltan
sdram_bank_map(Ppc4xxSdramBank * bank)1112a48dd7cSBALATON Zoltan static void sdram_bank_map(Ppc4xxSdramBank *bank)
1122a48dd7cSBALATON Zoltan {
113424a660cSBALATON Zoltan trace_ppc4xx_sdram_map(bank->base, bank->size);
1142a48dd7cSBALATON Zoltan memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
1152a48dd7cSBALATON Zoltan memory_region_add_subregion(&bank->container, 0, &bank->ram);
1162a48dd7cSBALATON Zoltan memory_region_add_subregion(get_system_memory(), bank->base,
1172a48dd7cSBALATON Zoltan &bank->container);
1182a48dd7cSBALATON Zoltan }
1192a48dd7cSBALATON Zoltan
sdram_bank_unmap(Ppc4xxSdramBank * bank)1202a48dd7cSBALATON Zoltan static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
1212a48dd7cSBALATON Zoltan {
122424a660cSBALATON Zoltan trace_ppc4xx_sdram_unmap(bank->base, bank->size);
1232a48dd7cSBALATON Zoltan memory_region_del_subregion(get_system_memory(), &bank->container);
1242a48dd7cSBALATON Zoltan memory_region_del_subregion(&bank->container, &bank->ram);
1252a48dd7cSBALATON Zoltan object_unparent(OBJECT(&bank->container));
1262a48dd7cSBALATON Zoltan }
1272a48dd7cSBALATON Zoltan
sdram_bank_set_bcr(Ppc4xxSdramBank * bank,uint32_t bcr,hwaddr base,hwaddr size,int enabled)128424a660cSBALATON Zoltan static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr,
129424a660cSBALATON Zoltan hwaddr base, hwaddr size, int enabled)
130424a660cSBALATON Zoltan {
131424a660cSBALATON Zoltan if (memory_region_is_mapped(&bank->container)) {
132424a660cSBALATON Zoltan sdram_bank_unmap(bank);
133424a660cSBALATON Zoltan }
134424a660cSBALATON Zoltan bank->bcr = bcr;
135424a660cSBALATON Zoltan bank->base = base;
136424a660cSBALATON Zoltan bank->size = size;
137424a660cSBALATON Zoltan if (enabled && (bcr & 1)) {
138424a660cSBALATON Zoltan sdram_bank_map(bank);
139424a660cSBALATON Zoltan }
140424a660cSBALATON Zoltan }
141424a660cSBALATON Zoltan
1422a48dd7cSBALATON Zoltan enum {
1432a48dd7cSBALATON Zoltan SDRAM0_CFGADDR = 0x010,
1442a48dd7cSBALATON Zoltan SDRAM0_CFGDATA = 0x011,
1452a48dd7cSBALATON Zoltan };
1462a48dd7cSBALATON Zoltan
1472a48dd7cSBALATON Zoltan /*****************************************************************************/
148fa446fc5SBALATON Zoltan /* DDR SDRAM controller */
14954a3527eSBALATON Zoltan #define SDRAM_DDR_BCR_MASK 0xFFDEE001
15054a3527eSBALATON Zoltan
sdram_ddr_bcr(hwaddr ram_base,hwaddr ram_size)151fa446fc5SBALATON Zoltan static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
152fa446fc5SBALATON Zoltan {
153fa446fc5SBALATON Zoltan uint32_t bcr;
154fa446fc5SBALATON Zoltan
155fa446fc5SBALATON Zoltan switch (ram_size) {
156fa446fc5SBALATON Zoltan case 4 * MiB:
157fa446fc5SBALATON Zoltan bcr = 0;
158fa446fc5SBALATON Zoltan break;
159fa446fc5SBALATON Zoltan case 8 * MiB:
160fa446fc5SBALATON Zoltan bcr = 0x20000;
161fa446fc5SBALATON Zoltan break;
162fa446fc5SBALATON Zoltan case 16 * MiB:
163fa446fc5SBALATON Zoltan bcr = 0x40000;
164fa446fc5SBALATON Zoltan break;
165fa446fc5SBALATON Zoltan case 32 * MiB:
166fa446fc5SBALATON Zoltan bcr = 0x60000;
167fa446fc5SBALATON Zoltan break;
168fa446fc5SBALATON Zoltan case 64 * MiB:
169fa446fc5SBALATON Zoltan bcr = 0x80000;
170fa446fc5SBALATON Zoltan break;
171fa446fc5SBALATON Zoltan case 128 * MiB:
172fa446fc5SBALATON Zoltan bcr = 0xA0000;
173fa446fc5SBALATON Zoltan break;
174fa446fc5SBALATON Zoltan case 256 * MiB:
175fa446fc5SBALATON Zoltan bcr = 0xC0000;
176fa446fc5SBALATON Zoltan break;
177fa446fc5SBALATON Zoltan default:
178fa446fc5SBALATON Zoltan qemu_log_mask(LOG_GUEST_ERROR,
179fa446fc5SBALATON Zoltan "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
180fa446fc5SBALATON Zoltan ram_size);
181fa446fc5SBALATON Zoltan return 0;
182fa446fc5SBALATON Zoltan }
183fa446fc5SBALATON Zoltan bcr |= ram_base & 0xFF800000;
184fa446fc5SBALATON Zoltan bcr |= 1;
185fa446fc5SBALATON Zoltan
186fa446fc5SBALATON Zoltan return bcr;
187fa446fc5SBALATON Zoltan }
188fa446fc5SBALATON Zoltan
sdram_ddr_base(uint32_t bcr)189fa446fc5SBALATON Zoltan static inline hwaddr sdram_ddr_base(uint32_t bcr)
190fa446fc5SBALATON Zoltan {
191fa446fc5SBALATON Zoltan return bcr & 0xFF800000;
192fa446fc5SBALATON Zoltan }
193fa446fc5SBALATON Zoltan
sdram_ddr_size(uint32_t bcr)194c8c6d68aSBALATON Zoltan static hwaddr sdram_ddr_size(uint32_t bcr)
195fa446fc5SBALATON Zoltan {
1966c5aaee4SMarkus Armbruster int sh = (bcr >> 17) & 0x7;
197fa446fc5SBALATON Zoltan
198fa446fc5SBALATON Zoltan if (sh == 7) {
1996c5aaee4SMarkus Armbruster return -1;
200fa446fc5SBALATON Zoltan }
201fa446fc5SBALATON Zoltan
2026c5aaee4SMarkus Armbruster return (4 * MiB) << sh;
203fa446fc5SBALATON Zoltan }
204fa446fc5SBALATON Zoltan
sdram_ddr_dcr_read(void * opaque,int dcrn)205fa446fc5SBALATON Zoltan static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
206fa446fc5SBALATON Zoltan {
20761cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = opaque;
208fa446fc5SBALATON Zoltan uint32_t ret;
209fa446fc5SBALATON Zoltan
210fa446fc5SBALATON Zoltan switch (dcrn) {
211fa446fc5SBALATON Zoltan case SDRAM0_CFGADDR:
21261cfe0dfSBALATON Zoltan ret = s->addr;
213fa446fc5SBALATON Zoltan break;
214fa446fc5SBALATON Zoltan case SDRAM0_CFGDATA:
21561cfe0dfSBALATON Zoltan switch (s->addr) {
216fa446fc5SBALATON Zoltan case 0x00: /* SDRAM_BESR0 */
21761cfe0dfSBALATON Zoltan ret = s->besr0;
218fa446fc5SBALATON Zoltan break;
219fa446fc5SBALATON Zoltan case 0x08: /* SDRAM_BESR1 */
22061cfe0dfSBALATON Zoltan ret = s->besr1;
221fa446fc5SBALATON Zoltan break;
222fa446fc5SBALATON Zoltan case 0x10: /* SDRAM_BEAR */
22361cfe0dfSBALATON Zoltan ret = s->bear;
224fa446fc5SBALATON Zoltan break;
225fa446fc5SBALATON Zoltan case 0x20: /* SDRAM_CFG */
22661cfe0dfSBALATON Zoltan ret = s->cfg;
227fa446fc5SBALATON Zoltan break;
228fa446fc5SBALATON Zoltan case 0x24: /* SDRAM_STATUS */
22961cfe0dfSBALATON Zoltan ret = s->status;
230fa446fc5SBALATON Zoltan break;
231fa446fc5SBALATON Zoltan case 0x30: /* SDRAM_RTR */
23261cfe0dfSBALATON Zoltan ret = s->rtr;
233fa446fc5SBALATON Zoltan break;
234fa446fc5SBALATON Zoltan case 0x34: /* SDRAM_PMIT */
23561cfe0dfSBALATON Zoltan ret = s->pmit;
236fa446fc5SBALATON Zoltan break;
237fa446fc5SBALATON Zoltan case 0x40: /* SDRAM_B0CR */
23861cfe0dfSBALATON Zoltan ret = s->bank[0].bcr;
239fa446fc5SBALATON Zoltan break;
240fa446fc5SBALATON Zoltan case 0x44: /* SDRAM_B1CR */
24161cfe0dfSBALATON Zoltan ret = s->bank[1].bcr;
242fa446fc5SBALATON Zoltan break;
243fa446fc5SBALATON Zoltan case 0x48: /* SDRAM_B2CR */
24461cfe0dfSBALATON Zoltan ret = s->bank[2].bcr;
245fa446fc5SBALATON Zoltan break;
246fa446fc5SBALATON Zoltan case 0x4C: /* SDRAM_B3CR */
24761cfe0dfSBALATON Zoltan ret = s->bank[3].bcr;
248fa446fc5SBALATON Zoltan break;
249fa446fc5SBALATON Zoltan case 0x80: /* SDRAM_TR */
250fa446fc5SBALATON Zoltan ret = -1; /* ? */
251fa446fc5SBALATON Zoltan break;
252fa446fc5SBALATON Zoltan case 0x94: /* SDRAM_ECCCFG */
25361cfe0dfSBALATON Zoltan ret = s->ecccfg;
254fa446fc5SBALATON Zoltan break;
255fa446fc5SBALATON Zoltan case 0x98: /* SDRAM_ECCESR */
25661cfe0dfSBALATON Zoltan ret = s->eccesr;
257fa446fc5SBALATON Zoltan break;
258fa446fc5SBALATON Zoltan default: /* Error */
259fa446fc5SBALATON Zoltan ret = -1;
260fa446fc5SBALATON Zoltan break;
261fa446fc5SBALATON Zoltan }
262fa446fc5SBALATON Zoltan break;
263fa446fc5SBALATON Zoltan default:
264fa446fc5SBALATON Zoltan /* Avoid gcc warning */
265fa446fc5SBALATON Zoltan ret = 0;
266fa446fc5SBALATON Zoltan break;
267fa446fc5SBALATON Zoltan }
268fa446fc5SBALATON Zoltan
269fa446fc5SBALATON Zoltan return ret;
270fa446fc5SBALATON Zoltan }
271fa446fc5SBALATON Zoltan
sdram_ddr_dcr_write(void * opaque,int dcrn,uint32_t val)272fa446fc5SBALATON Zoltan static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
273fa446fc5SBALATON Zoltan {
27461cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = opaque;
27554a3527eSBALATON Zoltan int i;
276fa446fc5SBALATON Zoltan
277fa446fc5SBALATON Zoltan switch (dcrn) {
278fa446fc5SBALATON Zoltan case SDRAM0_CFGADDR:
27961cfe0dfSBALATON Zoltan s->addr = val;
280fa446fc5SBALATON Zoltan break;
281fa446fc5SBALATON Zoltan case SDRAM0_CFGDATA:
28261cfe0dfSBALATON Zoltan switch (s->addr) {
283fa446fc5SBALATON Zoltan case 0x00: /* SDRAM_BESR0 */
28461cfe0dfSBALATON Zoltan s->besr0 &= ~val;
285fa446fc5SBALATON Zoltan break;
286fa446fc5SBALATON Zoltan case 0x08: /* SDRAM_BESR1 */
28761cfe0dfSBALATON Zoltan s->besr1 &= ~val;
288fa446fc5SBALATON Zoltan break;
289fa446fc5SBALATON Zoltan case 0x10: /* SDRAM_BEAR */
29061cfe0dfSBALATON Zoltan s->bear = val;
291fa446fc5SBALATON Zoltan break;
292fa446fc5SBALATON Zoltan case 0x20: /* SDRAM_CFG */
293fa446fc5SBALATON Zoltan val &= 0xFFE00000;
29461cfe0dfSBALATON Zoltan if (!(s->cfg & 0x80000000) && (val & 0x80000000)) {
295fa446fc5SBALATON Zoltan trace_ppc4xx_sdram_enable("enable");
296fa446fc5SBALATON Zoltan /* validate all RAM mappings */
29754a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
29854a3527eSBALATON Zoltan if (s->bank[i].size) {
29954a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
30054a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size,
30154a3527eSBALATON Zoltan 1);
30254a3527eSBALATON Zoltan }
30354a3527eSBALATON Zoltan }
30461cfe0dfSBALATON Zoltan s->status &= ~0x80000000;
30561cfe0dfSBALATON Zoltan } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) {
306fa446fc5SBALATON Zoltan trace_ppc4xx_sdram_enable("disable");
307fa446fc5SBALATON Zoltan /* invalidate all RAM mappings */
30854a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
30954a3527eSBALATON Zoltan if (s->bank[i].size) {
31054a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
31154a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size,
31254a3527eSBALATON Zoltan 0);
31354a3527eSBALATON Zoltan }
31454a3527eSBALATON Zoltan }
31561cfe0dfSBALATON Zoltan s->status |= 0x80000000;
316fa446fc5SBALATON Zoltan }
31761cfe0dfSBALATON Zoltan if (!(s->cfg & 0x40000000) && (val & 0x40000000)) {
31861cfe0dfSBALATON Zoltan s->status |= 0x40000000;
31961cfe0dfSBALATON Zoltan } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) {
32061cfe0dfSBALATON Zoltan s->status &= ~0x40000000;
321fa446fc5SBALATON Zoltan }
32261cfe0dfSBALATON Zoltan s->cfg = val;
323fa446fc5SBALATON Zoltan break;
324fa446fc5SBALATON Zoltan case 0x24: /* SDRAM_STATUS */
325fa446fc5SBALATON Zoltan /* Read-only register */
326fa446fc5SBALATON Zoltan break;
327fa446fc5SBALATON Zoltan case 0x30: /* SDRAM_RTR */
32861cfe0dfSBALATON Zoltan s->rtr = val & 0x3FF80000;
329fa446fc5SBALATON Zoltan break;
330fa446fc5SBALATON Zoltan case 0x34: /* SDRAM_PMIT */
33161cfe0dfSBALATON Zoltan s->pmit = (val & 0xF8000000) | 0x07C00000;
332fa446fc5SBALATON Zoltan break;
333fa446fc5SBALATON Zoltan case 0x40: /* SDRAM_B0CR */
334fa446fc5SBALATON Zoltan case 0x44: /* SDRAM_B1CR */
335fa446fc5SBALATON Zoltan case 0x48: /* SDRAM_B2CR */
336fa446fc5SBALATON Zoltan case 0x4C: /* SDRAM_B3CR */
33754a3527eSBALATON Zoltan i = (s->addr - 0x40) / 4;
33854a3527eSBALATON Zoltan val &= SDRAM_DDR_BCR_MASK;
33954a3527eSBALATON Zoltan if (s->bank[i].size) {
34054a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], val,
34154a3527eSBALATON Zoltan sdram_ddr_base(val), sdram_ddr_size(val),
34254a3527eSBALATON Zoltan s->cfg & 0x80000000);
34354a3527eSBALATON Zoltan }
344fa446fc5SBALATON Zoltan break;
345fa446fc5SBALATON Zoltan case 0x80: /* SDRAM_TR */
34661cfe0dfSBALATON Zoltan s->tr = val & 0x018FC01F;
347fa446fc5SBALATON Zoltan break;
348fa446fc5SBALATON Zoltan case 0x94: /* SDRAM_ECCCFG */
34961cfe0dfSBALATON Zoltan s->ecccfg = val & 0x00F00000;
350fa446fc5SBALATON Zoltan break;
351fa446fc5SBALATON Zoltan case 0x98: /* SDRAM_ECCESR */
352fa446fc5SBALATON Zoltan val &= 0xFFF0F000;
35361cfe0dfSBALATON Zoltan if (s->eccesr == 0 && val != 0) {
35461cfe0dfSBALATON Zoltan qemu_irq_raise(s->irq);
35561cfe0dfSBALATON Zoltan } else if (s->eccesr != 0 && val == 0) {
35661cfe0dfSBALATON Zoltan qemu_irq_lower(s->irq);
357fa446fc5SBALATON Zoltan }
35861cfe0dfSBALATON Zoltan s->eccesr = val;
359fa446fc5SBALATON Zoltan break;
360fa446fc5SBALATON Zoltan default: /* Error */
361fa446fc5SBALATON Zoltan break;
362fa446fc5SBALATON Zoltan }
363fa446fc5SBALATON Zoltan break;
364fa446fc5SBALATON Zoltan }
365fa446fc5SBALATON Zoltan }
366fa446fc5SBALATON Zoltan
ppc4xx_sdram_ddr_reset(DeviceState * dev)367fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
368fa446fc5SBALATON Zoltan {
36961cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
370fa446fc5SBALATON Zoltan
37161cfe0dfSBALATON Zoltan s->addr = 0;
37261cfe0dfSBALATON Zoltan s->bear = 0;
37361cfe0dfSBALATON Zoltan s->besr0 = 0; /* No error */
37461cfe0dfSBALATON Zoltan s->besr1 = 0; /* No error */
37561cfe0dfSBALATON Zoltan s->cfg = 0;
37661cfe0dfSBALATON Zoltan s->ecccfg = 0; /* No ECC */
37761cfe0dfSBALATON Zoltan s->eccesr = 0; /* No error */
37861cfe0dfSBALATON Zoltan s->pmit = 0x07C00000;
37961cfe0dfSBALATON Zoltan s->rtr = 0x05F00000;
38061cfe0dfSBALATON Zoltan s->tr = 0x00854009;
381fa446fc5SBALATON Zoltan /* We pre-initialize RAM banks */
38261cfe0dfSBALATON Zoltan s->status = 0;
38361cfe0dfSBALATON Zoltan s->cfg = 0x00800000;
384fa446fc5SBALATON Zoltan }
385fa446fc5SBALATON Zoltan
ppc4xx_sdram_ddr_realize(DeviceState * dev,Error ** errp)386fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
387fa446fc5SBALATON Zoltan {
388fa446fc5SBALATON Zoltan Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
389fa446fc5SBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
390fa446fc5SBALATON Zoltan const ram_addr_t valid_bank_sizes[] = {
391fa446fc5SBALATON Zoltan 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
392fa446fc5SBALATON Zoltan };
39354a3527eSBALATON Zoltan int i;
394fa446fc5SBALATON Zoltan
395fa446fc5SBALATON Zoltan if (s->nbanks < 1 || s->nbanks > 4) {
396fa446fc5SBALATON Zoltan error_setg(errp, "Invalid number of RAM banks");
397fa446fc5SBALATON Zoltan return;
398fa446fc5SBALATON Zoltan }
399fa446fc5SBALATON Zoltan if (!s->dram_mr) {
400fa446fc5SBALATON Zoltan error_setg(errp, "Missing dram memory region");
401fa446fc5SBALATON Zoltan return;
402fa446fc5SBALATON Zoltan }
403286787f1SBALATON Zoltan if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
404286787f1SBALATON Zoltan valid_bank_sizes, errp)) {
405286787f1SBALATON Zoltan return;
406286787f1SBALATON Zoltan }
40754a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
40854a3527eSBALATON Zoltan if (s->bank[i].size) {
40954a3527eSBALATON Zoltan s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size);
41054a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
41154a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size, 0);
41254a3527eSBALATON Zoltan } else {
41354a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
41454a3527eSBALATON Zoltan }
41554a3527eSBALATON Zoltan trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr),
41654a3527eSBALATON Zoltan sdram_ddr_size(s->bank[i].bcr),
41754a3527eSBALATON Zoltan s->bank[i].bcr);
41854a3527eSBALATON Zoltan }
419fa446fc5SBALATON Zoltan
420fa446fc5SBALATON Zoltan sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
421fa446fc5SBALATON Zoltan
422fa446fc5SBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
423fa446fc5SBALATON Zoltan s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
424fa446fc5SBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
425fa446fc5SBALATON Zoltan s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
426fa446fc5SBALATON Zoltan }
427fa446fc5SBALATON Zoltan
428fa446fc5SBALATON Zoltan static Property ppc4xx_sdram_ddr_props[] = {
429fa446fc5SBALATON Zoltan DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
430fa446fc5SBALATON Zoltan MemoryRegion *),
431fa446fc5SBALATON Zoltan DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
432fa446fc5SBALATON Zoltan DEFINE_PROP_END_OF_LIST(),
433fa446fc5SBALATON Zoltan };
434fa446fc5SBALATON Zoltan
ppc4xx_sdram_ddr_class_init(ObjectClass * oc,void * data)435fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
436fa446fc5SBALATON Zoltan {
437fa446fc5SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc);
438fa446fc5SBALATON Zoltan
439fa446fc5SBALATON Zoltan dc->realize = ppc4xx_sdram_ddr_realize;
440*e3d08143SPeter Maydell device_class_set_legacy_reset(dc, ppc4xx_sdram_ddr_reset);
441fa446fc5SBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */
442fa446fc5SBALATON Zoltan dc->user_creatable = false;
443fa446fc5SBALATON Zoltan device_class_set_props(dc, ppc4xx_sdram_ddr_props);
444fa446fc5SBALATON Zoltan }
445fa446fc5SBALATON Zoltan
ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState * s)446fa446fc5SBALATON Zoltan void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s)
447fa446fc5SBALATON Zoltan {
448fa446fc5SBALATON Zoltan sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
449fa446fc5SBALATON Zoltan sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
450fa446fc5SBALATON Zoltan }
451fa446fc5SBALATON Zoltan
452fa446fc5SBALATON Zoltan /*****************************************************************************/
4532a48dd7cSBALATON Zoltan /* DDR2 SDRAM controller */
454424a660cSBALATON Zoltan #define SDRAM_DDR2_BCR_MASK 0xffe0ffc1
455424a660cSBALATON Zoltan
4562a48dd7cSBALATON Zoltan enum {
4572a48dd7cSBALATON Zoltan SDRAM_R0BAS = 0x40,
4582a48dd7cSBALATON Zoltan SDRAM_R1BAS,
4592a48dd7cSBALATON Zoltan SDRAM_R2BAS,
4602a48dd7cSBALATON Zoltan SDRAM_R3BAS,
4612a48dd7cSBALATON Zoltan SDRAM_CONF1HB = 0x45,
4622a48dd7cSBALATON Zoltan SDRAM_PLBADDULL = 0x4a,
4632a48dd7cSBALATON Zoltan SDRAM_CONF1LL = 0x4b,
4642a48dd7cSBALATON Zoltan SDRAM_CONFPATHB = 0x4f,
4652a48dd7cSBALATON Zoltan SDRAM_PLBADDUHB = 0x50,
4662a48dd7cSBALATON Zoltan };
4672a48dd7cSBALATON Zoltan
sdram_ddr2_bcr(hwaddr ram_base,hwaddr ram_size)4682a48dd7cSBALATON Zoltan static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
4692a48dd7cSBALATON Zoltan {
4702a48dd7cSBALATON Zoltan uint32_t bcr;
4712a48dd7cSBALATON Zoltan
4722a48dd7cSBALATON Zoltan switch (ram_size) {
4732a48dd7cSBALATON Zoltan case 8 * MiB:
4742a48dd7cSBALATON Zoltan bcr = 0xffc0;
4752a48dd7cSBALATON Zoltan break;
4762a48dd7cSBALATON Zoltan case 16 * MiB:
4772a48dd7cSBALATON Zoltan bcr = 0xff80;
4782a48dd7cSBALATON Zoltan break;
4792a48dd7cSBALATON Zoltan case 32 * MiB:
4802a48dd7cSBALATON Zoltan bcr = 0xff00;
4812a48dd7cSBALATON Zoltan break;
4822a48dd7cSBALATON Zoltan case 64 * MiB:
4832a48dd7cSBALATON Zoltan bcr = 0xfe00;
4842a48dd7cSBALATON Zoltan break;
4852a48dd7cSBALATON Zoltan case 128 * MiB:
4862a48dd7cSBALATON Zoltan bcr = 0xfc00;
4872a48dd7cSBALATON Zoltan break;
4882a48dd7cSBALATON Zoltan case 256 * MiB:
4892a48dd7cSBALATON Zoltan bcr = 0xf800;
4902a48dd7cSBALATON Zoltan break;
4912a48dd7cSBALATON Zoltan case 512 * MiB:
4922a48dd7cSBALATON Zoltan bcr = 0xf000;
4932a48dd7cSBALATON Zoltan break;
4942a48dd7cSBALATON Zoltan case 1 * GiB:
4952a48dd7cSBALATON Zoltan bcr = 0xe000;
4962a48dd7cSBALATON Zoltan break;
4972a48dd7cSBALATON Zoltan case 2 * GiB:
4982a48dd7cSBALATON Zoltan bcr = 0xc000;
4992a48dd7cSBALATON Zoltan break;
5002a48dd7cSBALATON Zoltan case 4 * GiB:
5012a48dd7cSBALATON Zoltan bcr = 0x8000;
5022a48dd7cSBALATON Zoltan break;
5032a48dd7cSBALATON Zoltan default:
504883f2c59SPhilippe Mathieu-Daudé error_report("invalid RAM size " HWADDR_FMT_plx, ram_size);
5052a48dd7cSBALATON Zoltan return 0;
5062a48dd7cSBALATON Zoltan }
5072a48dd7cSBALATON Zoltan bcr |= ram_base >> 2 & 0xffe00000;
5082a48dd7cSBALATON Zoltan bcr |= 1;
5092a48dd7cSBALATON Zoltan
5102a48dd7cSBALATON Zoltan return bcr;
5112a48dd7cSBALATON Zoltan }
5122a48dd7cSBALATON Zoltan
sdram_ddr2_base(uint32_t bcr)5132a48dd7cSBALATON Zoltan static inline hwaddr sdram_ddr2_base(uint32_t bcr)
5142a48dd7cSBALATON Zoltan {
5152a48dd7cSBALATON Zoltan return (bcr & 0xffe00000) << 2;
5162a48dd7cSBALATON Zoltan }
5172a48dd7cSBALATON Zoltan
sdram_ddr2_size(uint32_t bcr)518c8c6d68aSBALATON Zoltan static hwaddr sdram_ddr2_size(uint32_t bcr)
5192a48dd7cSBALATON Zoltan {
5202a48dd7cSBALATON Zoltan int sh;
5212a48dd7cSBALATON Zoltan
5222a48dd7cSBALATON Zoltan sh = 1024 - ((bcr >> 6) & 0x3ff);
52366997c42SMarkus Armbruster return 8 * MiB * sh;
5242a48dd7cSBALATON Zoltan }
5252a48dd7cSBALATON Zoltan
sdram_ddr2_dcr_read(void * opaque,int dcrn)5262a48dd7cSBALATON Zoltan static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
5272a48dd7cSBALATON Zoltan {
52861cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = opaque;
5292a48dd7cSBALATON Zoltan uint32_t ret = 0;
5302a48dd7cSBALATON Zoltan
5312a48dd7cSBALATON Zoltan switch (dcrn) {
5322a48dd7cSBALATON Zoltan case SDRAM_R0BAS:
5332a48dd7cSBALATON Zoltan case SDRAM_R1BAS:
5342a48dd7cSBALATON Zoltan case SDRAM_R2BAS:
5352a48dd7cSBALATON Zoltan case SDRAM_R3BAS:
53661cfe0dfSBALATON Zoltan if (s->bank[dcrn - SDRAM_R0BAS].size) {
53761cfe0dfSBALATON Zoltan ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base,
53861cfe0dfSBALATON Zoltan s->bank[dcrn - SDRAM_R0BAS].size);
5392a48dd7cSBALATON Zoltan }
5402a48dd7cSBALATON Zoltan break;
5412a48dd7cSBALATON Zoltan case SDRAM_CONF1HB:
5422a48dd7cSBALATON Zoltan case SDRAM_CONF1LL:
5432a48dd7cSBALATON Zoltan case SDRAM_CONFPATHB:
5442a48dd7cSBALATON Zoltan case SDRAM_PLBADDULL:
5452a48dd7cSBALATON Zoltan case SDRAM_PLBADDUHB:
5462a48dd7cSBALATON Zoltan break;
5472a48dd7cSBALATON Zoltan case SDRAM0_CFGADDR:
54861cfe0dfSBALATON Zoltan ret = s->addr;
5492a48dd7cSBALATON Zoltan break;
5502a48dd7cSBALATON Zoltan case SDRAM0_CFGDATA:
55161cfe0dfSBALATON Zoltan switch (s->addr) {
5522a48dd7cSBALATON Zoltan case 0x14: /* SDRAM_MCSTAT (405EX) */
5532a48dd7cSBALATON Zoltan case 0x1F:
5542a48dd7cSBALATON Zoltan ret = 0x80000000;
5552a48dd7cSBALATON Zoltan break;
5562a48dd7cSBALATON Zoltan case 0x21: /* SDRAM_MCOPT2 */
55761cfe0dfSBALATON Zoltan ret = s->mcopt2;
5582a48dd7cSBALATON Zoltan break;
5592a48dd7cSBALATON Zoltan case 0x40: /* SDRAM_MB0CF */
5602a48dd7cSBALATON Zoltan ret = 0x00008001;
5612a48dd7cSBALATON Zoltan break;
5622a48dd7cSBALATON Zoltan case 0x7A: /* SDRAM_DLCR */
5632a48dd7cSBALATON Zoltan ret = 0x02000000;
5642a48dd7cSBALATON Zoltan break;
5652a48dd7cSBALATON Zoltan case 0xE1: /* SDR0_DDR0 */
5662a48dd7cSBALATON Zoltan ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
5672a48dd7cSBALATON Zoltan break;
5682a48dd7cSBALATON Zoltan default:
5692a48dd7cSBALATON Zoltan break;
5702a48dd7cSBALATON Zoltan }
5712a48dd7cSBALATON Zoltan break;
5722a48dd7cSBALATON Zoltan default:
5732a48dd7cSBALATON Zoltan break;
5742a48dd7cSBALATON Zoltan }
5752a48dd7cSBALATON Zoltan
5762a48dd7cSBALATON Zoltan return ret;
5772a48dd7cSBALATON Zoltan }
5782a48dd7cSBALATON Zoltan
5792a48dd7cSBALATON Zoltan #define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
5802a48dd7cSBALATON Zoltan
sdram_ddr2_dcr_write(void * opaque,int dcrn,uint32_t val)5812a48dd7cSBALATON Zoltan static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
5822a48dd7cSBALATON Zoltan {
58361cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = opaque;
584424a660cSBALATON Zoltan int i;
5852a48dd7cSBALATON Zoltan
5862a48dd7cSBALATON Zoltan switch (dcrn) {
5872a48dd7cSBALATON Zoltan case SDRAM_R0BAS:
5882a48dd7cSBALATON Zoltan case SDRAM_R1BAS:
5892a48dd7cSBALATON Zoltan case SDRAM_R2BAS:
5902a48dd7cSBALATON Zoltan case SDRAM_R3BAS:
5912a48dd7cSBALATON Zoltan case SDRAM_CONF1HB:
5922a48dd7cSBALATON Zoltan case SDRAM_CONF1LL:
5932a48dd7cSBALATON Zoltan case SDRAM_CONFPATHB:
5942a48dd7cSBALATON Zoltan case SDRAM_PLBADDULL:
5952a48dd7cSBALATON Zoltan case SDRAM_PLBADDUHB:
5962a48dd7cSBALATON Zoltan break;
5972a48dd7cSBALATON Zoltan case SDRAM0_CFGADDR:
59861cfe0dfSBALATON Zoltan s->addr = val;
5992a48dd7cSBALATON Zoltan break;
6002a48dd7cSBALATON Zoltan case SDRAM0_CFGDATA:
60161cfe0dfSBALATON Zoltan switch (s->addr) {
6022a48dd7cSBALATON Zoltan case 0x00: /* B0CR */
6032a48dd7cSBALATON Zoltan break;
6042a48dd7cSBALATON Zoltan case 0x21: /* SDRAM_MCOPT2 */
60561cfe0dfSBALATON Zoltan if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
6062a48dd7cSBALATON Zoltan (val & SDRAM_DDR2_MCOPT2_DCEN)) {
6072a48dd7cSBALATON Zoltan trace_ppc4xx_sdram_enable("enable");
6082a48dd7cSBALATON Zoltan /* validate all RAM mappings */
609424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
610424a660cSBALATON Zoltan if (s->bank[i].size) {
611424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
612424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size,
613424a660cSBALATON Zoltan 1);
614424a660cSBALATON Zoltan }
615424a660cSBALATON Zoltan }
61661cfe0dfSBALATON Zoltan s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
61761cfe0dfSBALATON Zoltan } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
6182a48dd7cSBALATON Zoltan !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
6192a48dd7cSBALATON Zoltan trace_ppc4xx_sdram_enable("disable");
6202a48dd7cSBALATON Zoltan /* invalidate all RAM mappings */
621424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
622424a660cSBALATON Zoltan if (s->bank[i].size) {
623424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
624424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size,
625424a660cSBALATON Zoltan 0);
626424a660cSBALATON Zoltan }
627424a660cSBALATON Zoltan }
62861cfe0dfSBALATON Zoltan s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
6292a48dd7cSBALATON Zoltan }
6302a48dd7cSBALATON Zoltan break;
6312a48dd7cSBALATON Zoltan default:
6322a48dd7cSBALATON Zoltan break;
6332a48dd7cSBALATON Zoltan }
6342a48dd7cSBALATON Zoltan break;
6352a48dd7cSBALATON Zoltan default:
6362a48dd7cSBALATON Zoltan break;
6372a48dd7cSBALATON Zoltan }
6382a48dd7cSBALATON Zoltan }
6392a48dd7cSBALATON Zoltan
ppc4xx_sdram_ddr2_reset(DeviceState * dev)6402a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
6412a48dd7cSBALATON Zoltan {
64261cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
6432a48dd7cSBALATON Zoltan
64461cfe0dfSBALATON Zoltan s->addr = 0;
64561cfe0dfSBALATON Zoltan s->mcopt2 = 0;
6462a48dd7cSBALATON Zoltan }
6472a48dd7cSBALATON Zoltan
ppc4xx_sdram_ddr2_realize(DeviceState * dev,Error ** errp)6482a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
6492a48dd7cSBALATON Zoltan {
6502a48dd7cSBALATON Zoltan Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
6512a48dd7cSBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
6522a48dd7cSBALATON Zoltan /*
6532a48dd7cSBALATON Zoltan * SoC also has 4 GiB but that causes problem with 32 bit
6542a48dd7cSBALATON Zoltan * builds (4*GiB overflows the 32 bit ram_addr_t).
6552a48dd7cSBALATON Zoltan */
6562a48dd7cSBALATON Zoltan const ram_addr_t valid_bank_sizes[] = {
6572a48dd7cSBALATON Zoltan 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB,
6582a48dd7cSBALATON Zoltan 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
6592a48dd7cSBALATON Zoltan };
660424a660cSBALATON Zoltan int i;
6612a48dd7cSBALATON Zoltan
6622a48dd7cSBALATON Zoltan if (s->nbanks < 1 || s->nbanks > 4) {
6632a48dd7cSBALATON Zoltan error_setg(errp, "Invalid number of RAM banks");
6642a48dd7cSBALATON Zoltan return;
6652a48dd7cSBALATON Zoltan }
6662a48dd7cSBALATON Zoltan if (!s->dram_mr) {
6672a48dd7cSBALATON Zoltan error_setg(errp, "Missing dram memory region");
6682a48dd7cSBALATON Zoltan return;
6692a48dd7cSBALATON Zoltan }
670286787f1SBALATON Zoltan if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
671286787f1SBALATON Zoltan valid_bank_sizes, errp)) {
672286787f1SBALATON Zoltan return;
673286787f1SBALATON Zoltan }
674424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) {
675424a660cSBALATON Zoltan if (s->bank[i].size) {
676424a660cSBALATON Zoltan s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size);
677424a660cSBALATON Zoltan s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK;
678424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
679424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size, 0);
680424a660cSBALATON Zoltan } else {
681424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
682424a660cSBALATON Zoltan }
683424a660cSBALATON Zoltan trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr),
684424a660cSBALATON Zoltan sdram_ddr2_size(s->bank[i].bcr),
685424a660cSBALATON Zoltan s->bank[i].bcr);
686424a660cSBALATON Zoltan }
6872a48dd7cSBALATON Zoltan
6882a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
6892a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
6902a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
6912a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
6922a48dd7cSBALATON Zoltan
6932a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R0BAS,
6942a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
6952a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R1BAS,
6962a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
6972a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R2BAS,
6982a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
6992a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R3BAS,
7002a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7012a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONF1HB,
7022a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7032a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL,
7042a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7052a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONF1LL,
7062a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7072a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB,
7082a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7092a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB,
7102a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
7112a48dd7cSBALATON Zoltan }
7122a48dd7cSBALATON Zoltan
7132a48dd7cSBALATON Zoltan static Property ppc4xx_sdram_ddr2_props[] = {
7142a48dd7cSBALATON Zoltan DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION,
7152a48dd7cSBALATON Zoltan MemoryRegion *),
7162a48dd7cSBALATON Zoltan DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4),
7172a48dd7cSBALATON Zoltan DEFINE_PROP_END_OF_LIST(),
7182a48dd7cSBALATON Zoltan };
7192a48dd7cSBALATON Zoltan
ppc4xx_sdram_ddr2_class_init(ObjectClass * oc,void * data)7202a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data)
7212a48dd7cSBALATON Zoltan {
7222a48dd7cSBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc);
7232a48dd7cSBALATON Zoltan
7242a48dd7cSBALATON Zoltan dc->realize = ppc4xx_sdram_ddr2_realize;
725*e3d08143SPeter Maydell device_class_set_legacy_reset(dc, ppc4xx_sdram_ddr2_reset);
7262a48dd7cSBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */
7272a48dd7cSBALATON Zoltan dc->user_creatable = false;
7282a48dd7cSBALATON Zoltan device_class_set_props(dc, ppc4xx_sdram_ddr2_props);
7292a48dd7cSBALATON Zoltan }
7302a48dd7cSBALATON Zoltan
ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State * s)7312a48dd7cSBALATON Zoltan void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
7322a48dd7cSBALATON Zoltan {
7332a48dd7cSBALATON Zoltan sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
7342a48dd7cSBALATON Zoltan sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
7352a48dd7cSBALATON Zoltan }
7362a48dd7cSBALATON Zoltan
7372a48dd7cSBALATON Zoltan static const TypeInfo ppc4xx_sdram_types[] = {
7382a48dd7cSBALATON Zoltan {
739fa446fc5SBALATON Zoltan .name = TYPE_PPC4xx_SDRAM_DDR,
740fa446fc5SBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE,
741fa446fc5SBALATON Zoltan .instance_size = sizeof(Ppc4xxSdramDdrState),
742fa446fc5SBALATON Zoltan .class_init = ppc4xx_sdram_ddr_class_init,
743fa446fc5SBALATON Zoltan }, {
7442a48dd7cSBALATON Zoltan .name = TYPE_PPC4xx_SDRAM_DDR2,
7452a48dd7cSBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE,
7462a48dd7cSBALATON Zoltan .instance_size = sizeof(Ppc4xxSdramDdr2State),
7472a48dd7cSBALATON Zoltan .class_init = ppc4xx_sdram_ddr2_class_init,
7482a48dd7cSBALATON Zoltan }
7492a48dd7cSBALATON Zoltan };
7502a48dd7cSBALATON Zoltan
7512a48dd7cSBALATON Zoltan DEFINE_TYPES(ppc4xx_sdram_types)
752