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 */ 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 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 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 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 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 189fa446fc5SBALATON Zoltan static inline hwaddr sdram_ddr_base(uint32_t bcr) 190fa446fc5SBALATON Zoltan { 191fa446fc5SBALATON Zoltan return bcr & 0xFF800000; 192fa446fc5SBALATON Zoltan } 193fa446fc5SBALATON Zoltan 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 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 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 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 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 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 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 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 5132a48dd7cSBALATON Zoltan static inline hwaddr sdram_ddr2_base(uint32_t bcr) 5142a48dd7cSBALATON Zoltan { 5152a48dd7cSBALATON Zoltan return (bcr & 0xffe00000) << 2; 5162a48dd7cSBALATON Zoltan } 5172a48dd7cSBALATON Zoltan 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 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 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 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 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 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 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