xref: /qemu/hw/arm/aspeed_ast27x0-fc.c (revision 61162c6f89d1e07788c5bd8a9b7f778102f8a1eb)
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_AST2700A1FC MACHINE_TYPE_NAME("ast2700fc")
27 OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700A1FC);
28 
29 static struct arm_boot_info ast2700fc_board_info = {
30     .board_id = -1, /* device-tree-only board */
31 };
32 
33 struct Ast2700FCState {
34     MachineState parent_obj;
35 
36     MemoryRegion ca35_memory;
37     MemoryRegion ca35_dram;
38     MemoryRegion ssp_memory;
39     MemoryRegion tsp_memory;
40 
41     Clock *ssp_sysclk;
42     Clock *tsp_sysclk;
43 
44     Aspeed27x0SoCState ca35;
45     Aspeed27x0SSPSoCState ssp;
46     Aspeed27x0TSPSoCState tsp;
47 
48     bool mmio_exec;
49 };
50 
51 #define AST2700FC_BMC_RAM_SIZE (1 * GiB)
52 #define AST2700FC_CM4_DRAM_SIZE (32 * MiB)
53 
54 #define AST2700FC_HW_STRAP1 0x000000C0
55 #define AST2700FC_HW_STRAP2 0x00000003
56 #define AST2700FC_FMC_MODEL "w25q01jvq"
57 #define AST2700FC_SPI_MODEL "w25q512jv"
58 
59 static void ast2700fc_ca35_init(MachineState *machine)
60 {
61     Ast2700FCState *s = AST2700A1FC(machine);
62     AspeedSoCState *soc;
63     AspeedSoCClass *sc;
64 
65     object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1");
66     soc = ASPEED_SOC(&s->ca35);
67     sc = ASPEED_SOC_GET_CLASS(soc);
68 
69     memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
70                        UINT64_MAX);
71 
72     if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
73                                 AST2700FC_BMC_RAM_SIZE, &error_abort)) {
74         return;
75     }
76     if (!object_property_set_link(OBJECT(&s->ca35), "memory",
77                                   OBJECT(&s->ca35_memory),
78                                   &error_abort)) {
79         return;
80     };
81     if (!object_property_set_link(OBJECT(&s->ca35), "dram",
82                                   OBJECT(&s->ca35_dram), &error_abort)) {
83         return;
84     }
85     if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
86                                  AST2700FC_BMC_RAM_SIZE, &error_abort)) {
87         return;
88     }
89 
90     for (int i = 0; i < sc->macs_num; i++) {
91         if (!qemu_configure_nic_device(DEVICE(&soc->ftgmac100[i]),
92                                        true, NULL)) {
93             break;
94         }
95     }
96     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
97                                  AST2700FC_HW_STRAP1, &error_abort)) {
98         return;
99     }
100     if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
101                                  AST2700FC_HW_STRAP2, &error_abort)) {
102         return;
103     }
104     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
105     if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
106         return;
107     }
108 
109     /*
110      * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
111      */
112     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
113 
114     aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
115     aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
116 
117     ast2700fc_board_info.ram_size = machine->ram_size;
118     ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
119 
120     arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
121 }
122 
123 static void ast2700fc_ssp_init(MachineState *machine)
124 {
125     AspeedSoCState *soc;
126     Ast2700FCState *s = AST2700A1FC(machine);
127     s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
128     clock_set_hz(s->ssp_sysclk, 200000000ULL);
129 
130     object_initialize_child(OBJECT(s), "ssp", &s->ssp, TYPE_ASPEED27X0SSP_SOC);
131     memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
132                        UINT64_MAX);
133 
134     qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
135     if (!object_property_set_link(OBJECT(&s->ssp), "memory",
136                                   OBJECT(&s->ssp_memory), &error_abort)) {
137         return;
138     }
139 
140     soc = ASPEED_SOC(&s->ssp);
141     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
142     if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
143         return;
144     }
145 }
146 
147 static void ast2700fc_tsp_init(MachineState *machine)
148 {
149     AspeedSoCState *soc;
150     Ast2700FCState *s = AST2700A1FC(machine);
151     s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
152     clock_set_hz(s->tsp_sysclk, 200000000ULL);
153 
154     object_initialize_child(OBJECT(s), "tsp", &s->tsp, TYPE_ASPEED27X0TSP_SOC);
155     memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
156                        UINT64_MAX);
157 
158     qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
159     if (!object_property_set_link(OBJECT(&s->tsp), "memory",
160                                   OBJECT(&s->tsp_memory), &error_abort)) {
161         return;
162     }
163 
164     soc = ASPEED_SOC(&s->tsp);
165     aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2));
166     if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
167         return;
168     }
169 }
170 
171 static void ast2700fc_init(MachineState *machine)
172 {
173     ast2700fc_ca35_init(machine);
174     ast2700fc_ssp_init(machine);
175     ast2700fc_tsp_init(machine);
176 }
177 
178 static void ast2700fc_class_init(ObjectClass *oc, const void *data)
179 {
180     MachineClass *mc = MACHINE_CLASS(oc);
181 
182     mc->alias = "ast2700fc";
183     mc->desc = "ast2700 full core support";
184     mc->init = ast2700fc_init;
185     mc->no_floppy = 1;
186     mc->no_cdrom = 1;
187     mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
188 }
189 
190 static const TypeInfo ast2700fc_types[] = {
191     {
192         .name           = MACHINE_TYPE_NAME("ast2700fc"),
193         .parent         = TYPE_MACHINE,
194         .class_init     = ast2700fc_class_init,
195         .instance_size  = sizeof(Ast2700FCState),
196     },
197 };
198 
199 DEFINE_TYPES(ast2700fc_types)
200