master
c 242 lines 8.24 KB
Raw
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/core/boards.h"
19 #include "hw/core/qdev-clock.h"
20 #include "hw/arm/aspeed_soc.h"
21 #include "hw/core/loader.h"
22 #include "hw/arm/boot.h"
23 #include "hw/block/flash.h"
24 #include "hw/arm/aspeed_coprocessor.h"
25 #include "hw/arm/machines-qom.h"
26
27 #define TYPE_AST2700FC MACHINE_TYPE_NAME("ast2700fc")
28 OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700FC);
29
30 struct Ast2700FCState {
31 MachineState parent_obj;
32
33 MemoryRegion ca35_memory;
34 MemoryRegion ca35_dram;
35 MemoryRegion ca35_boot_rom;
36 MemoryRegion ssp_memory;
37 MemoryRegion tsp_memory;
38
39 Clock *ssp_sysclk;
40 Clock *tsp_sysclk;
41
42 Aspeed27x0SoCState ca35;
43 Aspeed27x0CoprocessorState ssp;
44 Aspeed27x0CoprocessorState tsp;
45
46 struct arm_boot_info bootinfo;
47 };
48
49 #define AST2700FC_BMC_RAM_SIZE (2 * GiB)
50
51 /* SCU HW Strap1 */
52 #define AST2700FC_HW_STRAP1 0x00000800
53 /* SCUIO HW Strap1 */
54 #define AST2700FC_HW_STRAP2 0x00000700
55 #define AST2700FC_FMC_MODEL "w25q01jvq"
56 #define AST2700FC_SPI_MODEL "w25q512jv"
57
58 static bool ast2700fc_ca35_init(MachineState *machine, Error **errp)
59 {
60 Ast2700FCState *s = AST2700FC(machine);
61 AspeedSoCState *soc;
62 AspeedSoCClass *sc;
63 const char *bios_name = NULL;
64 BlockBackend *fmc0 = NULL;
65 DeviceState *dev = NULL;
66 uint64_t rom_size;
67
68 object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a2");
69 soc = ASPEED_SOC(&s->ca35);
70 sc = ASPEED_SOC_GET_CLASS(soc);
71
72 memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
73 UINT64_MAX);
74 memory_region_add_subregion(get_system_memory(), 0, &s->ca35_memory);
75
76 if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
77 AST2700FC_BMC_RAM_SIZE, errp)) {
78 return false;
79 }
80 object_property_set_link(OBJECT(&s->ca35), "memory",
81 OBJECT(&s->ca35_memory), &error_abort);
82 object_property_set_link(OBJECT(&s->ca35), "dram", OBJECT(&s->ca35_dram),
83 &error_abort);
84 object_property_set_int(OBJECT(&s->ca35), "ram-size",
85 AST2700FC_BMC_RAM_SIZE, &error_abort);
86
87 for (int i = 0; i < sc->macs_num; i++) {
88 if (!qemu_configure_nic_device(DEVICE(&soc->ftgmac100[i]),
89 true, NULL)) {
90 break;
91 }
92 }
93 object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
94 AST2700FC_HW_STRAP1, &error_abort);
95 object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
96 AST2700FC_HW_STRAP2, &error_abort);
97 aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART12, sc->uarts_base,
98 sc->uarts_num, serial_hd(0));
99 aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART4, sc->uarts_base,
100 sc->uarts_num, serial_hd(1));
101 aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART7, sc->uarts_base,
102 sc->uarts_num, serial_hd(2));
103 if (!qdev_realize(DEVICE(&s->ca35), NULL, errp)) {
104 return false;
105 }
106
107 /*
108 * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
109 */
110 i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
111
112 aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
113 aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
114
115 s->bootinfo.ram_size = machine->ram_size;
116 s->bootinfo.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
117 s->bootinfo.board_id = -1; /* device-tree-only board */
118
119 dev = ssi_get_cs(soc->fmc.spi, 0);
120 fmc0 = dev ? m25p80_get_blk(dev) : NULL;
121
122 if (fmc0) {
123 rom_size = memory_region_size(&soc->spi_boot);
124 aspeed_install_boot_rom(soc, fmc0, &s->ca35_boot_rom, rom_size);
125 }
126
127 /* VBOOTROM */
128 bios_name = machine->firmware ?: VBOOTROM_FILE_NAME;
129 aspeed_load_vbootrom(soc, bios_name, errp);
130
131 arm_load_kernel(ARM_CPU(first_cpu), machine, &s->bootinfo);
132
133 return true;
134 }
135
136 static bool ast2700fc_ssp_init(Ast2700FCState *s, AspeedSoCState *psp,
137 Error **errp)
138 {
139 s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
140 clock_set_hz(s->ssp_sysclk, 200000000ULL);
141
142 object_initialize_child(OBJECT(s), "ssp", &s->ssp,
143 TYPE_ASPEED27X0SSP_COPROCESSOR);
144 memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
145 UINT64_MAX);
146
147 qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
148 object_property_set_link(OBJECT(&s->ssp), "memory",
149 OBJECT(&s->ssp_memory), &error_abort);
150
151 object_property_set_link(OBJECT(&s->ssp), "uart",
152 OBJECT(&psp->uart[4]), &error_abort);
153 object_property_set_int(OBJECT(&s->ssp), "uart-dev", ASPEED_DEV_UART4,
154 &error_abort);
155 object_property_set_link(OBJECT(&s->ssp), "sram",
156 OBJECT(&psp->sram), &error_abort);
157 object_property_set_link(OBJECT(&s->ssp), "scu",
158 OBJECT(&s->ca35.scu), &error_abort);
159 object_property_set_link(OBJECT(&s->ssp), "scuio",
160 OBJECT(&psp->scuio), &error_abort);
161 object_property_set_link(OBJECT(&s->ssp), "fmc",
162 OBJECT(&psp->fmc), &error_abort);
163 if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) {
164 return false;
165 }
166
167 return true;
168 }
169
170 static bool ast2700fc_tsp_init(Ast2700FCState *s, AspeedSoCState *psp,
171 Error **errp)
172 {
173 s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
174 clock_set_hz(s->tsp_sysclk, 200000000ULL);
175
176 object_initialize_child(OBJECT(s), "tsp", &s->tsp,
177 TYPE_ASPEED27X0TSP_COPROCESSOR);
178 memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
179 UINT64_MAX);
180
181 qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
182 object_property_set_link(OBJECT(&s->tsp), "memory",
183 OBJECT(&s->tsp_memory), &error_abort);
184
185 object_property_set_link(OBJECT(&s->tsp), "uart",
186 OBJECT(&psp->uart[7]), &error_abort);
187 object_property_set_int(OBJECT(&s->tsp), "uart-dev", ASPEED_DEV_UART7,
188 &error_abort);
189 object_property_set_link(OBJECT(&s->tsp), "sram",
190 OBJECT(&psp->sram), &error_abort);
191 object_property_set_link(OBJECT(&s->tsp), "scu",
192 OBJECT(&s->ca35.scu), &error_abort);
193 object_property_set_link(OBJECT(&s->tsp), "scuio",
194 OBJECT(&psp->scuio), &error_abort);
195 object_property_set_link(OBJECT(&s->tsp), "fmc",
196 OBJECT(&psp->fmc), &error_abort);
197 if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) {
198 return false;
199 }
200
201 return true;
202 }
203
204 static void ast2700fc_init(MachineState *machine)
205 {
206 Ast2700FCState *s = AST2700FC(machine);
207 AspeedSoCState *psp;
208
209 ast2700fc_ca35_init(machine, &error_abort);
210
211 /*
212 * SSP and TSP use resources owned by the PSP SoC, such as UART,
213 * SRAM, SCU and SCUIO. Therefore the PSP SoC must be realized
214 * before the coprocessors are initialized.
215 */
216 psp = ASPEED_SOC(&s->ca35);
217 ast2700fc_ssp_init(s, psp, &error_abort);
218 ast2700fc_tsp_init(s, psp, &error_abort);
219 }
220
221 static void ast2700fc_class_init(ObjectClass *oc, const void *data)
222 {
223 MachineClass *mc = MACHINE_CLASS(oc);
224
225 mc->desc = "ast2700 full core support";
226 mc->init = ast2700fc_init;
227 mc->no_floppy = 1;
228 mc->no_cdrom = 1;
229 mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
230 }
231
232 static const TypeInfo ast2700fc_types[] = {
233 {
234 .name = MACHINE_TYPE_NAME("ast2700fc"),
235 .parent = TYPE_MACHINE,
236 .class_init = ast2700fc_class_init,
237 .instance_size = sizeof(Ast2700FCState),
238 .interfaces = aarch64_machine_interfaces,
239 },
240 };
241
242 DEFINE_TYPES(ast2700fc_types)