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 "sysemu/blockdev.h" 23 24 static struct arm_boot_info aspeed_board_binfo = { 25 .board_id = -1, /* device-tree-only board */ 26 .nb_cpus = 1, 27 }; 28 29 typedef struct AspeedBoardState { 30 AspeedSoCState soc; 31 MemoryRegion ram; 32 } AspeedBoardState; 33 34 typedef struct AspeedBoardConfig { 35 const char *soc_name; 36 uint32_t hw_strap1; 37 const char *fmc_model; 38 const char *spi_model; 39 uint32_t num_cs; 40 } AspeedBoardConfig; 41 42 enum { 43 PALMETTO_BMC, 44 AST2500_EVB, 45 ROMULUS_BMC, 46 }; 47 48 /* Palmetto hardware value: 0x120CE416 */ 49 #define PALMETTO_BMC_HW_STRAP1 ( \ 50 SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \ 51 SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \ 52 SCU_AST2400_HW_STRAP_ACPI_DIS | \ 53 SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) | \ 54 SCU_HW_STRAP_VGA_CLASS_CODE | \ 55 SCU_HW_STRAP_LPC_RESET_PIN | \ 56 SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) | \ 57 SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \ 58 SCU_HW_STRAP_SPI_WIDTH | \ 59 SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \ 60 SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT)) 61 62 /* AST2500 evb hardware value: 0xF100C2E6 */ 63 #define AST2500_EVB_HW_STRAP1 (( \ 64 AST2500_HW_STRAP1_DEFAULTS | \ 65 SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ 66 SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ 67 SCU_AST2500_HW_STRAP_UART_DEBUG | \ 68 SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ 69 SCU_HW_STRAP_MAC1_RGMII | \ 70 SCU_HW_STRAP_MAC0_RGMII) & \ 71 ~SCU_HW_STRAP_2ND_BOOT_WDT) 72 73 /* Romulus hardware value: 0xF10AD206 */ 74 #define ROMULUS_BMC_HW_STRAP1 ( \ 75 AST2500_HW_STRAP1_DEFAULTS | \ 76 SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ 77 SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ 78 SCU_AST2500_HW_STRAP_UART_DEBUG | \ 79 SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ 80 SCU_AST2500_HW_STRAP_ACPI_ENABLE | \ 81 SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER)) 82 83 static const AspeedBoardConfig aspeed_boards[] = { 84 [PALMETTO_BMC] = { 85 .soc_name = "ast2400-a1", 86 .hw_strap1 = PALMETTO_BMC_HW_STRAP1, 87 .fmc_model = "n25q256a", 88 .spi_model = "mx25l25635e", 89 .num_cs = 1, 90 }, 91 [AST2500_EVB] = { 92 .soc_name = "ast2500-a1", 93 .hw_strap1 = AST2500_EVB_HW_STRAP1, 94 .fmc_model = "n25q256a", 95 .spi_model = "mx25l25635e", 96 .num_cs = 1, 97 }, 98 [ROMULUS_BMC] = { 99 .soc_name = "ast2500-a1", 100 .hw_strap1 = ROMULUS_BMC_HW_STRAP1, 101 .fmc_model = "n25q256a", 102 .spi_model = "mx66l1g45g", 103 .num_cs = 2, 104 }, 105 }; 106 107 static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, 108 Error **errp) 109 { 110 int i ; 111 112 for (i = 0; i < s->num_cs; ++i) { 113 AspeedSMCFlash *fl = &s->flashes[i]; 114 DriveInfo *dinfo = drive_get_next(IF_MTD); 115 qemu_irq cs_line; 116 117 /* 118 * FIXME: check that we are not using a flash module exceeding 119 * the controller segment size 120 */ 121 fl->flash = ssi_create_slave_no_init(s->spi, flashtype); 122 if (dinfo) { 123 qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo), 124 errp); 125 } 126 qdev_init_nofail(fl->flash); 127 128 cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0); 129 sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line); 130 } 131 } 132 133 static void aspeed_board_init(MachineState *machine, 134 const AspeedBoardConfig *cfg) 135 { 136 AspeedBoardState *bmc; 137 AspeedSoCClass *sc; 138 139 bmc = g_new0(AspeedBoardState, 1); 140 object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name); 141 object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc), 142 &error_abort); 143 144 sc = ASPEED_SOC_GET_CLASS(&bmc->soc); 145 146 object_property_set_int(OBJECT(&bmc->soc), ram_size, "ram-size", 147 &error_abort); 148 object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", 149 &error_abort); 150 object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", 151 &error_abort); 152 object_property_set_bool(OBJECT(&bmc->soc), true, "realized", 153 &error_abort); 154 155 /* 156 * Allocate RAM after the memory controller has checked the size 157 * was valid. If not, a default value is used. 158 */ 159 ram_size = object_property_get_int(OBJECT(&bmc->soc), "ram-size", 160 &error_abort); 161 162 memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size); 163 memory_region_add_subregion(get_system_memory(), sc->info->sdram_base, 164 &bmc->ram); 165 object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram), 166 &error_abort); 167 168 aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort); 169 aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort); 170 171 aspeed_board_binfo.kernel_filename = machine->kernel_filename; 172 aspeed_board_binfo.initrd_filename = machine->initrd_filename; 173 aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline; 174 aspeed_board_binfo.ram_size = ram_size; 175 aspeed_board_binfo.loader_start = sc->info->sdram_base; 176 177 arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo); 178 } 179 180 static void palmetto_bmc_init(MachineState *machine) 181 { 182 aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]); 183 } 184 185 static void palmetto_bmc_class_init(ObjectClass *oc, void *data) 186 { 187 MachineClass *mc = MACHINE_CLASS(oc); 188 189 mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)"; 190 mc->init = palmetto_bmc_init; 191 mc->max_cpus = 1; 192 mc->no_sdcard = 1; 193 mc->no_floppy = 1; 194 mc->no_cdrom = 1; 195 mc->no_parallel = 1; 196 } 197 198 static const TypeInfo palmetto_bmc_type = { 199 .name = MACHINE_TYPE_NAME("palmetto-bmc"), 200 .parent = TYPE_MACHINE, 201 .class_init = palmetto_bmc_class_init, 202 }; 203 204 static void ast2500_evb_init(MachineState *machine) 205 { 206 aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]); 207 } 208 209 static void ast2500_evb_class_init(ObjectClass *oc, void *data) 210 { 211 MachineClass *mc = MACHINE_CLASS(oc); 212 213 mc->desc = "Aspeed AST2500 EVB (ARM1176)"; 214 mc->init = ast2500_evb_init; 215 mc->max_cpus = 1; 216 mc->no_sdcard = 1; 217 mc->no_floppy = 1; 218 mc->no_cdrom = 1; 219 mc->no_parallel = 1; 220 } 221 222 static const TypeInfo ast2500_evb_type = { 223 .name = MACHINE_TYPE_NAME("ast2500-evb"), 224 .parent = TYPE_MACHINE, 225 .class_init = ast2500_evb_class_init, 226 }; 227 228 static void romulus_bmc_init(MachineState *machine) 229 { 230 aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]); 231 } 232 233 static void romulus_bmc_class_init(ObjectClass *oc, void *data) 234 { 235 MachineClass *mc = MACHINE_CLASS(oc); 236 237 mc->desc = "OpenPOWER Romulus BMC (ARM1176)"; 238 mc->init = romulus_bmc_init; 239 mc->max_cpus = 1; 240 mc->no_sdcard = 1; 241 mc->no_floppy = 1; 242 mc->no_cdrom = 1; 243 mc->no_parallel = 1; 244 } 245 246 static const TypeInfo romulus_bmc_type = { 247 .name = MACHINE_TYPE_NAME("romulus-bmc"), 248 .parent = TYPE_MACHINE, 249 .class_init = romulus_bmc_class_init, 250 }; 251 252 static void aspeed_machine_init(void) 253 { 254 type_register_static(&palmetto_bmc_type); 255 type_register_static(&ast2500_evb_type); 256 type_register_static(&romulus_bmc_type); 257 } 258 259 type_init(aspeed_machine_init) 260