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" 362a48dd7cSBALATON Zoltan #include "exec/address-spaces.h" /* get_system_memory() */ 372a48dd7cSBALATON Zoltan #include "hw/irq.h" 382a48dd7cSBALATON Zoltan #include "hw/qdev-properties.h" 392a48dd7cSBALATON Zoltan #include "hw/ppc/ppc4xx.h" 402a48dd7cSBALATON Zoltan #include "trace.h" 412a48dd7cSBALATON Zoltan 422a48dd7cSBALATON Zoltan /*****************************************************************************/ 432a48dd7cSBALATON Zoltan /* Shared functions */ 442a48dd7cSBALATON Zoltan 45080741abSBALATON Zoltan /* 46080741abSBALATON Zoltan * Split RAM between SDRAM banks. 47080741abSBALATON Zoltan * 48080741abSBALATON Zoltan * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] 49080741abSBALATON Zoltan * and must be 0-terminated. 50080741abSBALATON Zoltan * 51080741abSBALATON Zoltan * The 4xx SDRAM controller supports a small number of banks, and each bank 52080741abSBALATON Zoltan * must be one of a small set of sizes. The number of banks and the supported 53080741abSBALATON Zoltan * sizes varies by SoC. 54080741abSBALATON Zoltan */ 55080741abSBALATON Zoltan static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, 56080741abSBALATON Zoltan Ppc4xxSdramBank ram_banks[], 57080741abSBALATON Zoltan const ram_addr_t sdram_bank_sizes[]) 58080741abSBALATON Zoltan { 59080741abSBALATON Zoltan ram_addr_t size_left = memory_region_size(ram); 60080741abSBALATON Zoltan ram_addr_t base = 0; 61080741abSBALATON Zoltan ram_addr_t bank_size; 62080741abSBALATON Zoltan int i; 63080741abSBALATON Zoltan int j; 64080741abSBALATON Zoltan 65080741abSBALATON Zoltan for (i = 0; i < nr_banks; i++) { 66080741abSBALATON Zoltan for (j = 0; sdram_bank_sizes[j] != 0; j++) { 67080741abSBALATON Zoltan bank_size = sdram_bank_sizes[j]; 68080741abSBALATON Zoltan if (bank_size <= size_left) { 69080741abSBALATON Zoltan char name[32]; 70080741abSBALATON Zoltan 71080741abSBALATON Zoltan ram_banks[i].base = base; 72080741abSBALATON Zoltan ram_banks[i].size = bank_size; 73080741abSBALATON Zoltan base += bank_size; 74080741abSBALATON Zoltan size_left -= bank_size; 75080741abSBALATON Zoltan snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); 76080741abSBALATON Zoltan memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram, 77080741abSBALATON Zoltan ram_banks[i].base, ram_banks[i].size); 78080741abSBALATON Zoltan break; 79080741abSBALATON Zoltan } 80080741abSBALATON Zoltan } 81080741abSBALATON Zoltan if (!size_left) { 82080741abSBALATON Zoltan /* No need to use the remaining banks. */ 83080741abSBALATON Zoltan break; 84080741abSBALATON Zoltan } 85080741abSBALATON Zoltan } 86080741abSBALATON Zoltan 87080741abSBALATON Zoltan if (size_left) { 88080741abSBALATON Zoltan ram_addr_t used_size = memory_region_size(ram) - size_left; 89080741abSBALATON Zoltan GString *s = g_string_new(NULL); 90080741abSBALATON Zoltan 91080741abSBALATON Zoltan for (i = 0; sdram_bank_sizes[i]; i++) { 92080741abSBALATON Zoltan g_string_append_printf(s, "%" PRIi64 "%s", 93080741abSBALATON Zoltan sdram_bank_sizes[i] / MiB, 94080741abSBALATON Zoltan sdram_bank_sizes[i + 1] ? ", " : ""); 95080741abSBALATON Zoltan } 96080741abSBALATON Zoltan error_report("at most %d bank%s of %s MiB each supported", 97080741abSBALATON Zoltan nr_banks, nr_banks == 1 ? "" : "s", s->str); 98080741abSBALATON Zoltan error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", 99080741abSBALATON Zoltan used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); 100080741abSBALATON Zoltan 101080741abSBALATON Zoltan g_string_free(s, true); 102080741abSBALATON Zoltan exit(EXIT_FAILURE); 103080741abSBALATON Zoltan } 104080741abSBALATON Zoltan } 105080741abSBALATON Zoltan 1062a48dd7cSBALATON Zoltan static void sdram_bank_map(Ppc4xxSdramBank *bank) 1072a48dd7cSBALATON Zoltan { 108424a660cSBALATON Zoltan trace_ppc4xx_sdram_map(bank->base, bank->size); 1092a48dd7cSBALATON Zoltan memory_region_init(&bank->container, NULL, "sdram-container", bank->size); 1102a48dd7cSBALATON Zoltan memory_region_add_subregion(&bank->container, 0, &bank->ram); 1112a48dd7cSBALATON Zoltan memory_region_add_subregion(get_system_memory(), bank->base, 1122a48dd7cSBALATON Zoltan &bank->container); 1132a48dd7cSBALATON Zoltan } 1142a48dd7cSBALATON Zoltan 1152a48dd7cSBALATON Zoltan static void sdram_bank_unmap(Ppc4xxSdramBank *bank) 1162a48dd7cSBALATON Zoltan { 117424a660cSBALATON Zoltan trace_ppc4xx_sdram_unmap(bank->base, bank->size); 1182a48dd7cSBALATON Zoltan memory_region_del_subregion(get_system_memory(), &bank->container); 1192a48dd7cSBALATON Zoltan memory_region_del_subregion(&bank->container, &bank->ram); 1202a48dd7cSBALATON Zoltan object_unparent(OBJECT(&bank->container)); 1212a48dd7cSBALATON Zoltan } 1222a48dd7cSBALATON Zoltan 123424a660cSBALATON Zoltan static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr, 124424a660cSBALATON Zoltan hwaddr base, hwaddr size, int enabled) 125424a660cSBALATON Zoltan { 126424a660cSBALATON Zoltan if (memory_region_is_mapped(&bank->container)) { 127424a660cSBALATON Zoltan sdram_bank_unmap(bank); 128424a660cSBALATON Zoltan } 129424a660cSBALATON Zoltan bank->bcr = bcr; 130424a660cSBALATON Zoltan bank->base = base; 131424a660cSBALATON Zoltan bank->size = size; 132424a660cSBALATON Zoltan if (enabled && (bcr & 1)) { 133424a660cSBALATON Zoltan sdram_bank_map(bank); 134424a660cSBALATON Zoltan } 135424a660cSBALATON Zoltan } 136424a660cSBALATON Zoltan 1372a48dd7cSBALATON Zoltan enum { 1382a48dd7cSBALATON Zoltan SDRAM0_CFGADDR = 0x010, 1392a48dd7cSBALATON Zoltan SDRAM0_CFGDATA = 0x011, 1402a48dd7cSBALATON Zoltan }; 1412a48dd7cSBALATON Zoltan 1422a48dd7cSBALATON Zoltan /*****************************************************************************/ 143fa446fc5SBALATON Zoltan /* DDR SDRAM controller */ 144*54a3527eSBALATON Zoltan #define SDRAM_DDR_BCR_MASK 0xFFDEE001 145*54a3527eSBALATON Zoltan 146fa446fc5SBALATON Zoltan static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) 147fa446fc5SBALATON Zoltan { 148fa446fc5SBALATON Zoltan uint32_t bcr; 149fa446fc5SBALATON Zoltan 150fa446fc5SBALATON Zoltan switch (ram_size) { 151fa446fc5SBALATON Zoltan case 4 * MiB: 152fa446fc5SBALATON Zoltan bcr = 0; 153fa446fc5SBALATON Zoltan break; 154fa446fc5SBALATON Zoltan case 8 * MiB: 155fa446fc5SBALATON Zoltan bcr = 0x20000; 156fa446fc5SBALATON Zoltan break; 157fa446fc5SBALATON Zoltan case 16 * MiB: 158fa446fc5SBALATON Zoltan bcr = 0x40000; 159fa446fc5SBALATON Zoltan break; 160fa446fc5SBALATON Zoltan case 32 * MiB: 161fa446fc5SBALATON Zoltan bcr = 0x60000; 162fa446fc5SBALATON Zoltan break; 163fa446fc5SBALATON Zoltan case 64 * MiB: 164fa446fc5SBALATON Zoltan bcr = 0x80000; 165fa446fc5SBALATON Zoltan break; 166fa446fc5SBALATON Zoltan case 128 * MiB: 167fa446fc5SBALATON Zoltan bcr = 0xA0000; 168fa446fc5SBALATON Zoltan break; 169fa446fc5SBALATON Zoltan case 256 * MiB: 170fa446fc5SBALATON Zoltan bcr = 0xC0000; 171fa446fc5SBALATON Zoltan break; 172fa446fc5SBALATON Zoltan default: 173fa446fc5SBALATON Zoltan qemu_log_mask(LOG_GUEST_ERROR, 174fa446fc5SBALATON Zoltan "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, 175fa446fc5SBALATON Zoltan ram_size); 176fa446fc5SBALATON Zoltan return 0; 177fa446fc5SBALATON Zoltan } 178fa446fc5SBALATON Zoltan bcr |= ram_base & 0xFF800000; 179fa446fc5SBALATON Zoltan bcr |= 1; 180fa446fc5SBALATON Zoltan 181fa446fc5SBALATON Zoltan return bcr; 182fa446fc5SBALATON Zoltan } 183fa446fc5SBALATON Zoltan 184fa446fc5SBALATON Zoltan static inline hwaddr sdram_ddr_base(uint32_t bcr) 185fa446fc5SBALATON Zoltan { 186fa446fc5SBALATON Zoltan return bcr & 0xFF800000; 187fa446fc5SBALATON Zoltan } 188fa446fc5SBALATON Zoltan 189c8c6d68aSBALATON Zoltan static hwaddr sdram_ddr_size(uint32_t bcr) 190fa446fc5SBALATON Zoltan { 191c8c6d68aSBALATON Zoltan hwaddr size; 192fa446fc5SBALATON Zoltan int sh; 193fa446fc5SBALATON Zoltan 194fa446fc5SBALATON Zoltan sh = (bcr >> 17) & 0x7; 195fa446fc5SBALATON Zoltan if (sh == 7) { 196fa446fc5SBALATON Zoltan size = -1; 197fa446fc5SBALATON Zoltan } else { 198fa446fc5SBALATON Zoltan size = (4 * MiB) << sh; 199fa446fc5SBALATON Zoltan } 200fa446fc5SBALATON Zoltan 201fa446fc5SBALATON Zoltan return size; 202fa446fc5SBALATON Zoltan } 203fa446fc5SBALATON Zoltan 204fa446fc5SBALATON Zoltan static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) 205fa446fc5SBALATON Zoltan { 20661cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = opaque; 207fa446fc5SBALATON Zoltan uint32_t ret; 208fa446fc5SBALATON Zoltan 209fa446fc5SBALATON Zoltan switch (dcrn) { 210fa446fc5SBALATON Zoltan case SDRAM0_CFGADDR: 21161cfe0dfSBALATON Zoltan ret = s->addr; 212fa446fc5SBALATON Zoltan break; 213fa446fc5SBALATON Zoltan case SDRAM0_CFGDATA: 21461cfe0dfSBALATON Zoltan switch (s->addr) { 215fa446fc5SBALATON Zoltan case 0x00: /* SDRAM_BESR0 */ 21661cfe0dfSBALATON Zoltan ret = s->besr0; 217fa446fc5SBALATON Zoltan break; 218fa446fc5SBALATON Zoltan case 0x08: /* SDRAM_BESR1 */ 21961cfe0dfSBALATON Zoltan ret = s->besr1; 220fa446fc5SBALATON Zoltan break; 221fa446fc5SBALATON Zoltan case 0x10: /* SDRAM_BEAR */ 22261cfe0dfSBALATON Zoltan ret = s->bear; 223fa446fc5SBALATON Zoltan break; 224fa446fc5SBALATON Zoltan case 0x20: /* SDRAM_CFG */ 22561cfe0dfSBALATON Zoltan ret = s->cfg; 226fa446fc5SBALATON Zoltan break; 227fa446fc5SBALATON Zoltan case 0x24: /* SDRAM_STATUS */ 22861cfe0dfSBALATON Zoltan ret = s->status; 229fa446fc5SBALATON Zoltan break; 230fa446fc5SBALATON Zoltan case 0x30: /* SDRAM_RTR */ 23161cfe0dfSBALATON Zoltan ret = s->rtr; 232fa446fc5SBALATON Zoltan break; 233fa446fc5SBALATON Zoltan case 0x34: /* SDRAM_PMIT */ 23461cfe0dfSBALATON Zoltan ret = s->pmit; 235fa446fc5SBALATON Zoltan break; 236fa446fc5SBALATON Zoltan case 0x40: /* SDRAM_B0CR */ 23761cfe0dfSBALATON Zoltan ret = s->bank[0].bcr; 238fa446fc5SBALATON Zoltan break; 239fa446fc5SBALATON Zoltan case 0x44: /* SDRAM_B1CR */ 24061cfe0dfSBALATON Zoltan ret = s->bank[1].bcr; 241fa446fc5SBALATON Zoltan break; 242fa446fc5SBALATON Zoltan case 0x48: /* SDRAM_B2CR */ 24361cfe0dfSBALATON Zoltan ret = s->bank[2].bcr; 244fa446fc5SBALATON Zoltan break; 245fa446fc5SBALATON Zoltan case 0x4C: /* SDRAM_B3CR */ 24661cfe0dfSBALATON Zoltan ret = s->bank[3].bcr; 247fa446fc5SBALATON Zoltan break; 248fa446fc5SBALATON Zoltan case 0x80: /* SDRAM_TR */ 249fa446fc5SBALATON Zoltan ret = -1; /* ? */ 250fa446fc5SBALATON Zoltan break; 251fa446fc5SBALATON Zoltan case 0x94: /* SDRAM_ECCCFG */ 25261cfe0dfSBALATON Zoltan ret = s->ecccfg; 253fa446fc5SBALATON Zoltan break; 254fa446fc5SBALATON Zoltan case 0x98: /* SDRAM_ECCESR */ 25561cfe0dfSBALATON Zoltan ret = s->eccesr; 256fa446fc5SBALATON Zoltan break; 257fa446fc5SBALATON Zoltan default: /* Error */ 258fa446fc5SBALATON Zoltan ret = -1; 259fa446fc5SBALATON Zoltan break; 260fa446fc5SBALATON Zoltan } 261fa446fc5SBALATON Zoltan break; 262fa446fc5SBALATON Zoltan default: 263fa446fc5SBALATON Zoltan /* Avoid gcc warning */ 264fa446fc5SBALATON Zoltan ret = 0; 265fa446fc5SBALATON Zoltan break; 266fa446fc5SBALATON Zoltan } 267fa446fc5SBALATON Zoltan 268fa446fc5SBALATON Zoltan return ret; 269fa446fc5SBALATON Zoltan } 270fa446fc5SBALATON Zoltan 271fa446fc5SBALATON Zoltan static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) 272fa446fc5SBALATON Zoltan { 27361cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = opaque; 274*54a3527eSBALATON Zoltan int i; 275fa446fc5SBALATON Zoltan 276fa446fc5SBALATON Zoltan switch (dcrn) { 277fa446fc5SBALATON Zoltan case SDRAM0_CFGADDR: 27861cfe0dfSBALATON Zoltan s->addr = val; 279fa446fc5SBALATON Zoltan break; 280fa446fc5SBALATON Zoltan case SDRAM0_CFGDATA: 28161cfe0dfSBALATON Zoltan switch (s->addr) { 282fa446fc5SBALATON Zoltan case 0x00: /* SDRAM_BESR0 */ 28361cfe0dfSBALATON Zoltan s->besr0 &= ~val; 284fa446fc5SBALATON Zoltan break; 285fa446fc5SBALATON Zoltan case 0x08: /* SDRAM_BESR1 */ 28661cfe0dfSBALATON Zoltan s->besr1 &= ~val; 287fa446fc5SBALATON Zoltan break; 288fa446fc5SBALATON Zoltan case 0x10: /* SDRAM_BEAR */ 28961cfe0dfSBALATON Zoltan s->bear = val; 290fa446fc5SBALATON Zoltan break; 291fa446fc5SBALATON Zoltan case 0x20: /* SDRAM_CFG */ 292fa446fc5SBALATON Zoltan val &= 0xFFE00000; 29361cfe0dfSBALATON Zoltan if (!(s->cfg & 0x80000000) && (val & 0x80000000)) { 294fa446fc5SBALATON Zoltan trace_ppc4xx_sdram_enable("enable"); 295fa446fc5SBALATON Zoltan /* validate all RAM mappings */ 296*54a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 297*54a3527eSBALATON Zoltan if (s->bank[i].size) { 298*54a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 299*54a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size, 300*54a3527eSBALATON Zoltan 1); 301*54a3527eSBALATON Zoltan } 302*54a3527eSBALATON Zoltan } 30361cfe0dfSBALATON Zoltan s->status &= ~0x80000000; 30461cfe0dfSBALATON Zoltan } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) { 305fa446fc5SBALATON Zoltan trace_ppc4xx_sdram_enable("disable"); 306fa446fc5SBALATON Zoltan /* invalidate all RAM mappings */ 307*54a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 308*54a3527eSBALATON Zoltan if (s->bank[i].size) { 309*54a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 310*54a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size, 311*54a3527eSBALATON Zoltan 0); 312*54a3527eSBALATON Zoltan } 313*54a3527eSBALATON Zoltan } 31461cfe0dfSBALATON Zoltan s->status |= 0x80000000; 315fa446fc5SBALATON Zoltan } 31661cfe0dfSBALATON Zoltan if (!(s->cfg & 0x40000000) && (val & 0x40000000)) { 31761cfe0dfSBALATON Zoltan s->status |= 0x40000000; 31861cfe0dfSBALATON Zoltan } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) { 31961cfe0dfSBALATON Zoltan s->status &= ~0x40000000; 320fa446fc5SBALATON Zoltan } 32161cfe0dfSBALATON Zoltan s->cfg = val; 322fa446fc5SBALATON Zoltan break; 323fa446fc5SBALATON Zoltan case 0x24: /* SDRAM_STATUS */ 324fa446fc5SBALATON Zoltan /* Read-only register */ 325fa446fc5SBALATON Zoltan break; 326fa446fc5SBALATON Zoltan case 0x30: /* SDRAM_RTR */ 32761cfe0dfSBALATON Zoltan s->rtr = val & 0x3FF80000; 328fa446fc5SBALATON Zoltan break; 329fa446fc5SBALATON Zoltan case 0x34: /* SDRAM_PMIT */ 33061cfe0dfSBALATON Zoltan s->pmit = (val & 0xF8000000) | 0x07C00000; 331fa446fc5SBALATON Zoltan break; 332fa446fc5SBALATON Zoltan case 0x40: /* SDRAM_B0CR */ 333fa446fc5SBALATON Zoltan case 0x44: /* SDRAM_B1CR */ 334fa446fc5SBALATON Zoltan case 0x48: /* SDRAM_B2CR */ 335fa446fc5SBALATON Zoltan case 0x4C: /* SDRAM_B3CR */ 336*54a3527eSBALATON Zoltan i = (s->addr - 0x40) / 4; 337*54a3527eSBALATON Zoltan val &= SDRAM_DDR_BCR_MASK; 338*54a3527eSBALATON Zoltan if (s->bank[i].size) { 339*54a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], val, 340*54a3527eSBALATON Zoltan sdram_ddr_base(val), sdram_ddr_size(val), 341*54a3527eSBALATON Zoltan s->cfg & 0x80000000); 342*54a3527eSBALATON Zoltan } 343fa446fc5SBALATON Zoltan break; 344fa446fc5SBALATON Zoltan case 0x80: /* SDRAM_TR */ 34561cfe0dfSBALATON Zoltan s->tr = val & 0x018FC01F; 346fa446fc5SBALATON Zoltan break; 347fa446fc5SBALATON Zoltan case 0x94: /* SDRAM_ECCCFG */ 34861cfe0dfSBALATON Zoltan s->ecccfg = val & 0x00F00000; 349fa446fc5SBALATON Zoltan break; 350fa446fc5SBALATON Zoltan case 0x98: /* SDRAM_ECCESR */ 351fa446fc5SBALATON Zoltan val &= 0xFFF0F000; 35261cfe0dfSBALATON Zoltan if (s->eccesr == 0 && val != 0) { 35361cfe0dfSBALATON Zoltan qemu_irq_raise(s->irq); 35461cfe0dfSBALATON Zoltan } else if (s->eccesr != 0 && val == 0) { 35561cfe0dfSBALATON Zoltan qemu_irq_lower(s->irq); 356fa446fc5SBALATON Zoltan } 35761cfe0dfSBALATON Zoltan s->eccesr = val; 358fa446fc5SBALATON Zoltan break; 359fa446fc5SBALATON Zoltan default: /* Error */ 360fa446fc5SBALATON Zoltan break; 361fa446fc5SBALATON Zoltan } 362fa446fc5SBALATON Zoltan break; 363fa446fc5SBALATON Zoltan } 364fa446fc5SBALATON Zoltan } 365fa446fc5SBALATON Zoltan 366fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_reset(DeviceState *dev) 367fa446fc5SBALATON Zoltan { 36861cfe0dfSBALATON Zoltan Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); 369fa446fc5SBALATON Zoltan 37061cfe0dfSBALATON Zoltan s->addr = 0; 37161cfe0dfSBALATON Zoltan s->bear = 0; 37261cfe0dfSBALATON Zoltan s->besr0 = 0; /* No error */ 37361cfe0dfSBALATON Zoltan s->besr1 = 0; /* No error */ 37461cfe0dfSBALATON Zoltan s->cfg = 0; 37561cfe0dfSBALATON Zoltan s->ecccfg = 0; /* No ECC */ 37661cfe0dfSBALATON Zoltan s->eccesr = 0; /* No error */ 37761cfe0dfSBALATON Zoltan s->pmit = 0x07C00000; 37861cfe0dfSBALATON Zoltan s->rtr = 0x05F00000; 37961cfe0dfSBALATON Zoltan s->tr = 0x00854009; 380fa446fc5SBALATON Zoltan /* We pre-initialize RAM banks */ 38161cfe0dfSBALATON Zoltan s->status = 0; 38261cfe0dfSBALATON Zoltan s->cfg = 0x00800000; 383fa446fc5SBALATON Zoltan } 384fa446fc5SBALATON Zoltan 385fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) 386fa446fc5SBALATON Zoltan { 387fa446fc5SBALATON Zoltan Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); 388fa446fc5SBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); 389fa446fc5SBALATON Zoltan const ram_addr_t valid_bank_sizes[] = { 390fa446fc5SBALATON Zoltan 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 391fa446fc5SBALATON Zoltan }; 392*54a3527eSBALATON Zoltan int i; 393fa446fc5SBALATON Zoltan 394fa446fc5SBALATON Zoltan if (s->nbanks < 1 || s->nbanks > 4) { 395fa446fc5SBALATON Zoltan error_setg(errp, "Invalid number of RAM banks"); 396fa446fc5SBALATON Zoltan return; 397fa446fc5SBALATON Zoltan } 398fa446fc5SBALATON Zoltan if (!s->dram_mr) { 399fa446fc5SBALATON Zoltan error_setg(errp, "Missing dram memory region"); 400fa446fc5SBALATON Zoltan return; 401fa446fc5SBALATON Zoltan } 402fa446fc5SBALATON Zoltan ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); 403*54a3527eSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 404*54a3527eSBALATON Zoltan if (s->bank[i].size) { 405*54a3527eSBALATON Zoltan s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size); 406*54a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 407*54a3527eSBALATON Zoltan s->bank[i].base, s->bank[i].size, 0); 408*54a3527eSBALATON Zoltan } else { 409*54a3527eSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); 410*54a3527eSBALATON Zoltan } 411*54a3527eSBALATON Zoltan trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr), 412*54a3527eSBALATON Zoltan sdram_ddr_size(s->bank[i].bcr), 413*54a3527eSBALATON Zoltan s->bank[i].bcr); 414*54a3527eSBALATON Zoltan } 415fa446fc5SBALATON Zoltan 416fa446fc5SBALATON Zoltan sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); 417fa446fc5SBALATON Zoltan 418fa446fc5SBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, 419fa446fc5SBALATON Zoltan s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); 420fa446fc5SBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, 421fa446fc5SBALATON Zoltan s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); 422fa446fc5SBALATON Zoltan } 423fa446fc5SBALATON Zoltan 424fa446fc5SBALATON Zoltan static Property ppc4xx_sdram_ddr_props[] = { 425fa446fc5SBALATON Zoltan DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION, 426fa446fc5SBALATON Zoltan MemoryRegion *), 427fa446fc5SBALATON Zoltan DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), 428fa446fc5SBALATON Zoltan DEFINE_PROP_END_OF_LIST(), 429fa446fc5SBALATON Zoltan }; 430fa446fc5SBALATON Zoltan 431fa446fc5SBALATON Zoltan static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) 432fa446fc5SBALATON Zoltan { 433fa446fc5SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc); 434fa446fc5SBALATON Zoltan 435fa446fc5SBALATON Zoltan dc->realize = ppc4xx_sdram_ddr_realize; 436fa446fc5SBALATON Zoltan dc->reset = ppc4xx_sdram_ddr_reset; 437fa446fc5SBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */ 438fa446fc5SBALATON Zoltan dc->user_creatable = false; 439fa446fc5SBALATON Zoltan device_class_set_props(dc, ppc4xx_sdram_ddr_props); 440fa446fc5SBALATON Zoltan } 441fa446fc5SBALATON Zoltan 442fa446fc5SBALATON Zoltan void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) 443fa446fc5SBALATON Zoltan { 444fa446fc5SBALATON Zoltan sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); 445fa446fc5SBALATON Zoltan sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); 446fa446fc5SBALATON Zoltan } 447fa446fc5SBALATON Zoltan 448fa446fc5SBALATON Zoltan /*****************************************************************************/ 4492a48dd7cSBALATON Zoltan /* DDR2 SDRAM controller */ 450424a660cSBALATON Zoltan #define SDRAM_DDR2_BCR_MASK 0xffe0ffc1 451424a660cSBALATON Zoltan 4522a48dd7cSBALATON Zoltan enum { 4532a48dd7cSBALATON Zoltan SDRAM_R0BAS = 0x40, 4542a48dd7cSBALATON Zoltan SDRAM_R1BAS, 4552a48dd7cSBALATON Zoltan SDRAM_R2BAS, 4562a48dd7cSBALATON Zoltan SDRAM_R3BAS, 4572a48dd7cSBALATON Zoltan SDRAM_CONF1HB = 0x45, 4582a48dd7cSBALATON Zoltan SDRAM_PLBADDULL = 0x4a, 4592a48dd7cSBALATON Zoltan SDRAM_CONF1LL = 0x4b, 4602a48dd7cSBALATON Zoltan SDRAM_CONFPATHB = 0x4f, 4612a48dd7cSBALATON Zoltan SDRAM_PLBADDUHB = 0x50, 4622a48dd7cSBALATON Zoltan }; 4632a48dd7cSBALATON Zoltan 4642a48dd7cSBALATON Zoltan static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size) 4652a48dd7cSBALATON Zoltan { 4662a48dd7cSBALATON Zoltan uint32_t bcr; 4672a48dd7cSBALATON Zoltan 4682a48dd7cSBALATON Zoltan switch (ram_size) { 4692a48dd7cSBALATON Zoltan case 8 * MiB: 4702a48dd7cSBALATON Zoltan bcr = 0xffc0; 4712a48dd7cSBALATON Zoltan break; 4722a48dd7cSBALATON Zoltan case 16 * MiB: 4732a48dd7cSBALATON Zoltan bcr = 0xff80; 4742a48dd7cSBALATON Zoltan break; 4752a48dd7cSBALATON Zoltan case 32 * MiB: 4762a48dd7cSBALATON Zoltan bcr = 0xff00; 4772a48dd7cSBALATON Zoltan break; 4782a48dd7cSBALATON Zoltan case 64 * MiB: 4792a48dd7cSBALATON Zoltan bcr = 0xfe00; 4802a48dd7cSBALATON Zoltan break; 4812a48dd7cSBALATON Zoltan case 128 * MiB: 4822a48dd7cSBALATON Zoltan bcr = 0xfc00; 4832a48dd7cSBALATON Zoltan break; 4842a48dd7cSBALATON Zoltan case 256 * MiB: 4852a48dd7cSBALATON Zoltan bcr = 0xf800; 4862a48dd7cSBALATON Zoltan break; 4872a48dd7cSBALATON Zoltan case 512 * MiB: 4882a48dd7cSBALATON Zoltan bcr = 0xf000; 4892a48dd7cSBALATON Zoltan break; 4902a48dd7cSBALATON Zoltan case 1 * GiB: 4912a48dd7cSBALATON Zoltan bcr = 0xe000; 4922a48dd7cSBALATON Zoltan break; 4932a48dd7cSBALATON Zoltan case 2 * GiB: 4942a48dd7cSBALATON Zoltan bcr = 0xc000; 4952a48dd7cSBALATON Zoltan break; 4962a48dd7cSBALATON Zoltan case 4 * GiB: 4972a48dd7cSBALATON Zoltan bcr = 0x8000; 4982a48dd7cSBALATON Zoltan break; 4992a48dd7cSBALATON Zoltan default: 5002a48dd7cSBALATON Zoltan error_report("invalid RAM size " TARGET_FMT_plx, ram_size); 5012a48dd7cSBALATON Zoltan return 0; 5022a48dd7cSBALATON Zoltan } 5032a48dd7cSBALATON Zoltan bcr |= ram_base >> 2 & 0xffe00000; 5042a48dd7cSBALATON Zoltan bcr |= 1; 5052a48dd7cSBALATON Zoltan 5062a48dd7cSBALATON Zoltan return bcr; 5072a48dd7cSBALATON Zoltan } 5082a48dd7cSBALATON Zoltan 5092a48dd7cSBALATON Zoltan static inline hwaddr sdram_ddr2_base(uint32_t bcr) 5102a48dd7cSBALATON Zoltan { 5112a48dd7cSBALATON Zoltan return (bcr & 0xffe00000) << 2; 5122a48dd7cSBALATON Zoltan } 5132a48dd7cSBALATON Zoltan 514c8c6d68aSBALATON Zoltan static hwaddr sdram_ddr2_size(uint32_t bcr) 5152a48dd7cSBALATON Zoltan { 516c8c6d68aSBALATON Zoltan hwaddr size; 5172a48dd7cSBALATON Zoltan int sh; 5182a48dd7cSBALATON Zoltan 5192a48dd7cSBALATON Zoltan sh = 1024 - ((bcr >> 6) & 0x3ff); 5202a48dd7cSBALATON Zoltan size = 8 * MiB * sh; 5212a48dd7cSBALATON Zoltan 5222a48dd7cSBALATON Zoltan return size; 5232a48dd7cSBALATON Zoltan } 5242a48dd7cSBALATON Zoltan 5252a48dd7cSBALATON Zoltan static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) 5262a48dd7cSBALATON Zoltan { 52761cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = opaque; 5282a48dd7cSBALATON Zoltan uint32_t ret = 0; 5292a48dd7cSBALATON Zoltan 5302a48dd7cSBALATON Zoltan switch (dcrn) { 5312a48dd7cSBALATON Zoltan case SDRAM_R0BAS: 5322a48dd7cSBALATON Zoltan case SDRAM_R1BAS: 5332a48dd7cSBALATON Zoltan case SDRAM_R2BAS: 5342a48dd7cSBALATON Zoltan case SDRAM_R3BAS: 53561cfe0dfSBALATON Zoltan if (s->bank[dcrn - SDRAM_R0BAS].size) { 53661cfe0dfSBALATON Zoltan ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base, 53761cfe0dfSBALATON Zoltan s->bank[dcrn - SDRAM_R0BAS].size); 5382a48dd7cSBALATON Zoltan } 5392a48dd7cSBALATON Zoltan break; 5402a48dd7cSBALATON Zoltan case SDRAM_CONF1HB: 5412a48dd7cSBALATON Zoltan case SDRAM_CONF1LL: 5422a48dd7cSBALATON Zoltan case SDRAM_CONFPATHB: 5432a48dd7cSBALATON Zoltan case SDRAM_PLBADDULL: 5442a48dd7cSBALATON Zoltan case SDRAM_PLBADDUHB: 5452a48dd7cSBALATON Zoltan break; 5462a48dd7cSBALATON Zoltan case SDRAM0_CFGADDR: 54761cfe0dfSBALATON Zoltan ret = s->addr; 5482a48dd7cSBALATON Zoltan break; 5492a48dd7cSBALATON Zoltan case SDRAM0_CFGDATA: 55061cfe0dfSBALATON Zoltan switch (s->addr) { 5512a48dd7cSBALATON Zoltan case 0x14: /* SDRAM_MCSTAT (405EX) */ 5522a48dd7cSBALATON Zoltan case 0x1F: 5532a48dd7cSBALATON Zoltan ret = 0x80000000; 5542a48dd7cSBALATON Zoltan break; 5552a48dd7cSBALATON Zoltan case 0x21: /* SDRAM_MCOPT2 */ 55661cfe0dfSBALATON Zoltan ret = s->mcopt2; 5572a48dd7cSBALATON Zoltan break; 5582a48dd7cSBALATON Zoltan case 0x40: /* SDRAM_MB0CF */ 5592a48dd7cSBALATON Zoltan ret = 0x00008001; 5602a48dd7cSBALATON Zoltan break; 5612a48dd7cSBALATON Zoltan case 0x7A: /* SDRAM_DLCR */ 5622a48dd7cSBALATON Zoltan ret = 0x02000000; 5632a48dd7cSBALATON Zoltan break; 5642a48dd7cSBALATON Zoltan case 0xE1: /* SDR0_DDR0 */ 5652a48dd7cSBALATON Zoltan ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1; 5662a48dd7cSBALATON Zoltan break; 5672a48dd7cSBALATON Zoltan default: 5682a48dd7cSBALATON Zoltan break; 5692a48dd7cSBALATON Zoltan } 5702a48dd7cSBALATON Zoltan break; 5712a48dd7cSBALATON Zoltan default: 5722a48dd7cSBALATON Zoltan break; 5732a48dd7cSBALATON Zoltan } 5742a48dd7cSBALATON Zoltan 5752a48dd7cSBALATON Zoltan return ret; 5762a48dd7cSBALATON Zoltan } 5772a48dd7cSBALATON Zoltan 5782a48dd7cSBALATON Zoltan #define SDRAM_DDR2_MCOPT2_DCEN BIT(27) 5792a48dd7cSBALATON Zoltan 5802a48dd7cSBALATON Zoltan static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) 5812a48dd7cSBALATON Zoltan { 58261cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = opaque; 583424a660cSBALATON Zoltan int i; 5842a48dd7cSBALATON Zoltan 5852a48dd7cSBALATON Zoltan switch (dcrn) { 5862a48dd7cSBALATON Zoltan case SDRAM_R0BAS: 5872a48dd7cSBALATON Zoltan case SDRAM_R1BAS: 5882a48dd7cSBALATON Zoltan case SDRAM_R2BAS: 5892a48dd7cSBALATON Zoltan case SDRAM_R3BAS: 5902a48dd7cSBALATON Zoltan case SDRAM_CONF1HB: 5912a48dd7cSBALATON Zoltan case SDRAM_CONF1LL: 5922a48dd7cSBALATON Zoltan case SDRAM_CONFPATHB: 5932a48dd7cSBALATON Zoltan case SDRAM_PLBADDULL: 5942a48dd7cSBALATON Zoltan case SDRAM_PLBADDUHB: 5952a48dd7cSBALATON Zoltan break; 5962a48dd7cSBALATON Zoltan case SDRAM0_CFGADDR: 59761cfe0dfSBALATON Zoltan s->addr = val; 5982a48dd7cSBALATON Zoltan break; 5992a48dd7cSBALATON Zoltan case SDRAM0_CFGDATA: 60061cfe0dfSBALATON Zoltan switch (s->addr) { 6012a48dd7cSBALATON Zoltan case 0x00: /* B0CR */ 6022a48dd7cSBALATON Zoltan break; 6032a48dd7cSBALATON Zoltan case 0x21: /* SDRAM_MCOPT2 */ 60461cfe0dfSBALATON Zoltan if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && 6052a48dd7cSBALATON Zoltan (val & SDRAM_DDR2_MCOPT2_DCEN)) { 6062a48dd7cSBALATON Zoltan trace_ppc4xx_sdram_enable("enable"); 6072a48dd7cSBALATON Zoltan /* validate all RAM mappings */ 608424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 609424a660cSBALATON Zoltan if (s->bank[i].size) { 610424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 611424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size, 612424a660cSBALATON Zoltan 1); 613424a660cSBALATON Zoltan } 614424a660cSBALATON Zoltan } 61561cfe0dfSBALATON Zoltan s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; 61661cfe0dfSBALATON Zoltan } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && 6172a48dd7cSBALATON Zoltan !(val & SDRAM_DDR2_MCOPT2_DCEN)) { 6182a48dd7cSBALATON Zoltan trace_ppc4xx_sdram_enable("disable"); 6192a48dd7cSBALATON Zoltan /* invalidate all RAM mappings */ 620424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 621424a660cSBALATON Zoltan if (s->bank[i].size) { 622424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 623424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size, 624424a660cSBALATON Zoltan 0); 625424a660cSBALATON Zoltan } 626424a660cSBALATON Zoltan } 62761cfe0dfSBALATON Zoltan s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; 6282a48dd7cSBALATON Zoltan } 6292a48dd7cSBALATON Zoltan break; 6302a48dd7cSBALATON Zoltan default: 6312a48dd7cSBALATON Zoltan break; 6322a48dd7cSBALATON Zoltan } 6332a48dd7cSBALATON Zoltan break; 6342a48dd7cSBALATON Zoltan default: 6352a48dd7cSBALATON Zoltan break; 6362a48dd7cSBALATON Zoltan } 6372a48dd7cSBALATON Zoltan } 6382a48dd7cSBALATON Zoltan 6392a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) 6402a48dd7cSBALATON Zoltan { 64161cfe0dfSBALATON Zoltan Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); 6422a48dd7cSBALATON Zoltan 64361cfe0dfSBALATON Zoltan s->addr = 0; 64461cfe0dfSBALATON Zoltan s->mcopt2 = 0; 6452a48dd7cSBALATON Zoltan } 6462a48dd7cSBALATON Zoltan 6472a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) 6482a48dd7cSBALATON Zoltan { 6492a48dd7cSBALATON Zoltan Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); 6502a48dd7cSBALATON Zoltan Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); 6512a48dd7cSBALATON Zoltan /* 6522a48dd7cSBALATON Zoltan * SoC also has 4 GiB but that causes problem with 32 bit 6532a48dd7cSBALATON Zoltan * builds (4*GiB overflows the 32 bit ram_addr_t). 6542a48dd7cSBALATON Zoltan */ 6552a48dd7cSBALATON Zoltan const ram_addr_t valid_bank_sizes[] = { 6562a48dd7cSBALATON Zoltan 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 6572a48dd7cSBALATON Zoltan 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 6582a48dd7cSBALATON Zoltan }; 659424a660cSBALATON Zoltan int i; 6602a48dd7cSBALATON Zoltan 6612a48dd7cSBALATON Zoltan if (s->nbanks < 1 || s->nbanks > 4) { 6622a48dd7cSBALATON Zoltan error_setg(errp, "Invalid number of RAM banks"); 6632a48dd7cSBALATON Zoltan return; 6642a48dd7cSBALATON Zoltan } 6652a48dd7cSBALATON Zoltan if (!s->dram_mr) { 6662a48dd7cSBALATON Zoltan error_setg(errp, "Missing dram memory region"); 6672a48dd7cSBALATON Zoltan return; 6682a48dd7cSBALATON Zoltan } 6692a48dd7cSBALATON Zoltan ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); 670424a660cSBALATON Zoltan for (i = 0; i < s->nbanks; i++) { 671424a660cSBALATON Zoltan if (s->bank[i].size) { 672424a660cSBALATON Zoltan s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size); 673424a660cSBALATON Zoltan s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK; 674424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, 675424a660cSBALATON Zoltan s->bank[i].base, s->bank[i].size, 0); 676424a660cSBALATON Zoltan } else { 677424a660cSBALATON Zoltan sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); 678424a660cSBALATON Zoltan } 679424a660cSBALATON Zoltan trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr), 680424a660cSBALATON Zoltan sdram_ddr2_size(s->bank[i].bcr), 681424a660cSBALATON Zoltan s->bank[i].bcr); 682424a660cSBALATON Zoltan } 6832a48dd7cSBALATON Zoltan 6842a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, 6852a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6862a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, 6872a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6882a48dd7cSBALATON Zoltan 6892a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R0BAS, 6902a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6912a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R1BAS, 6922a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6932a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R2BAS, 6942a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6952a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_R3BAS, 6962a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6972a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, 6982a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 6992a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, 7002a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 7012a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, 7022a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 7032a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, 7042a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 7052a48dd7cSBALATON Zoltan ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, 7062a48dd7cSBALATON Zoltan s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); 7072a48dd7cSBALATON Zoltan } 7082a48dd7cSBALATON Zoltan 7092a48dd7cSBALATON Zoltan static Property ppc4xx_sdram_ddr2_props[] = { 7102a48dd7cSBALATON Zoltan DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, 7112a48dd7cSBALATON Zoltan MemoryRegion *), 7122a48dd7cSBALATON Zoltan DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), 7132a48dd7cSBALATON Zoltan DEFINE_PROP_END_OF_LIST(), 7142a48dd7cSBALATON Zoltan }; 7152a48dd7cSBALATON Zoltan 7162a48dd7cSBALATON Zoltan static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) 7172a48dd7cSBALATON Zoltan { 7182a48dd7cSBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc); 7192a48dd7cSBALATON Zoltan 7202a48dd7cSBALATON Zoltan dc->realize = ppc4xx_sdram_ddr2_realize; 7212a48dd7cSBALATON Zoltan dc->reset = ppc4xx_sdram_ddr2_reset; 7222a48dd7cSBALATON Zoltan /* Reason: only works as function of a ppc4xx SoC */ 7232a48dd7cSBALATON Zoltan dc->user_creatable = false; 7242a48dd7cSBALATON Zoltan device_class_set_props(dc, ppc4xx_sdram_ddr2_props); 7252a48dd7cSBALATON Zoltan } 7262a48dd7cSBALATON Zoltan 7272a48dd7cSBALATON Zoltan void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) 7282a48dd7cSBALATON Zoltan { 7292a48dd7cSBALATON Zoltan sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); 7302a48dd7cSBALATON Zoltan sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); 7312a48dd7cSBALATON Zoltan } 7322a48dd7cSBALATON Zoltan 7332a48dd7cSBALATON Zoltan static const TypeInfo ppc4xx_sdram_types[] = { 7342a48dd7cSBALATON Zoltan { 735fa446fc5SBALATON Zoltan .name = TYPE_PPC4xx_SDRAM_DDR, 736fa446fc5SBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE, 737fa446fc5SBALATON Zoltan .instance_size = sizeof(Ppc4xxSdramDdrState), 738fa446fc5SBALATON Zoltan .class_init = ppc4xx_sdram_ddr_class_init, 739fa446fc5SBALATON Zoltan }, { 7402a48dd7cSBALATON Zoltan .name = TYPE_PPC4xx_SDRAM_DDR2, 7412a48dd7cSBALATON Zoltan .parent = TYPE_PPC4xx_DCR_DEVICE, 7422a48dd7cSBALATON Zoltan .instance_size = sizeof(Ppc4xxSdramDdr2State), 7432a48dd7cSBALATON Zoltan .class_init = ppc4xx_sdram_ddr2_class_init, 7442a48dd7cSBALATON Zoltan } 7452a48dd7cSBALATON Zoltan }; 7462a48dd7cSBALATON Zoltan 7472a48dd7cSBALATON Zoltan DEFINE_TYPES(ppc4xx_sdram_types) 748