xref: /openbmc/qemu/hw/ppc/ppc4xx_sdram.c (revision 080741abc293e79b6e860e2c8d66bfe519090c86)
1 /*
2  * QEMU PowerPC 4xx embedded processors SDRAM controller emulation
3  *
4  * DDR SDRAM controller:
5  * Copyright (c) 2007 Jocelyn Mayer
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  * DDR2 SDRAM controller:
26  * Copyright (c) 2012 François Revol
27  * Copyright (c) 2016-2019 BALATON Zoltan
28  *
29  * This work is licensed under the GNU GPL license version 2 or later.
30  */
31 
32 #include "qemu/osdep.h"
33 #include "qemu/units.h"
34 #include "qapi/error.h"
35 #include "qemu/log.h"
36 #include "exec/address-spaces.h" /* get_system_memory() */
37 #include "exec/cpu-defs.h" /* target_ulong */
38 #include "hw/irq.h"
39 #include "hw/qdev-properties.h"
40 #include "hw/ppc/ppc4xx.h"
41 #include "trace.h"
42 
43 /*****************************************************************************/
44 /* Shared functions */
45 
46 /*
47  * Split RAM between SDRAM banks.
48  *
49  * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
50  * and must be 0-terminated.
51  *
52  * The 4xx SDRAM controller supports a small number of banks, and each bank
53  * must be one of a small set of sizes. The number of banks and the supported
54  * sizes varies by SoC.
55  */
56 static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
57                                Ppc4xxSdramBank ram_banks[],
58                                const ram_addr_t sdram_bank_sizes[])
59 {
60     ram_addr_t size_left = memory_region_size(ram);
61     ram_addr_t base = 0;
62     ram_addr_t bank_size;
63     int i;
64     int j;
65 
66     for (i = 0; i < nr_banks; i++) {
67         for (j = 0; sdram_bank_sizes[j] != 0; j++) {
68             bank_size = sdram_bank_sizes[j];
69             if (bank_size <= size_left) {
70                 char name[32];
71 
72                 ram_banks[i].base = base;
73                 ram_banks[i].size = bank_size;
74                 base += bank_size;
75                 size_left -= bank_size;
76                 snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
77                 memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram,
78                                          ram_banks[i].base, ram_banks[i].size);
79                 break;
80             }
81         }
82         if (!size_left) {
83             /* No need to use the remaining banks. */
84             break;
85         }
86     }
87 
88     if (size_left) {
89         ram_addr_t used_size = memory_region_size(ram) - size_left;
90         GString *s = g_string_new(NULL);
91 
92         for (i = 0; sdram_bank_sizes[i]; i++) {
93             g_string_append_printf(s, "%" PRIi64 "%s",
94                                    sdram_bank_sizes[i] / MiB,
95                                    sdram_bank_sizes[i + 1] ? ", " : "");
96         }
97         error_report("at most %d bank%s of %s MiB each supported",
98                      nr_banks, nr_banks == 1 ? "" : "s", s->str);
99         error_printf("Possible valid RAM size: %" PRIi64 " MiB\n",
100             used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
101 
102         g_string_free(s, true);
103         exit(EXIT_FAILURE);
104     }
105 }
106 
107 static void sdram_bank_map(Ppc4xxSdramBank *bank)
108 {
109     memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
110     memory_region_add_subregion(&bank->container, 0, &bank->ram);
111     memory_region_add_subregion(get_system_memory(), bank->base,
112                                 &bank->container);
113 }
114 
115 static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
116 {
117     memory_region_del_subregion(get_system_memory(), &bank->container);
118     memory_region_del_subregion(&bank->container, &bank->ram);
119     object_unparent(OBJECT(&bank->container));
120 }
121 
122 enum {
123     SDRAM0_CFGADDR = 0x010,
124     SDRAM0_CFGDATA = 0x011,
125 };
126 
127 /*****************************************************************************/
128 /* DDR SDRAM controller */
129 /*
130  * XXX: TOFIX: some patches have made this code become inconsistent:
131  *      there are type inconsistencies, mixing hwaddr, target_ulong
132  *      and uint32_t
133  */
134 static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
135 {
136     uint32_t bcr;
137 
138     switch (ram_size) {
139     case 4 * MiB:
140         bcr = 0;
141         break;
142     case 8 * MiB:
143         bcr = 0x20000;
144         break;
145     case 16 * MiB:
146         bcr = 0x40000;
147         break;
148     case 32 * MiB:
149         bcr = 0x60000;
150         break;
151     case 64 * MiB:
152         bcr = 0x80000;
153         break;
154     case 128 * MiB:
155         bcr = 0xA0000;
156         break;
157     case 256 * MiB:
158         bcr = 0xC0000;
159         break;
160     default:
161         qemu_log_mask(LOG_GUEST_ERROR,
162                       "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
163                       ram_size);
164         return 0;
165     }
166     bcr |= ram_base & 0xFF800000;
167     bcr |= 1;
168 
169     return bcr;
170 }
171 
172 static inline hwaddr sdram_ddr_base(uint32_t bcr)
173 {
174     return bcr & 0xFF800000;
175 }
176 
177 static target_ulong sdram_ddr_size(uint32_t bcr)
178 {
179     target_ulong size;
180     int sh;
181 
182     sh = (bcr >> 17) & 0x7;
183     if (sh == 7) {
184         size = -1;
185     } else {
186         size = (4 * MiB) << sh;
187     }
188 
189     return size;
190 }
191 
192 static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
193                               uint32_t bcr, int enabled)
194 {
195     if (sdram->bank[i].bcr & 1) {
196         /* Unmap RAM */
197         trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
198                                  sdram_ddr_size(sdram->bank[i].bcr));
199         memory_region_del_subregion(get_system_memory(),
200                                     &sdram->bank[i].container);
201         memory_region_del_subregion(&sdram->bank[i].container,
202                                     &sdram->bank[i].ram);
203         object_unparent(OBJECT(&sdram->bank[i].container));
204     }
205     sdram->bank[i].bcr = bcr & 0xFFDEE001;
206     if (enabled && (bcr & 1)) {
207         trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr));
208         memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
209                            sdram_ddr_size(bcr));
210         memory_region_add_subregion(&sdram->bank[i].container, 0,
211                                     &sdram->bank[i].ram);
212         memory_region_add_subregion(get_system_memory(),
213                                     sdram_ddr_base(bcr),
214                                     &sdram->bank[i].container);
215     }
216 }
217 
218 static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram)
219 {
220     int i;
221 
222     for (i = 0; i < sdram->nbanks; i++) {
223         if (sdram->bank[i].size != 0) {
224             sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
225                                                       sdram->bank[i].size), 1);
226         } else {
227             sdram_ddr_set_bcr(sdram, i, 0, 0);
228         }
229     }
230 }
231 
232 static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram)
233 {
234     int i;
235 
236     for (i = 0; i < sdram->nbanks; i++) {
237         trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
238                                  sdram_ddr_size(sdram->bank[i].bcr));
239         memory_region_del_subregion(get_system_memory(),
240                                     &sdram->bank[i].ram);
241     }
242 }
243 
244 static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
245 {
246     Ppc4xxSdramDdrState *sdram = opaque;
247     uint32_t ret;
248 
249     switch (dcrn) {
250     case SDRAM0_CFGADDR:
251         ret = sdram->addr;
252         break;
253     case SDRAM0_CFGDATA:
254         switch (sdram->addr) {
255         case 0x00: /* SDRAM_BESR0 */
256             ret = sdram->besr0;
257             break;
258         case 0x08: /* SDRAM_BESR1 */
259             ret = sdram->besr1;
260             break;
261         case 0x10: /* SDRAM_BEAR */
262             ret = sdram->bear;
263             break;
264         case 0x20: /* SDRAM_CFG */
265             ret = sdram->cfg;
266             break;
267         case 0x24: /* SDRAM_STATUS */
268             ret = sdram->status;
269             break;
270         case 0x30: /* SDRAM_RTR */
271             ret = sdram->rtr;
272             break;
273         case 0x34: /* SDRAM_PMIT */
274             ret = sdram->pmit;
275             break;
276         case 0x40: /* SDRAM_B0CR */
277             ret = sdram->bank[0].bcr;
278             break;
279         case 0x44: /* SDRAM_B1CR */
280             ret = sdram->bank[1].bcr;
281             break;
282         case 0x48: /* SDRAM_B2CR */
283             ret = sdram->bank[2].bcr;
284             break;
285         case 0x4C: /* SDRAM_B3CR */
286             ret = sdram->bank[3].bcr;
287             break;
288         case 0x80: /* SDRAM_TR */
289             ret = -1; /* ? */
290             break;
291         case 0x94: /* SDRAM_ECCCFG */
292             ret = sdram->ecccfg;
293             break;
294         case 0x98: /* SDRAM_ECCESR */
295             ret = sdram->eccesr;
296             break;
297         default: /* Error */
298             ret = -1;
299             break;
300         }
301         break;
302     default:
303         /* Avoid gcc warning */
304         ret = 0;
305         break;
306     }
307 
308     return ret;
309 }
310 
311 static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
312 {
313     Ppc4xxSdramDdrState *sdram = opaque;
314 
315     switch (dcrn) {
316     case SDRAM0_CFGADDR:
317         sdram->addr = val;
318         break;
319     case SDRAM0_CFGDATA:
320         switch (sdram->addr) {
321         case 0x00: /* SDRAM_BESR0 */
322             sdram->besr0 &= ~val;
323             break;
324         case 0x08: /* SDRAM_BESR1 */
325             sdram->besr1 &= ~val;
326             break;
327         case 0x10: /* SDRAM_BEAR */
328             sdram->bear = val;
329             break;
330         case 0x20: /* SDRAM_CFG */
331             val &= 0xFFE00000;
332             if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
333                 trace_ppc4xx_sdram_enable("enable");
334                 /* validate all RAM mappings */
335                 sdram_ddr_map_bcr(sdram);
336                 sdram->status &= ~0x80000000;
337             } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
338                 trace_ppc4xx_sdram_enable("disable");
339                 /* invalidate all RAM mappings */
340                 sdram_ddr_unmap_bcr(sdram);
341                 sdram->status |= 0x80000000;
342             }
343             if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) {
344                 sdram->status |= 0x40000000;
345             } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) {
346                 sdram->status &= ~0x40000000;
347             }
348             sdram->cfg = val;
349             break;
350         case 0x24: /* SDRAM_STATUS */
351             /* Read-only register */
352             break;
353         case 0x30: /* SDRAM_RTR */
354             sdram->rtr = val & 0x3FF80000;
355             break;
356         case 0x34: /* SDRAM_PMIT */
357             sdram->pmit = (val & 0xF8000000) | 0x07C00000;
358             break;
359         case 0x40: /* SDRAM_B0CR */
360             sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000);
361             break;
362         case 0x44: /* SDRAM_B1CR */
363             sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000);
364             break;
365         case 0x48: /* SDRAM_B2CR */
366             sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000);
367             break;
368         case 0x4C: /* SDRAM_B3CR */
369             sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000);
370             break;
371         case 0x80: /* SDRAM_TR */
372             sdram->tr = val & 0x018FC01F;
373             break;
374         case 0x94: /* SDRAM_ECCCFG */
375             sdram->ecccfg = val & 0x00F00000;
376             break;
377         case 0x98: /* SDRAM_ECCESR */
378             val &= 0xFFF0F000;
379             if (sdram->eccesr == 0 && val != 0) {
380                 qemu_irq_raise(sdram->irq);
381             } else if (sdram->eccesr != 0 && val == 0) {
382                 qemu_irq_lower(sdram->irq);
383             }
384             sdram->eccesr = val;
385             break;
386         default: /* Error */
387             break;
388         }
389         break;
390     }
391 }
392 
393 static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
394 {
395     Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
396 
397     sdram->addr = 0;
398     sdram->bear = 0;
399     sdram->besr0 = 0; /* No error */
400     sdram->besr1 = 0; /* No error */
401     sdram->cfg = 0;
402     sdram->ecccfg = 0; /* No ECC */
403     sdram->eccesr = 0; /* No error */
404     sdram->pmit = 0x07C00000;
405     sdram->rtr = 0x05F00000;
406     sdram->tr = 0x00854009;
407     /* We pre-initialize RAM banks */
408     sdram->status = 0;
409     sdram->cfg = 0x00800000;
410 }
411 
412 static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
413 {
414     Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
415     Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
416     const ram_addr_t valid_bank_sizes[] = {
417         256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
418     };
419 
420     if (s->nbanks < 1 || s->nbanks > 4) {
421         error_setg(errp, "Invalid number of RAM banks");
422         return;
423     }
424     if (!s->dram_mr) {
425         error_setg(errp, "Missing dram memory region");
426         return;
427     }
428     ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
429 
430     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
431 
432     ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
433                         s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
434     ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
435                         s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
436 }
437 
438 static Property ppc4xx_sdram_ddr_props[] = {
439     DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
440                      MemoryRegion *),
441     DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
442     DEFINE_PROP_END_OF_LIST(),
443 };
444 
445 static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
446 {
447     DeviceClass *dc = DEVICE_CLASS(oc);
448 
449     dc->realize = ppc4xx_sdram_ddr_realize;
450     dc->reset = ppc4xx_sdram_ddr_reset;
451     /* Reason: only works as function of a ppc4xx SoC */
452     dc->user_creatable = false;
453     device_class_set_props(dc, ppc4xx_sdram_ddr_props);
454 }
455 
456 void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s)
457 {
458     sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
459     sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
460 }
461 
462 /*****************************************************************************/
463 /* DDR2 SDRAM controller */
464 enum {
465     SDRAM_R0BAS = 0x40,
466     SDRAM_R1BAS,
467     SDRAM_R2BAS,
468     SDRAM_R3BAS,
469     SDRAM_CONF1HB = 0x45,
470     SDRAM_PLBADDULL = 0x4a,
471     SDRAM_CONF1LL = 0x4b,
472     SDRAM_CONFPATHB = 0x4f,
473     SDRAM_PLBADDUHB = 0x50,
474 };
475 
476 static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
477 {
478     uint32_t bcr;
479 
480     switch (ram_size) {
481     case 8 * MiB:
482         bcr = 0xffc0;
483         break;
484     case 16 * MiB:
485         bcr = 0xff80;
486         break;
487     case 32 * MiB:
488         bcr = 0xff00;
489         break;
490     case 64 * MiB:
491         bcr = 0xfe00;
492         break;
493     case 128 * MiB:
494         bcr = 0xfc00;
495         break;
496     case 256 * MiB:
497         bcr = 0xf800;
498         break;
499     case 512 * MiB:
500         bcr = 0xf000;
501         break;
502     case 1 * GiB:
503         bcr = 0xe000;
504         break;
505     case 2 * GiB:
506         bcr = 0xc000;
507         break;
508     case 4 * GiB:
509         bcr = 0x8000;
510         break;
511     default:
512         error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
513         return 0;
514     }
515     bcr |= ram_base >> 2 & 0xffe00000;
516     bcr |= 1;
517 
518     return bcr;
519 }
520 
521 static inline hwaddr sdram_ddr2_base(uint32_t bcr)
522 {
523     return (bcr & 0xffe00000) << 2;
524 }
525 
526 static uint64_t sdram_ddr2_size(uint32_t bcr)
527 {
528     uint64_t size;
529     int sh;
530 
531     sh = 1024 - ((bcr >> 6) & 0x3ff);
532     size = 8 * MiB * sh;
533 
534     return size;
535 }
536 
537 static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
538                                uint32_t bcr, int enabled)
539 {
540     if (sdram->bank[i].bcr & 1) {
541         /* First unmap RAM if enabled */
542         trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
543                                  sdram_ddr2_size(sdram->bank[i].bcr));
544         sdram_bank_unmap(&sdram->bank[i]);
545     }
546     sdram->bank[i].bcr = bcr & 0xffe0ffc1;
547     if (enabled && (bcr & 1)) {
548         trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
549         sdram_bank_map(&sdram->bank[i]);
550     }
551 }
552 
553 static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
554 {
555     int i;
556 
557     for (i = 0; i < sdram->nbanks; i++) {
558         if (sdram->bank[i].size) {
559             sdram_ddr2_set_bcr(sdram, i,
560                                sdram_ddr2_bcr(sdram->bank[i].base,
561                                               sdram->bank[i].size), 1);
562         } else {
563             sdram_ddr2_set_bcr(sdram, i, 0, 0);
564         }
565     }
566 }
567 
568 static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
569 {
570     int i;
571 
572     for (i = 0; i < sdram->nbanks; i++) {
573         if (sdram->bank[i].size) {
574             sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
575         }
576     }
577 }
578 
579 static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
580 {
581     Ppc4xxSdramDdr2State *sdram = opaque;
582     uint32_t ret = 0;
583 
584     switch (dcrn) {
585     case SDRAM_R0BAS:
586     case SDRAM_R1BAS:
587     case SDRAM_R2BAS:
588     case SDRAM_R3BAS:
589         if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
590             ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
591                                  sdram->bank[dcrn - SDRAM_R0BAS].size);
592         }
593         break;
594     case SDRAM_CONF1HB:
595     case SDRAM_CONF1LL:
596     case SDRAM_CONFPATHB:
597     case SDRAM_PLBADDULL:
598     case SDRAM_PLBADDUHB:
599         break;
600     case SDRAM0_CFGADDR:
601         ret = sdram->addr;
602         break;
603     case SDRAM0_CFGDATA:
604         switch (sdram->addr) {
605         case 0x14: /* SDRAM_MCSTAT (405EX) */
606         case 0x1F:
607             ret = 0x80000000;
608             break;
609         case 0x21: /* SDRAM_MCOPT2 */
610             ret = sdram->mcopt2;
611             break;
612         case 0x40: /* SDRAM_MB0CF */
613             ret = 0x00008001;
614             break;
615         case 0x7A: /* SDRAM_DLCR */
616             ret = 0x02000000;
617             break;
618         case 0xE1: /* SDR0_DDR0 */
619             ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
620             break;
621         default:
622             break;
623         }
624         break;
625     default:
626         break;
627     }
628 
629     return ret;
630 }
631 
632 #define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
633 
634 static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
635 {
636     Ppc4xxSdramDdr2State *sdram = opaque;
637 
638     switch (dcrn) {
639     case SDRAM_R0BAS:
640     case SDRAM_R1BAS:
641     case SDRAM_R2BAS:
642     case SDRAM_R3BAS:
643     case SDRAM_CONF1HB:
644     case SDRAM_CONF1LL:
645     case SDRAM_CONFPATHB:
646     case SDRAM_PLBADDULL:
647     case SDRAM_PLBADDUHB:
648         break;
649     case SDRAM0_CFGADDR:
650         sdram->addr = val;
651         break;
652     case SDRAM0_CFGDATA:
653         switch (sdram->addr) {
654         case 0x00: /* B0CR */
655             break;
656         case 0x21: /* SDRAM_MCOPT2 */
657             if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
658                 (val & SDRAM_DDR2_MCOPT2_DCEN)) {
659                 trace_ppc4xx_sdram_enable("enable");
660                 /* validate all RAM mappings */
661                 sdram_ddr2_map_bcr(sdram);
662                 sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
663             } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
664                        !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
665                 trace_ppc4xx_sdram_enable("disable");
666                 /* invalidate all RAM mappings */
667                 sdram_ddr2_unmap_bcr(sdram);
668                 sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
669             }
670             break;
671         default:
672             break;
673         }
674         break;
675     default:
676         break;
677     }
678 }
679 
680 static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
681 {
682     Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev);
683 
684     sdram->addr = 0;
685     sdram->mcopt2 = 0;
686 }
687 
688 static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
689 {
690     Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
691     Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
692     /*
693      * SoC also has 4 GiB but that causes problem with 32 bit
694      * builds (4*GiB overflows the 32 bit ram_addr_t).
695      */
696     const ram_addr_t valid_bank_sizes[] = {
697         2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB,
698         64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
699     };
700 
701     if (s->nbanks < 1 || s->nbanks > 4) {
702         error_setg(errp, "Invalid number of RAM banks");
703         return;
704     }
705     if (!s->dram_mr) {
706         error_setg(errp, "Missing dram memory region");
707         return;
708     }
709     ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
710 
711     ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
712                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
713     ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
714                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
715 
716     ppc4xx_dcr_register(dcr, SDRAM_R0BAS,
717                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
718     ppc4xx_dcr_register(dcr, SDRAM_R1BAS,
719                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
720     ppc4xx_dcr_register(dcr, SDRAM_R2BAS,
721                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
722     ppc4xx_dcr_register(dcr, SDRAM_R3BAS,
723                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
724     ppc4xx_dcr_register(dcr, SDRAM_CONF1HB,
725                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
726     ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL,
727                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
728     ppc4xx_dcr_register(dcr, SDRAM_CONF1LL,
729                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
730     ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB,
731                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
732     ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB,
733                         s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
734 }
735 
736 static Property ppc4xx_sdram_ddr2_props[] = {
737     DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION,
738                      MemoryRegion *),
739     DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4),
740     DEFINE_PROP_END_OF_LIST(),
741 };
742 
743 static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data)
744 {
745     DeviceClass *dc = DEVICE_CLASS(oc);
746 
747     dc->realize = ppc4xx_sdram_ddr2_realize;
748     dc->reset = ppc4xx_sdram_ddr2_reset;
749     /* Reason: only works as function of a ppc4xx SoC */
750     dc->user_creatable = false;
751     device_class_set_props(dc, ppc4xx_sdram_ddr2_props);
752 }
753 
754 void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
755 {
756     sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
757     sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
758 }
759 
760 static const TypeInfo ppc4xx_sdram_types[] = {
761     {
762         .name           = TYPE_PPC4xx_SDRAM_DDR,
763         .parent         = TYPE_PPC4xx_DCR_DEVICE,
764         .instance_size  = sizeof(Ppc4xxSdramDdrState),
765         .class_init     = ppc4xx_sdram_ddr_class_init,
766     }, {
767         .name           = TYPE_PPC4xx_SDRAM_DDR2,
768         .parent         = TYPE_PPC4xx_DCR_DEVICE,
769         .instance_size  = sizeof(Ppc4xxSdramDdr2State),
770         .class_init     = ppc4xx_sdram_ddr2_class_init,
771     }
772 };
773 
774 DEFINE_TYPES(ppc4xx_sdram_types)
775