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