1 /* 2 * ASPEED SDRAM Memory Controller 3 * 4 * Copyright (C) 2016 IBM Corp. 5 * 6 * This code is licensed under the GPL version 2 or later. See 7 * the COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "qemu/log.h" 12 #include "qemu/module.h" 13 #include "qemu/error-report.h" 14 #include "hw/misc/aspeed_sdmc.h" 15 #include "hw/misc/aspeed_scu.h" 16 #include "hw/qdev-properties.h" 17 #include "migration/vmstate.h" 18 #include "qapi/error.h" 19 #include "trace.h" 20 21 /* Protection Key Register */ 22 #define R_PROT (0x00 / 4) 23 #define PROT_KEY_UNLOCK 0xFC600309 24 25 /* Configuration Register */ 26 #define R_CONF (0x04 / 4) 27 28 /* Control/Status Register #1 (ast2500) */ 29 #define R_STATUS1 (0x60 / 4) 30 #define PHY_BUSY_STATE BIT(0) 31 #define PHY_PLL_LOCK_STATUS BIT(4) 32 33 #define R_ECC_TEST_CTRL (0x70 / 4) 34 #define ECC_TEST_FINISHED BIT(12) 35 #define ECC_TEST_FAIL BIT(13) 36 37 /* 38 * Configuration register Ox4 (for Aspeed AST2400 SOC) 39 * 40 * These are for the record and future use. ASPEED_SDMC_DRAM_SIZE is 41 * what we care about right now as it is checked by U-Boot to 42 * determine the RAM size. 43 */ 44 45 #define ASPEED_SDMC_RESERVED 0xFFFFF800 /* 31:11 reserved */ 46 #define ASPEED_SDMC_AST2300_COMPAT (1 << 10) 47 #define ASPEED_SDMC_SCRAMBLE_PATTERN (1 << 9) 48 #define ASPEED_SDMC_DATA_SCRAMBLE (1 << 8) 49 #define ASPEED_SDMC_ECC_ENABLE (1 << 7) 50 #define ASPEED_SDMC_VGA_COMPAT (1 << 6) /* readonly */ 51 #define ASPEED_SDMC_DRAM_BANK (1 << 5) 52 #define ASPEED_SDMC_DRAM_BURST (1 << 4) 53 #define ASPEED_SDMC_VGA_APERTURE(x) ((x & 0x3) << 2) /* readonly */ 54 #define ASPEED_SDMC_VGA_8MB 0x0 55 #define ASPEED_SDMC_VGA_16MB 0x1 56 #define ASPEED_SDMC_VGA_32MB 0x2 57 #define ASPEED_SDMC_VGA_64MB 0x3 58 #define ASPEED_SDMC_DRAM_SIZE(x) (x & 0x3) 59 #define ASPEED_SDMC_DRAM_64MB 0x0 60 #define ASPEED_SDMC_DRAM_128MB 0x1 61 #define ASPEED_SDMC_DRAM_256MB 0x2 62 #define ASPEED_SDMC_DRAM_512MB 0x3 63 64 #define ASPEED_SDMC_READONLY_MASK \ 65 (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT | \ 66 ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB)) 67 /* 68 * Configuration register Ox4 (for Aspeed AST2500 SOC and higher) 69 * 70 * Incompatibilities are annotated in the list. ASPEED_SDMC_HW_VERSION 71 * should be set to 1 for the AST2500 SOC. 72 */ 73 #define ASPEED_SDMC_HW_VERSION(x) ((x & 0xf) << 28) /* readonly */ 74 #define ASPEED_SDMC_SW_VERSION ((x & 0xff) << 20) 75 #define ASPEED_SDMC_CACHE_INITIAL_DONE (1 << 19) /* readonly */ 76 #define ASPEED_SDMC_AST2500_RESERVED 0x7C000 /* 18:14 reserved */ 77 #define ASPEED_SDMC_CACHE_DDR4_CONF (1 << 13) 78 #define ASPEED_SDMC_CACHE_INITIAL (1 << 12) 79 #define ASPEED_SDMC_CACHE_RANGE_CTRL (1 << 11) 80 #define ASPEED_SDMC_CACHE_ENABLE (1 << 10) /* differs from AST2400 */ 81 #define ASPEED_SDMC_DRAM_TYPE (1 << 4) /* differs from AST2400 */ 82 83 /* DRAM size definitions differs */ 84 #define ASPEED_SDMC_AST2500_128MB 0x0 85 #define ASPEED_SDMC_AST2500_256MB 0x1 86 #define ASPEED_SDMC_AST2500_512MB 0x2 87 #define ASPEED_SDMC_AST2500_1024MB 0x3 88 89 #define ASPEED_SDMC_AST2600_256MB 0x0 90 #define ASPEED_SDMC_AST2600_512MB 0x1 91 #define ASPEED_SDMC_AST2600_1024MB 0x2 92 #define ASPEED_SDMC_AST2600_2048MB 0x3 93 94 #define ASPEED_SDMC_AST2500_READONLY_MASK \ 95 (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \ 96 ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT | \ 97 ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB)) 98 99 static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size) 100 { 101 AspeedSDMCState *s = ASPEED_SDMC(opaque); 102 103 addr >>= 2; 104 105 if (addr >= ARRAY_SIZE(s->regs)) { 106 qemu_log_mask(LOG_GUEST_ERROR, 107 "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n", 108 __func__, addr); 109 return 0; 110 } 111 112 return s->regs[addr]; 113 } 114 115 static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data, 116 unsigned int size) 117 { 118 AspeedSDMCState *s = ASPEED_SDMC(opaque); 119 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s); 120 121 addr >>= 2; 122 123 if (addr >= ARRAY_SIZE(s->regs)) { 124 qemu_log_mask(LOG_GUEST_ERROR, 125 "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n", 126 __func__, addr); 127 return; 128 } 129 130 if (addr == R_PROT) { 131 s->regs[addr] = (data == PROT_KEY_UNLOCK) ? 1 : 0; 132 return; 133 } 134 135 if (!s->regs[R_PROT]) { 136 qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__); 137 return; 138 } 139 140 asc->write(s, addr, data); 141 } 142 143 static const MemoryRegionOps aspeed_sdmc_ops = { 144 .read = aspeed_sdmc_read, 145 .write = aspeed_sdmc_write, 146 .endianness = DEVICE_LITTLE_ENDIAN, 147 .valid.min_access_size = 4, 148 .valid.max_access_size = 4, 149 }; 150 151 static int ast2400_rambits(AspeedSDMCState *s) 152 { 153 switch (s->ram_size >> 20) { 154 case 64: 155 return ASPEED_SDMC_DRAM_64MB; 156 case 128: 157 return ASPEED_SDMC_DRAM_128MB; 158 case 256: 159 return ASPEED_SDMC_DRAM_256MB; 160 case 512: 161 return ASPEED_SDMC_DRAM_512MB; 162 default: 163 break; 164 } 165 166 /* use a common default */ 167 warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 256M", 168 s->ram_size); 169 s->ram_size = 256 << 20; 170 return ASPEED_SDMC_DRAM_256MB; 171 } 172 173 static int ast2500_rambits(AspeedSDMCState *s) 174 { 175 switch (s->ram_size >> 20) { 176 case 128: 177 return ASPEED_SDMC_AST2500_128MB; 178 case 256: 179 return ASPEED_SDMC_AST2500_256MB; 180 case 512: 181 return ASPEED_SDMC_AST2500_512MB; 182 case 1024: 183 return ASPEED_SDMC_AST2500_1024MB; 184 default: 185 break; 186 } 187 188 /* use a common default */ 189 warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M", 190 s->ram_size); 191 s->ram_size = 512 << 20; 192 return ASPEED_SDMC_AST2500_512MB; 193 } 194 195 static int ast2600_rambits(AspeedSDMCState *s) 196 { 197 switch (s->ram_size >> 20) { 198 case 256: 199 return ASPEED_SDMC_AST2600_256MB; 200 case 512: 201 return ASPEED_SDMC_AST2600_512MB; 202 case 1024: 203 return ASPEED_SDMC_AST2600_1024MB; 204 case 2048: 205 return ASPEED_SDMC_AST2600_2048MB; 206 default: 207 break; 208 } 209 210 /* use a common default */ 211 warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M", 212 s->ram_size); 213 s->ram_size = 1024 << 20; 214 return ASPEED_SDMC_AST2600_1024MB; 215 } 216 217 static void aspeed_sdmc_reset(DeviceState *dev) 218 { 219 AspeedSDMCState *s = ASPEED_SDMC(dev); 220 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s); 221 222 memset(s->regs, 0, sizeof(s->regs)); 223 224 /* Set ram size bit and defaults values */ 225 s->regs[R_CONF] = asc->compute_conf(s, 0); 226 } 227 228 static void aspeed_sdmc_realize(DeviceState *dev, Error **errp) 229 { 230 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 231 AspeedSDMCState *s = ASPEED_SDMC(dev); 232 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s); 233 234 s->max_ram_size = asc->max_ram_size; 235 236 memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s, 237 TYPE_ASPEED_SDMC, 0x1000); 238 sysbus_init_mmio(sbd, &s->iomem); 239 } 240 241 static const VMStateDescription vmstate_aspeed_sdmc = { 242 .name = "aspeed.sdmc", 243 .version_id = 1, 244 .minimum_version_id = 1, 245 .fields = (VMStateField[]) { 246 VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS), 247 VMSTATE_END_OF_LIST() 248 } 249 }; 250 251 static Property aspeed_sdmc_properties[] = { 252 DEFINE_PROP_UINT64("ram-size", AspeedSDMCState, ram_size, 0), 253 DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0), 254 DEFINE_PROP_END_OF_LIST(), 255 }; 256 257 static void aspeed_sdmc_class_init(ObjectClass *klass, void *data) 258 { 259 DeviceClass *dc = DEVICE_CLASS(klass); 260 dc->realize = aspeed_sdmc_realize; 261 dc->reset = aspeed_sdmc_reset; 262 dc->desc = "ASPEED SDRAM Memory Controller"; 263 dc->vmsd = &vmstate_aspeed_sdmc; 264 device_class_set_props(dc, aspeed_sdmc_properties); 265 } 266 267 static const TypeInfo aspeed_sdmc_info = { 268 .name = TYPE_ASPEED_SDMC, 269 .parent = TYPE_SYS_BUS_DEVICE, 270 .instance_size = sizeof(AspeedSDMCState), 271 .class_init = aspeed_sdmc_class_init, 272 .class_size = sizeof(AspeedSDMCClass), 273 .abstract = true, 274 }; 275 276 static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) 277 { 278 uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT | 279 ASPEED_SDMC_DRAM_SIZE(ast2400_rambits(s)); 280 281 /* Make sure readonly bits are kept */ 282 data &= ~ASPEED_SDMC_READONLY_MASK; 283 284 return data | fixed_conf; 285 } 286 287 static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg, 288 uint32_t data) 289 { 290 switch (reg) { 291 case R_CONF: 292 data = aspeed_2400_sdmc_compute_conf(s, data); 293 break; 294 default: 295 break; 296 } 297 298 s->regs[reg] = data; 299 } 300 301 static void aspeed_2400_sdmc_class_init(ObjectClass *klass, void *data) 302 { 303 DeviceClass *dc = DEVICE_CLASS(klass); 304 AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); 305 306 dc->desc = "ASPEED 2400 SDRAM Memory Controller"; 307 asc->max_ram_size = 512 << 20; 308 asc->compute_conf = aspeed_2400_sdmc_compute_conf; 309 asc->write = aspeed_2400_sdmc_write; 310 } 311 312 static const TypeInfo aspeed_2400_sdmc_info = { 313 .name = TYPE_ASPEED_2400_SDMC, 314 .parent = TYPE_ASPEED_SDMC, 315 .class_init = aspeed_2400_sdmc_class_init, 316 }; 317 318 static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) 319 { 320 uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) | 321 ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) | 322 ASPEED_SDMC_CACHE_INITIAL_DONE | 323 ASPEED_SDMC_DRAM_SIZE(ast2500_rambits(s)); 324 325 /* Make sure readonly bits are kept */ 326 data &= ~ASPEED_SDMC_AST2500_READONLY_MASK; 327 328 return data | fixed_conf; 329 } 330 331 static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg, 332 uint32_t data) 333 { 334 switch (reg) { 335 case R_CONF: 336 data = aspeed_2500_sdmc_compute_conf(s, data); 337 break; 338 case R_STATUS1: 339 /* Will never return 'busy' */ 340 data &= ~PHY_BUSY_STATE; 341 break; 342 case R_ECC_TEST_CTRL: 343 /* Always done, always happy */ 344 data |= ECC_TEST_FINISHED; 345 data &= ~ECC_TEST_FAIL; 346 break; 347 default: 348 break; 349 } 350 351 s->regs[reg] = data; 352 } 353 354 static void aspeed_2500_sdmc_class_init(ObjectClass *klass, void *data) 355 { 356 DeviceClass *dc = DEVICE_CLASS(klass); 357 AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); 358 359 dc->desc = "ASPEED 2500 SDRAM Memory Controller"; 360 asc->max_ram_size = 1024 << 20; 361 asc->compute_conf = aspeed_2500_sdmc_compute_conf; 362 asc->write = aspeed_2500_sdmc_write; 363 } 364 365 static const TypeInfo aspeed_2500_sdmc_info = { 366 .name = TYPE_ASPEED_2500_SDMC, 367 .parent = TYPE_ASPEED_SDMC, 368 .class_init = aspeed_2500_sdmc_class_init, 369 }; 370 371 static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) 372 { 373 uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) | 374 ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) | 375 ASPEED_SDMC_DRAM_SIZE(ast2600_rambits(s)); 376 377 /* Make sure readonly bits are kept (use ast2500 mask) */ 378 data &= ~ASPEED_SDMC_AST2500_READONLY_MASK; 379 380 return data | fixed_conf; 381 } 382 383 static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg, 384 uint32_t data) 385 { 386 switch (reg) { 387 case R_CONF: 388 data = aspeed_2600_sdmc_compute_conf(s, data); 389 break; 390 case R_STATUS1: 391 /* Will never return 'busy'. 'lock status' is always set */ 392 data &= ~PHY_BUSY_STATE; 393 data |= PHY_PLL_LOCK_STATUS; 394 break; 395 case R_ECC_TEST_CTRL: 396 /* Always done, always happy */ 397 data |= ECC_TEST_FINISHED; 398 data &= ~ECC_TEST_FAIL; 399 break; 400 default: 401 break; 402 } 403 404 s->regs[reg] = data; 405 } 406 407 static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data) 408 { 409 DeviceClass *dc = DEVICE_CLASS(klass); 410 AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); 411 412 dc->desc = "ASPEED 2600 SDRAM Memory Controller"; 413 asc->max_ram_size = 2048 << 20; 414 asc->compute_conf = aspeed_2600_sdmc_compute_conf; 415 asc->write = aspeed_2600_sdmc_write; 416 } 417 418 static const TypeInfo aspeed_2600_sdmc_info = { 419 .name = TYPE_ASPEED_2600_SDMC, 420 .parent = TYPE_ASPEED_SDMC, 421 .class_init = aspeed_2600_sdmc_class_init, 422 }; 423 424 static void aspeed_sdmc_register_types(void) 425 { 426 type_register_static(&aspeed_sdmc_info); 427 type_register_static(&aspeed_2400_sdmc_info); 428 type_register_static(&aspeed_2500_sdmc_info); 429 type_register_static(&aspeed_2600_sdmc_info); 430 } 431 432 type_init(aspeed_sdmc_register_types); 433