xref: /qemu/hw/arm/aspeed_ast27x0-fc.c (revision 80db93b2b88f9b3ed8927ae7ac74ca30e643a83e)
1a74faf35SSteven Lee /*
2a74faf35SSteven Lee  * ASPEED SoC 2700 family
3a74faf35SSteven Lee  *
4a74faf35SSteven Lee  * Copyright (C) 2025 ASPEED Technology Inc.
5a74faf35SSteven Lee  *
6a74faf35SSteven Lee  * This code is licensed under the GPL version 2 or later.  See
7a74faf35SSteven Lee  * the COPYING file in the top-level directory.
8a74faf35SSteven Lee  *
9a74faf35SSteven Lee  * SPDX-License-Identifier: GPL-2.0-or-later
10a74faf35SSteven Lee  */
11a74faf35SSteven Lee 
12a74faf35SSteven Lee #include "qemu/osdep.h"
13a74faf35SSteven Lee #include "qemu/units.h"
14a74faf35SSteven Lee #include "qapi/error.h"
15a74faf35SSteven Lee #include "system/block-backend.h"
16a74faf35SSteven Lee #include "system/system.h"
17a74faf35SSteven Lee #include "hw/arm/aspeed.h"
18a74faf35SSteven Lee #include "hw/boards.h"
19a74faf35SSteven Lee #include "hw/qdev-clock.h"
20a74faf35SSteven Lee #include "hw/arm/aspeed_soc.h"
21a74faf35SSteven Lee #include "hw/loader.h"
22a74faf35SSteven Lee #include "hw/arm/boot.h"
23a74faf35SSteven Lee #include "hw/block/flash.h"
24a74faf35SSteven Lee 
25a74faf35SSteven Lee 
26a74faf35SSteven Lee #define TYPE_AST2700A1FC MACHINE_TYPE_NAME("ast2700fc")
27a74faf35SSteven Lee OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700A1FC);
28a74faf35SSteven Lee 
29a74faf35SSteven Lee static struct arm_boot_info ast2700fc_board_info = {
30a74faf35SSteven Lee     .board_id = -1, /* device-tree-only board */
31a74faf35SSteven Lee };
32a74faf35SSteven Lee 
33a74faf35SSteven Lee struct Ast2700FCState {
34a74faf35SSteven Lee     MachineState parent_obj;
35a74faf35SSteven Lee 
36a74faf35SSteven Lee     MemoryRegion ca35_memory;
37a74faf35SSteven Lee     MemoryRegion ca35_dram;
38a74faf35SSteven Lee     MemoryRegion ssp_memory;
39a74faf35SSteven Lee     MemoryRegion tsp_memory;
40a74faf35SSteven Lee 
41a74faf35SSteven Lee     Clock *ssp_sysclk;
42a74faf35SSteven Lee     Clock *tsp_sysclk;
43a74faf35SSteven Lee 
44a74faf35SSteven Lee     Aspeed27x0SoCState ca35;
45a74faf35SSteven Lee     Aspeed27x0SSPSoCState ssp;
46a74faf35SSteven Lee     Aspeed27x0TSPSoCState tsp;
47a74faf35SSteven Lee 
48a74faf35SSteven Lee     bool mmio_exec;
49a74faf35SSteven Lee };
50a74faf35SSteven Lee 
5161162c6fSSteven Lee #define AST2700FC_BMC_RAM_SIZE (1 * GiB)
52a74faf35SSteven Lee #define AST2700FC_CM4_DRAM_SIZE (32 * MiB)
53a74faf35SSteven Lee 
54a74faf35SSteven Lee #define AST2700FC_HW_STRAP1 0x000000C0
55a74faf35SSteven Lee #define AST2700FC_HW_STRAP2 0x00000003
56a74faf35SSteven Lee #define AST2700FC_FMC_MODEL "w25q01jvq"
57a74faf35SSteven Lee #define AST2700FC_SPI_MODEL "w25q512jv"
58a74faf35SSteven Lee 
ast2700fc_ca35_init(MachineState * machine)59a74faf35SSteven Lee static void ast2700fc_ca35_init(MachineState *machine)
60a74faf35SSteven Lee {
61a74faf35SSteven Lee     Ast2700FCState *s = AST2700A1FC(machine);
62a74faf35SSteven Lee     AspeedSoCState *soc;
63a74faf35SSteven Lee     AspeedSoCClass *sc;
64a74faf35SSteven Lee 
65a74faf35SSteven Lee     object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1");
66a74faf35SSteven Lee     soc = ASPEED_SOC(&s->ca35);
67a74faf35SSteven Lee     sc = ASPEED_SOC_GET_CLASS(soc);
68a74faf35SSteven Lee 
69a74faf35SSteven Lee     memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
70a74faf35SSteven Lee                        UINT64_MAX);
71*bb1747a3SSteven Lee     memory_region_add_subregion(get_system_memory(), 0, &s->ca35_memory);
72a74faf35SSteven Lee 
73a74faf35SSteven Lee     if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
74a74faf35SSteven Lee                                 AST2700FC_BMC_RAM_SIZE, &error_abort)) {
75a74faf35SSteven Lee         return;
76a74faf35SSteven Lee     }
77a74faf35SSteven Lee     if (!object_property_set_link(OBJECT(&s->ca35), "memory",
78a74faf35SSteven Lee                                   OBJECT(&s->ca35_memory),
79a74faf35SSteven Lee                                   &error_abort)) {
80a74faf35SSteven Lee         return;
81a74faf35SSteven Lee     };
82a74faf35SSteven Lee     if (!object_property_set_link(OBJECT(&s->ca35), "dram",
83a74faf35SSteven Lee                                   OBJECT(&s->ca35_dram), &error_abort)) {
84a74faf35SSteven Lee         return;
85a74faf35SSteven Lee     }
86a74faf35SSteven Lee     if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
87a74faf35SSteven Lee                                  AST2700FC_BMC_RAM_SIZE, &error_abort)) {
88a74faf35SSteven Lee         return;
89a74faf35SSteven Lee     }
90453b928aSSteven Lee 
91453b928aSSteven Lee     for (int i = 0; i < sc->macs_num; i++) {
92453b928aSSteven Lee         if (!qemu_configure_nic_device(DEVICE(&soc->ftgmac100[i]),
93453b928aSSteven Lee                                        true, NULL)) {
94453b928aSSteven Lee             break;
95453b928aSSteven Lee         }
96453b928aSSteven Lee     }
97a74faf35SSteven Lee     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
98a74faf35SSteven Lee                                  AST2700FC_HW_STRAP1, &error_abort)) {
99a74faf35SSteven Lee         return;
100a74faf35SSteven Lee     }
101a74faf35SSteven Lee     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
102a74faf35SSteven Lee                                  AST2700FC_HW_STRAP2, &error_abort)) {
103a74faf35SSteven Lee         return;
104a74faf35SSteven Lee     }
105a74faf35SSteven Lee     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
106a74faf35SSteven Lee     if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
107a74faf35SSteven Lee         return;
108a74faf35SSteven Lee     }
109a74faf35SSteven Lee 
110a74faf35SSteven Lee     /*
111a74faf35SSteven Lee      * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
112a74faf35SSteven Lee      */
113a74faf35SSteven Lee     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
114a74faf35SSteven Lee 
115a74faf35SSteven Lee     aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
116a74faf35SSteven Lee     aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
117a74faf35SSteven Lee 
118a74faf35SSteven Lee     ast2700fc_board_info.ram_size = machine->ram_size;
119a74faf35SSteven Lee     ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
120a74faf35SSteven Lee 
121a74faf35SSteven Lee     arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
122a74faf35SSteven Lee }
123a74faf35SSteven Lee 
ast2700fc_ssp_init(MachineState * machine)124a74faf35SSteven Lee static void ast2700fc_ssp_init(MachineState *machine)
125a74faf35SSteven Lee {
126a74faf35SSteven Lee     AspeedSoCState *soc;
127a74faf35SSteven Lee     Ast2700FCState *s = AST2700A1FC(machine);
128a74faf35SSteven Lee     s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
129a74faf35SSteven Lee     clock_set_hz(s->ssp_sysclk, 200000000ULL);
130a74faf35SSteven Lee 
131a74faf35SSteven Lee     object_initialize_child(OBJECT(s), "ssp", &s->ssp, TYPE_ASPEED27X0SSP_SOC);
132a74faf35SSteven Lee     memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
133a74faf35SSteven Lee                        UINT64_MAX);
134a74faf35SSteven Lee 
135a74faf35SSteven Lee     qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
136a74faf35SSteven Lee     if (!object_property_set_link(OBJECT(&s->ssp), "memory",
137a74faf35SSteven Lee                                   OBJECT(&s->ssp_memory), &error_abort)) {
138a74faf35SSteven Lee         return;
139a74faf35SSteven Lee     }
140a74faf35SSteven Lee 
141a74faf35SSteven Lee     soc = ASPEED_SOC(&s->ssp);
142a74faf35SSteven Lee     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
143a74faf35SSteven Lee     if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
144a74faf35SSteven Lee         return;
145a74faf35SSteven Lee     }
146a74faf35SSteven Lee }
147a74faf35SSteven Lee 
ast2700fc_tsp_init(MachineState * machine)148a74faf35SSteven Lee static void ast2700fc_tsp_init(MachineState *machine)
149a74faf35SSteven Lee {
150a74faf35SSteven Lee     AspeedSoCState *soc;
151a74faf35SSteven Lee     Ast2700FCState *s = AST2700A1FC(machine);
152a74faf35SSteven Lee     s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
153a74faf35SSteven Lee     clock_set_hz(s->tsp_sysclk, 200000000ULL);
154a74faf35SSteven Lee 
155a74faf35SSteven Lee     object_initialize_child(OBJECT(s), "tsp", &s->tsp, TYPE_ASPEED27X0TSP_SOC);
156a74faf35SSteven Lee     memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
157a74faf35SSteven Lee                        UINT64_MAX);
158a74faf35SSteven Lee 
159a74faf35SSteven Lee     qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
160a74faf35SSteven Lee     if (!object_property_set_link(OBJECT(&s->tsp), "memory",
161a74faf35SSteven Lee                                   OBJECT(&s->tsp_memory), &error_abort)) {
162a74faf35SSteven Lee         return;
163a74faf35SSteven Lee     }
164a74faf35SSteven Lee 
165a74faf35SSteven Lee     soc = ASPEED_SOC(&s->tsp);
166a74faf35SSteven Lee     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2));
167a74faf35SSteven Lee     if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
168a74faf35SSteven Lee         return;
169a74faf35SSteven Lee     }
170a74faf35SSteven Lee }
171a74faf35SSteven Lee 
ast2700fc_init(MachineState * machine)172a74faf35SSteven Lee static void ast2700fc_init(MachineState *machine)
173a74faf35SSteven Lee {
174a74faf35SSteven Lee     ast2700fc_ca35_init(machine);
175a74faf35SSteven Lee     ast2700fc_ssp_init(machine);
176a74faf35SSteven Lee     ast2700fc_tsp_init(machine);
177a74faf35SSteven Lee }
178a74faf35SSteven Lee 
ast2700fc_class_init(ObjectClass * oc,const void * data)179a74faf35SSteven Lee static void ast2700fc_class_init(ObjectClass *oc, const void *data)
180a74faf35SSteven Lee {
181a74faf35SSteven Lee     MachineClass *mc = MACHINE_CLASS(oc);
182a74faf35SSteven Lee 
183a74faf35SSteven Lee     mc->alias = "ast2700fc";
184a74faf35SSteven Lee     mc->desc = "ast2700 full core support";
185a74faf35SSteven Lee     mc->init = ast2700fc_init;
186a74faf35SSteven Lee     mc->no_floppy = 1;
187a74faf35SSteven Lee     mc->no_cdrom = 1;
188a74faf35SSteven Lee     mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
189a74faf35SSteven Lee }
190a74faf35SSteven Lee 
191a74faf35SSteven Lee static const TypeInfo ast2700fc_types[] = {
192a74faf35SSteven Lee     {
193a74faf35SSteven Lee         .name           = MACHINE_TYPE_NAME("ast2700fc"),
194a74faf35SSteven Lee         .parent         = TYPE_MACHINE,
195a74faf35SSteven Lee         .class_init     = ast2700fc_class_init,
196a74faf35SSteven Lee         .instance_size  = sizeof(Ast2700FCState),
197a74faf35SSteven Lee     },
198a74faf35SSteven Lee };
199a74faf35SSteven Lee 
200a74faf35SSteven Lee DEFINE_TYPES(ast2700fc_types)
201