xref: /openbmc/qemu/hw/arm/aspeed_ast27x0-fc.c (revision d5a4ff395f9170556665d4d455ebf87663eee888)
1 /*
2  * ASPEED SoC 2700 family
3  *
4  * Copyright (C) 2025 ASPEED Technology Inc.
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  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "qemu/osdep.h"
13 #include "qemu/units.h"
14 #include "qapi/error.h"
15 #include "system/block-backend.h"
16 #include "system/system.h"
17 #include "hw/arm/aspeed.h"
18 #include "hw/boards.h"
19 #include "hw/qdev-clock.h"
20 #include "hw/arm/aspeed_soc.h"
21 #include "hw/loader.h"
22 #include "hw/arm/boot.h"
23 #include "hw/block/flash.h"
24 
25 
26 #define TYPE_AST2700A0FC MACHINE_TYPE_NAME("ast2700fc-a0")
27 OBJECT_DECLARE_SIMPLE_TYPE(Ast2700a0FCState, AST2700A0FC);
28 #define TYPE_AST2700A1FC MACHINE_TYPE_NAME("ast2700fc-a1")
29 OBJECT_DECLARE_SIMPLE_TYPE(Ast2700a1FCState, AST2700A1FC);
30 
31 static struct arm_boot_info ast2700fc_board_info = {
32     .board_id = -1, /* device-tree-only board */
33 };
34 
35 struct Ast2700a0FCState {
36     MachineState parent_obj;
37 
38     MemoryRegion ca35_memory;
39     MemoryRegion ca35_dram;
40     MemoryRegion ssp_memory;
41     MemoryRegion tsp_memory;
42 
43     Clock *ssp_sysclk;
44     Clock *tsp_sysclk;
45 
46     Aspeed27x0SoCState ca35;
47     Aspeed27x0SSPSoCState ssp;
48     Aspeed27x0TSPSoCState tsp;
49 
50     bool mmio_exec;
51 };
52 
53 struct Ast2700a1FCState {
54     MachineState parent_obj;
55 
56     MemoryRegion ca35_memory;
57     MemoryRegion ca35_dram;
58     MemoryRegion ssp_memory;
59     MemoryRegion tsp_memory;
60 
61     Clock *ssp_sysclk;
62     Clock *tsp_sysclk;
63 
64     Aspeed27x0SoCState ca35;
65     Aspeed27x0SSPSoCState ssp;
66     Aspeed27x0TSPSoCState tsp;
67 
68     bool mmio_exec;
69 };
70 
71 #define AST2700FC_BMC_RAM_SIZE (2 * GiB)
72 #define AST2700FC_CM4_DRAM_SIZE (32 * MiB)
73 
74 #define AST2700FC_HW_STRAP1 0x000000C0
75 #define AST2700FC_HW_STRAP2 0x00000003
76 #define AST2700FC_FMC_MODEL "w25q01jvq"
77 #define AST2700FC_SPI_MODEL "w25q512jv"
78 
ast2700a0fc_ca35_init(MachineState * machine)79 static void ast2700a0fc_ca35_init(MachineState *machine)
80 {
81     Ast2700a0FCState *s = AST2700A0FC(machine);
82     AspeedSoCState *soc;
83     AspeedSoCClass *sc;
84 
85     object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a0");
86     soc = ASPEED_SOC(&s->ca35);
87     sc = ASPEED_SOC_GET_CLASS(soc);
88 
89     memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
90                        UINT64_MAX);
91 
92     if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
93                                 AST2700FC_BMC_RAM_SIZE, &error_abort)) {
94         return;
95     }
96     if (!object_property_set_link(OBJECT(&s->ca35), "memory",
97                                   OBJECT(&s->ca35_memory),
98                                   &error_abort)) {
99         return;
100     };
101     if (!object_property_set_link(OBJECT(&s->ca35), "dram",
102                                   OBJECT(&s->ca35_dram), &error_abort)) {
103         return;
104     }
105     if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
106                                  AST2700FC_BMC_RAM_SIZE, &error_abort)) {
107         return;
108     }
109     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
110                                  AST2700FC_HW_STRAP1, &error_abort)) {
111         return;
112     }
113     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
114                                  AST2700FC_HW_STRAP2, &error_abort)) {
115         return;
116     }
117     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
118     if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
119         return;
120     }
121     /*
122      * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
123      */
124     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
125 
126     aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
127     aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
128 
129     ast2700fc_board_info.ram_size = machine->ram_size;
130     ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
131 
132     arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
133 }
134 
ast2700a1fc_ca35_init(MachineState * machine)135 static void ast2700a1fc_ca35_init(MachineState *machine)
136 {
137     Ast2700a1FCState *s = AST2700A1FC(machine);
138     AspeedSoCState *soc;
139     AspeedSoCClass *sc;
140 
141     object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1");
142     soc = ASPEED_SOC(&s->ca35);
143     sc = ASPEED_SOC_GET_CLASS(soc);
144 
145     memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
146                        UINT64_MAX);
147 
148     if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
149                                 AST2700FC_BMC_RAM_SIZE, &error_abort)) {
150         return;
151     }
152     if (!object_property_set_link(OBJECT(&s->ca35), "memory",
153                                   OBJECT(&s->ca35_memory),
154                                   &error_abort)) {
155         return;
156     };
157     if (!object_property_set_link(OBJECT(&s->ca35), "dram",
158                                   OBJECT(&s->ca35_dram), &error_abort)) {
159         return;
160     }
161     if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
162                                  AST2700FC_BMC_RAM_SIZE, &error_abort)) {
163         return;
164     }
165     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
166                                  AST2700FC_HW_STRAP1, &error_abort)) {
167         return;
168     }
169     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
170                                  AST2700FC_HW_STRAP2, &error_abort)) {
171         return;
172     }
173     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
174     if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
175         return;
176     }
177 
178     /*
179      * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
180      */
181     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
182 
183     aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
184     aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
185 
186     ast2700fc_board_info.ram_size = machine->ram_size;
187     ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
188 
189     arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
190 }
191 
ast2700a0fc_ssp_init(MachineState * machine)192 static void ast2700a0fc_ssp_init(MachineState *machine)
193 {
194     AspeedSoCState *soc;
195     Ast2700a0FCState *s = AST2700A0FC(machine);
196     s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
197     clock_set_hz(s->ssp_sysclk, 200000000ULL);
198 
199     object_initialize_child(OBJECT(s), "ssp", &s->ssp, "ast2700ssp-a0");
200     memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
201                        UINT64_MAX);
202 
203     qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
204     if (!object_property_set_link(OBJECT(&s->ssp), "memory",
205                                   OBJECT(&s->ssp_memory), &error_abort)) {
206         return;
207     }
208 
209     soc = ASPEED_SOC(&s->ssp);
210     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
211     if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
212         return;
213     }
214 }
215 
ast2700a1fc_ssp_init(MachineState * machine)216 static void ast2700a1fc_ssp_init(MachineState *machine)
217 {
218     AspeedSoCState *soc;
219     Ast2700a1FCState *s = AST2700A1FC(machine);
220     s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
221     clock_set_hz(s->ssp_sysclk, 200000000ULL);
222 
223     object_initialize_child(OBJECT(s), "ssp", &s->ssp, "ast2700ssp-a1");
224     memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
225                        UINT64_MAX);
226 
227     qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
228     if (!object_property_set_link(OBJECT(&s->ssp), "memory",
229                                   OBJECT(&s->ssp_memory), &error_abort)) {
230         return;
231     }
232 
233     soc = ASPEED_SOC(&s->ssp);
234     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
235     if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
236         return;
237     }
238 }
239 
ast2700a0fc_tsp_init(MachineState * machine)240 static void ast2700a0fc_tsp_init(MachineState *machine)
241 {
242     AspeedSoCState *soc;
243     Ast2700a0FCState *s = AST2700A0FC(machine);
244     s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
245     clock_set_hz(s->tsp_sysclk, 200000000ULL);
246 
247     object_initialize_child(OBJECT(s), "tsp", &s->tsp, "ast2700tsp-a0");
248     memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
249                        UINT64_MAX);
250 
251     qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
252     if (!object_property_set_link(OBJECT(&s->tsp), "memory",
253                                   OBJECT(&s->tsp_memory), &error_abort)) {
254         return;
255     }
256 
257     soc = ASPEED_SOC(&s->tsp);
258     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(2));
259     if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
260         return;
261     }
262 }
263 
ast2700a1fc_tsp_init(MachineState * machine)264 static void ast2700a1fc_tsp_init(MachineState *machine)
265 {
266     AspeedSoCState *soc;
267     Ast2700a1FCState *s = AST2700A1FC(machine);
268     s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
269     clock_set_hz(s->tsp_sysclk, 200000000ULL);
270 
271     object_initialize_child(OBJECT(s), "tsp", &s->tsp, "ast2700tsp-a1");
272     memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
273                        UINT64_MAX);
274 
275     qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
276     if (!object_property_set_link(OBJECT(&s->tsp), "memory",
277                                   OBJECT(&s->tsp_memory), &error_abort)) {
278         return;
279     }
280 
281     soc = ASPEED_SOC(&s->tsp);
282     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2));
283     if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
284         return;
285     }
286 }
287 
ast2700a0fc_init(MachineState * machine)288 static void ast2700a0fc_init(MachineState *machine)
289 {
290     ast2700a0fc_ca35_init(machine);
291     ast2700a0fc_ssp_init(machine);
292     ast2700a0fc_tsp_init(machine);
293 }
294 
ast2700a1fc_init(MachineState * machine)295 static void ast2700a1fc_init(MachineState *machine)
296 {
297     ast2700a1fc_ca35_init(machine);
298     ast2700a1fc_ssp_init(machine);
299     ast2700a1fc_tsp_init(machine);
300 }
301 
ast2700a0fc_class_init(ObjectClass * oc,void * data)302 static void ast2700a0fc_class_init(ObjectClass *oc, void *data)
303 {
304     MachineClass *mc = MACHINE_CLASS(oc);
305 
306     mc->desc = "ast2700-a0 full core support";
307     mc->init = ast2700a0fc_init;
308     mc->no_floppy = 1;
309     mc->no_cdrom = 1;
310     mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
311 }
312 
ast2700a1fc_class_init(ObjectClass * oc,void * data)313 static void ast2700a1fc_class_init(ObjectClass *oc, void *data)
314 {
315     MachineClass *mc = MACHINE_CLASS(oc);
316 
317     mc->alias = "ast2700fc";
318     mc->desc = "ast2700-a1 full core support";
319     mc->init = ast2700a1fc_init;
320     mc->no_floppy = 1;
321     mc->no_cdrom = 1;
322     mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
323 }
324 
325 static const TypeInfo ast2700fc_types[] = {
326     {
327         .name           = MACHINE_TYPE_NAME("ast2700fc-a0"),
328         .parent         = TYPE_MACHINE,
329         .class_init     = ast2700a0fc_class_init,
330         .instance_size  = sizeof(Ast2700a0FCState),
331     },
332     {
333         .name           = MACHINE_TYPE_NAME("ast2700fc-a1"),
334         .parent         = TYPE_MACHINE,
335         .class_init     = ast2700a1fc_class_init,
336         .instance_size  = sizeof(Ast2700a1FCState),
337     },
338 };
339 
340 DEFINE_TYPES(ast2700fc_types)
341