1 /* 2 * OpenPOWER Palmetto BMC 3 * 4 * Andrew Jeffery <andrew@aj.id.au> 5 * 6 * Copyright 2016 IBM Corp. 7 * 8 * This code is licensed under the GPL version 2 or later. See 9 * the COPYING file in the top-level directory. 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qapi/error.h" 14 #include "qemu-common.h" 15 #include "cpu.h" 16 #include "exec/address-spaces.h" 17 #include "hw/arm/arm.h" 18 #include "hw/arm/aspeed_soc.h" 19 #include "hw/boards.h" 20 #include "qemu/log.h" 21 #include "sysemu/block-backend.h" 22 #include "hw/loader.h" 23 #include "qemu/error-report.h" 24 25 static struct arm_boot_info aspeed_board_binfo = { 26 .board_id = -1, /* device-tree-only board */ 27 .nb_cpus = 1, 28 }; 29 30 typedef struct AspeedBoardState { 31 AspeedSoCState soc; 32 MemoryRegion ram; 33 } AspeedBoardState; 34 35 typedef struct AspeedBoardConfig { 36 const char *soc_name; 37 uint32_t hw_strap1; 38 const char *fmc_model; 39 const char *spi_model; 40 uint32_t num_cs; 41 void (*i2c_init)(AspeedBoardState *bmc); 42 } AspeedBoardConfig; 43 44 enum { 45 PALMETTO_BMC, 46 AST2500_EVB, 47 ROMULUS_BMC, 48 WITHERSPOON_BMC, 49 }; 50 51 /* Palmetto hardware value: 0x120CE416 */ 52 #define PALMETTO_BMC_HW_STRAP1 ( \ 53 SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \ 54 SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \ 55 SCU_AST2400_HW_STRAP_ACPI_DIS | \ 56 SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) | \ 57 SCU_HW_STRAP_VGA_CLASS_CODE | \ 58 SCU_HW_STRAP_LPC_RESET_PIN | \ 59 SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) | \ 60 SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \ 61 SCU_HW_STRAP_SPI_WIDTH | \ 62 SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \ 63 SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT)) 64 65 /* AST2500 evb hardware value: 0xF100C2E6 */ 66 #define AST2500_EVB_HW_STRAP1 (( \ 67 AST2500_HW_STRAP1_DEFAULTS | \ 68 SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ 69 SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ 70 SCU_AST2500_HW_STRAP_UART_DEBUG | \ 71 SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ 72 SCU_HW_STRAP_MAC1_RGMII | \ 73 SCU_HW_STRAP_MAC0_RGMII) & \ 74 ~SCU_HW_STRAP_2ND_BOOT_WDT) 75 76 /* Romulus hardware value: 0xF10AD206 */ 77 #define ROMULUS_BMC_HW_STRAP1 ( \ 78 AST2500_HW_STRAP1_DEFAULTS | \ 79 SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ 80 SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ 81 SCU_AST2500_HW_STRAP_UART_DEBUG | \ 82 SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ 83 SCU_AST2500_HW_STRAP_ACPI_ENABLE | \ 84 SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER)) 85 86 /* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */ 87 #define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1 88 89 static void palmetto_bmc_i2c_init(AspeedBoardState *bmc); 90 static void ast2500_evb_i2c_init(AspeedBoardState *bmc); 91 static void romulus_bmc_i2c_init(AspeedBoardState *bmc); 92 static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc); 93 94 static const AspeedBoardConfig aspeed_boards[] = { 95 [PALMETTO_BMC] = { 96 .soc_name = "ast2400-a1", 97 .hw_strap1 = PALMETTO_BMC_HW_STRAP1, 98 .fmc_model = "n25q256a", 99 .spi_model = "mx25l25635e", 100 .num_cs = 1, 101 .i2c_init = palmetto_bmc_i2c_init, 102 }, 103 [AST2500_EVB] = { 104 .soc_name = "ast2500-a1", 105 .hw_strap1 = AST2500_EVB_HW_STRAP1, 106 .fmc_model = "n25q256a", 107 .spi_model = "mx25l25635e", 108 .num_cs = 1, 109 .i2c_init = ast2500_evb_i2c_init, 110 }, 111 [ROMULUS_BMC] = { 112 .soc_name = "ast2500-a1", 113 .hw_strap1 = ROMULUS_BMC_HW_STRAP1, 114 .fmc_model = "n25q256a", 115 .spi_model = "mx66l1g45g", 116 .num_cs = 2, 117 .i2c_init = romulus_bmc_i2c_init, 118 }, 119 [WITHERSPOON_BMC] = { 120 .soc_name = "ast2500-a1", 121 .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1, 122 .fmc_model = "mx25l25635e", 123 .spi_model = "mx66l1g45g", 124 .num_cs = 2, 125 .i2c_init = witherspoon_bmc_i2c_init, 126 }, 127 }; 128 129 #define FIRMWARE_ADDR 0x0 130 131 static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size, 132 Error **errp) 133 { 134 BlockBackend *blk = blk_by_legacy_dinfo(dinfo); 135 uint8_t *storage; 136 int64_t size; 137 138 /* The block backend size should have already been 'validated' by 139 * the creation of the m25p80 object. 140 */ 141 size = blk_getlength(blk); 142 if (size <= 0) { 143 error_setg(errp, "failed to get flash size"); 144 return; 145 } 146 147 if (rom_size > size) { 148 rom_size = size; 149 } 150 151 storage = g_new0(uint8_t, rom_size); 152 if (blk_pread(blk, 0, storage, rom_size) < 0) { 153 error_setg(errp, "failed to read the initial flash content"); 154 return; 155 } 156 157 rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr); 158 g_free(storage); 159 } 160 161 static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, 162 Error **errp) 163 { 164 int i ; 165 166 for (i = 0; i < s->num_cs; ++i) { 167 AspeedSMCFlash *fl = &s->flashes[i]; 168 DriveInfo *dinfo = drive_get_next(IF_MTD); 169 qemu_irq cs_line; 170 171 fl->flash = ssi_create_slave_no_init(s->spi, flashtype); 172 if (dinfo) { 173 qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo), 174 errp); 175 } 176 qdev_init_nofail(fl->flash); 177 178 cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0); 179 sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line); 180 } 181 } 182 183 static void aspeed_board_init(MachineState *machine, 184 const AspeedBoardConfig *cfg) 185 { 186 AspeedBoardState *bmc; 187 AspeedSoCClass *sc; 188 DriveInfo *drive0 = drive_get(IF_MTD, 0, 0); 189 190 bmc = g_new0(AspeedBoardState, 1); 191 object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name); 192 object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc), 193 &error_abort); 194 195 sc = ASPEED_SOC_GET_CLASS(&bmc->soc); 196 197 object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size", 198 &error_abort); 199 object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", 200 &error_abort); 201 object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", 202 &error_abort); 203 if (machine->kernel_filename) { 204 /* 205 * When booting with a -kernel command line there is no u-boot 206 * that runs to unlock the SCU. In this case set the default to 207 * be unlocked as the kernel expects 208 */ 209 object_property_set_int(OBJECT(&bmc->soc), ASPEED_SCU_PROT_KEY, 210 "hw-prot-key", &error_abort); 211 } 212 object_property_set_bool(OBJECT(&bmc->soc), true, "realized", 213 &error_abort); 214 215 /* 216 * Allocate RAM after the memory controller has checked the size 217 * was valid. If not, a default value is used. 218 */ 219 ram_size = object_property_get_uint(OBJECT(&bmc->soc), "ram-size", 220 &error_abort); 221 222 memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size); 223 memory_region_add_subregion(get_system_memory(), sc->info->sdram_base, 224 &bmc->ram); 225 object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram), 226 &error_abort); 227 228 aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort); 229 aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort); 230 231 /* Install first FMC flash content as a boot rom. */ 232 if (drive0) { 233 AspeedSMCFlash *fl = &bmc->soc.fmc.flashes[0]; 234 MemoryRegion *boot_rom = g_new(MemoryRegion, 1); 235 236 /* 237 * create a ROM region using the default mapping window size of 238 * the flash module. The window size is 64MB for the AST2400 239 * SoC and 128MB for the AST2500 SoC, which is twice as big as 240 * needed by the flash modules of the Aspeed machines. 241 */ 242 memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom", 243 fl->size, &error_abort); 244 memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR, 245 boot_rom); 246 write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort); 247 } 248 249 aspeed_board_binfo.kernel_filename = machine->kernel_filename; 250 aspeed_board_binfo.initrd_filename = machine->initrd_filename; 251 aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline; 252 aspeed_board_binfo.ram_size = ram_size; 253 aspeed_board_binfo.loader_start = sc->info->sdram_base; 254 255 if (cfg->i2c_init) { 256 cfg->i2c_init(bmc); 257 } 258 259 arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo); 260 } 261 262 static void palmetto_bmc_i2c_init(AspeedBoardState *bmc) 263 { 264 AspeedSoCState *soc = &bmc->soc; 265 DeviceState *dev; 266 267 /* The palmetto platform expects a ds3231 RTC but a ds1338 is 268 * enough to provide basic RTC features. Alarms will be missing */ 269 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68); 270 271 /* add a TMP423 temperature sensor */ 272 dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), 273 "tmp423", 0x4c); 274 object_property_set_int(OBJECT(dev), 31000, "temperature0", &error_abort); 275 object_property_set_int(OBJECT(dev), 28000, "temperature1", &error_abort); 276 object_property_set_int(OBJECT(dev), 20000, "temperature2", &error_abort); 277 object_property_set_int(OBJECT(dev), 110000, "temperature3", &error_abort); 278 } 279 280 static void palmetto_bmc_init(MachineState *machine) 281 { 282 aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]); 283 } 284 285 static void palmetto_bmc_class_init(ObjectClass *oc, void *data) 286 { 287 MachineClass *mc = MACHINE_CLASS(oc); 288 289 mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)"; 290 mc->init = palmetto_bmc_init; 291 mc->max_cpus = 1; 292 mc->no_sdcard = 1; 293 mc->no_floppy = 1; 294 mc->no_cdrom = 1; 295 mc->no_parallel = 1; 296 } 297 298 static const TypeInfo palmetto_bmc_type = { 299 .name = MACHINE_TYPE_NAME("palmetto-bmc"), 300 .parent = TYPE_MACHINE, 301 .class_init = palmetto_bmc_class_init, 302 }; 303 304 static void ast2500_evb_i2c_init(AspeedBoardState *bmc) 305 { 306 AspeedSoCState *soc = &bmc->soc; 307 308 /* The AST2500 EVB expects a LM75 but a TMP105 is compatible */ 309 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d); 310 311 /* The AST2500 EVB does not have an RTC. Let's pretend that one is 312 * plugged on the I2C bus header */ 313 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); 314 } 315 316 static void ast2500_evb_init(MachineState *machine) 317 { 318 aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]); 319 } 320 321 static void ast2500_evb_class_init(ObjectClass *oc, void *data) 322 { 323 MachineClass *mc = MACHINE_CLASS(oc); 324 325 mc->desc = "Aspeed AST2500 EVB (ARM1176)"; 326 mc->init = ast2500_evb_init; 327 mc->max_cpus = 1; 328 mc->no_sdcard = 1; 329 mc->no_floppy = 1; 330 mc->no_cdrom = 1; 331 mc->no_parallel = 1; 332 } 333 334 static const TypeInfo ast2500_evb_type = { 335 .name = MACHINE_TYPE_NAME("ast2500-evb"), 336 .parent = TYPE_MACHINE, 337 .class_init = ast2500_evb_class_init, 338 }; 339 340 static void romulus_bmc_i2c_init(AspeedBoardState *bmc) 341 { 342 AspeedSoCState *soc = &bmc->soc; 343 344 /* The romulus board expects Epson RX8900 I2C RTC but a ds1338 is 345 * good enough */ 346 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); 347 } 348 349 static void romulus_bmc_init(MachineState *machine) 350 { 351 aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]); 352 } 353 354 static void romulus_bmc_class_init(ObjectClass *oc, void *data) 355 { 356 MachineClass *mc = MACHINE_CLASS(oc); 357 358 mc->desc = "OpenPOWER Romulus BMC (ARM1176)"; 359 mc->init = romulus_bmc_init; 360 mc->max_cpus = 1; 361 mc->no_sdcard = 1; 362 mc->no_floppy = 1; 363 mc->no_cdrom = 1; 364 mc->no_parallel = 1; 365 } 366 367 static const TypeInfo romulus_bmc_type = { 368 .name = MACHINE_TYPE_NAME("romulus-bmc"), 369 .parent = TYPE_MACHINE, 370 .class_init = romulus_bmc_class_init, 371 }; 372 373 static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc) 374 { 375 AspeedSoCState *soc = &bmc->soc; 376 377 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c); 378 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c); 379 380 /* The Witherspoon expects a TMP275 but a TMP105 is compatible */ 381 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a); 382 383 /* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is 384 * good enough */ 385 i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32); 386 } 387 388 static void witherspoon_bmc_init(MachineState *machine) 389 { 390 aspeed_board_init(machine, &aspeed_boards[WITHERSPOON_BMC]); 391 } 392 393 static void witherspoon_bmc_class_init(ObjectClass *oc, void *data) 394 { 395 MachineClass *mc = MACHINE_CLASS(oc); 396 397 mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)"; 398 mc->init = witherspoon_bmc_init; 399 mc->max_cpus = 1; 400 mc->no_sdcard = 1; 401 mc->no_floppy = 1; 402 mc->no_cdrom = 1; 403 mc->no_parallel = 1; 404 } 405 406 static const TypeInfo witherspoon_bmc_type = { 407 .name = MACHINE_TYPE_NAME("witherspoon-bmc"), 408 .parent = TYPE_MACHINE, 409 .class_init = witherspoon_bmc_class_init, 410 }; 411 412 static void aspeed_machine_init(void) 413 { 414 type_register_static(&palmetto_bmc_type); 415 type_register_static(&ast2500_evb_type); 416 type_register_static(&romulus_bmc_type); 417 type_register_static(&witherspoon_bmc_type); 418 } 419 420 type_init(aspeed_machine_init) 421