]> Git Repo - qemu.git/blob - hw/arm/aspeed_soc.c
scripts: Add decodetree.py
[qemu.git] / hw / arm / aspeed_soc.c
1 /*
2  * ASPEED SoC family
3  *
4  * Andrew Jeffery <[email protected]>
5  * Jeremy Kerr <[email protected]>
6  *
7  * Copyright 2016 IBM Corp.
8  *
9  * This code is licensed under the GPL version 2 or later.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qemu-common.h"
16 #include "cpu.h"
17 #include "exec/address-spaces.h"
18 #include "hw/misc/unimp.h"
19 #include "hw/arm/aspeed_soc.h"
20 #include "hw/char/serial.h"
21 #include "qemu/log.h"
22 #include "hw/i2c/aspeed_i2c.h"
23 #include "net/net.h"
24
25 #define ASPEED_SOC_UART_5_BASE      0x00184000
26 #define ASPEED_SOC_IOMEM_SIZE       0x00200000
27 #define ASPEED_SOC_IOMEM_BASE       0x1E600000
28 #define ASPEED_SOC_FMC_BASE         0x1E620000
29 #define ASPEED_SOC_SPI_BASE         0x1E630000
30 #define ASPEED_SOC_SPI2_BASE        0x1E631000
31 #define ASPEED_SOC_VIC_BASE         0x1E6C0000
32 #define ASPEED_SOC_SDMC_BASE        0x1E6E0000
33 #define ASPEED_SOC_SCU_BASE         0x1E6E2000
34 #define ASPEED_SOC_SRAM_BASE        0x1E720000
35 #define ASPEED_SOC_TIMER_BASE       0x1E782000
36 #define ASPEED_SOC_WDT_BASE         0x1E785000
37 #define ASPEED_SOC_I2C_BASE         0x1E78A000
38 #define ASPEED_SOC_ETH1_BASE        0x1E660000
39 #define ASPEED_SOC_ETH2_BASE        0x1E680000
40
41 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
42 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
43
44 #define AST2400_SDRAM_BASE       0x40000000
45 #define AST2500_SDRAM_BASE       0x80000000
46
47 static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
48 static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
49
50 static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE,
51                                                        ASPEED_SOC_SPI2_BASE};
52 static const char *aspeed_soc_ast2500_typenames[] = {
53     "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
54
55 static const AspeedSoCInfo aspeed_socs[] = {
56     {
57         .name         = "ast2400-a0",
58         .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
59         .silicon_rev  = AST2400_A0_SILICON_REV,
60         .sdram_base   = AST2400_SDRAM_BASE,
61         .sram_size    = 0x8000,
62         .spis_num     = 1,
63         .spi_bases    = aspeed_soc_ast2400_spi_bases,
64         .fmc_typename = "aspeed.smc.fmc",
65         .spi_typename = aspeed_soc_ast2400_typenames,
66         .wdts_num     = 2,
67     }, {
68         .name         = "ast2400-a1",
69         .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
70         .silicon_rev  = AST2400_A1_SILICON_REV,
71         .sdram_base   = AST2400_SDRAM_BASE,
72         .sram_size    = 0x8000,
73         .spis_num     = 1,
74         .spi_bases    = aspeed_soc_ast2400_spi_bases,
75         .fmc_typename = "aspeed.smc.fmc",
76         .spi_typename = aspeed_soc_ast2400_typenames,
77         .wdts_num     = 2,
78     }, {
79         .name         = "ast2400",
80         .cpu_type     = ARM_CPU_TYPE_NAME("arm926"),
81         .silicon_rev  = AST2400_A0_SILICON_REV,
82         .sdram_base   = AST2400_SDRAM_BASE,
83         .sram_size    = 0x8000,
84         .spis_num     = 1,
85         .spi_bases    = aspeed_soc_ast2400_spi_bases,
86         .fmc_typename = "aspeed.smc.fmc",
87         .spi_typename = aspeed_soc_ast2400_typenames,
88         .wdts_num     = 2,
89     }, {
90         .name         = "ast2500-a1",
91         .cpu_type     = ARM_CPU_TYPE_NAME("arm1176"),
92         .silicon_rev  = AST2500_A1_SILICON_REV,
93         .sdram_base   = AST2500_SDRAM_BASE,
94         .sram_size    = 0x9000,
95         .spis_num     = 2,
96         .spi_bases    = aspeed_soc_ast2500_spi_bases,
97         .fmc_typename = "aspeed.smc.ast2500-fmc",
98         .spi_typename = aspeed_soc_ast2500_typenames,
99         .wdts_num     = 3,
100     },
101 };
102
103 static void aspeed_soc_init(Object *obj)
104 {
105     AspeedSoCState *s = ASPEED_SOC(obj);
106     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
107     int i;
108
109     object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type);
110     object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
111
112     object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
113     object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
114     qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
115
116     object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
117     object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
118     qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
119
120     object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
121     object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
122     qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
123
124     object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
125     object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
126     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
127     qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
128                          sc->info->silicon_rev);
129     object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
130                               "hw-strap1", &error_abort);
131     object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
132                               "hw-strap2", &error_abort);
133     object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
134                               "hw-prot-key", &error_abort);
135
136     object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
137     object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
138     qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
139     object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
140                               &error_abort);
141
142     for (i = 0; i < sc->info->spis_num; i++) {
143         object_initialize(&s->spi[i], sizeof(s->spi[i]),
144                           sc->info->spi_typename[i]);
145         object_property_add_child(obj, "spi[*]", OBJECT(&s->spi[i]), NULL);
146         qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
147     }
148
149     object_initialize(&s->sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
150     object_property_add_child(obj, "sdmc", OBJECT(&s->sdmc), NULL);
151     qdev_set_parent_bus(DEVICE(&s->sdmc), sysbus_get_default());
152     qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev",
153                          sc->info->silicon_rev);
154     object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
155                               "ram-size", &error_abort);
156
157     for (i = 0; i < sc->info->wdts_num; i++) {
158         object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
159         object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL);
160         qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default());
161         qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev",
162                                     sc->info->silicon_rev);
163     }
164
165     object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100);
166     object_property_add_child(obj, "ftgmac100", OBJECT(&s->ftgmac100), NULL);
167     qdev_set_parent_bus(DEVICE(&s->ftgmac100), sysbus_get_default());
168 }
169
170 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
171 {
172     int i;
173     AspeedSoCState *s = ASPEED_SOC(dev);
174     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
175     Error *err = NULL, *local_err = NULL;
176
177     /* IO space */
178     create_unimplemented_device("aspeed_soc.io",
179                                 ASPEED_SOC_IOMEM_BASE, ASPEED_SOC_IOMEM_SIZE);
180
181     /* CPU */
182     object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
183     if (err) {
184         error_propagate(errp, err);
185         return;
186     }
187
188     /* SRAM */
189     memory_region_init_ram_nomigrate(&s->sram, OBJECT(dev), "aspeed.sram",
190                            sc->info->sram_size, &err);
191     if (err) {
192         error_propagate(errp, err);
193         return;
194     }
195     vmstate_register_ram_global(&s->sram);
196     memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
197                                 &s->sram);
198
199     /* VIC */
200     object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
201     if (err) {
202         error_propagate(errp, err);
203         return;
204     }
205     sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE);
206     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
207                        qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
208     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
209                        qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
210
211     /* Timer */
212     object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
213     if (err) {
214         error_propagate(errp, err);
215         return;
216     }
217     sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, ASPEED_SOC_TIMER_BASE);
218     for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
219         qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
220         sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
221     }
222
223     /* SCU */
224     object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
225     if (err) {
226         error_propagate(errp, err);
227         return;
228     }
229     sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
230
231     /* UART - attach an 8250 to the IO space as our UART5 */
232     if (serial_hds[0]) {
233         qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
234         serial_mm_init(get_system_memory(),
235                        ASPEED_SOC_IOMEM_BASE + ASPEED_SOC_UART_5_BASE, 2,
236                        uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
237     }
238
239     /* I2C */
240     object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
241     if (err) {
242         error_propagate(errp, err);
243         return;
244     }
245     sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, ASPEED_SOC_I2C_BASE);
246     sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
247                        qdev_get_gpio_in(DEVICE(&s->vic), 12));
248
249     /* FMC, The number of CS is set at the board level */
250     object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err);
251     if (err) {
252         error_propagate(errp, err);
253         return;
254     }
255     sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
256     sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
257                     s->fmc.ctrl->flash_window_base);
258     sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
259                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
260
261     /* SPI */
262     for (i = 0; i < sc->info->spis_num; i++) {
263         object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
264         object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
265                                  &local_err);
266         error_propagate(&err, local_err);
267         if (err) {
268             error_propagate(errp, err);
269             return;
270         }
271         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, sc->info->spi_bases[i]);
272         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
273                         s->spi[i].ctrl->flash_window_base);
274     }
275
276     /* SDMC - SDRAM Memory Controller */
277     object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
278     if (err) {
279         error_propagate(errp, err);
280         return;
281     }
282     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
283
284     /* Watch dog */
285     for (i = 0; i < sc->info->wdts_num; i++) {
286         object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
287         if (err) {
288             error_propagate(errp, err);
289             return;
290         }
291         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
292                         ASPEED_SOC_WDT_BASE + i * 0x20);
293     }
294
295     /* Net */
296     qdev_set_nic_properties(DEVICE(&s->ftgmac100), &nd_table[0]);
297     object_property_set_bool(OBJECT(&s->ftgmac100), true, "aspeed", &err);
298     object_property_set_bool(OBJECT(&s->ftgmac100), true, "realized",
299                              &local_err);
300     error_propagate(&err, local_err);
301     if (err) {
302         error_propagate(errp, err);
303         return;
304     }
305     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
306     sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100), 0,
307                        qdev_get_gpio_in(DEVICE(&s->vic), 2));
308 }
309
310 static void aspeed_soc_class_init(ObjectClass *oc, void *data)
311 {
312     DeviceClass *dc = DEVICE_CLASS(oc);
313     AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
314
315     sc->info = (AspeedSoCInfo *) data;
316     dc->realize = aspeed_soc_realize;
317     /* Reason: Uses serial_hds and nd_table in realize() directly */
318     dc->user_creatable = false;
319 }
320
321 static const TypeInfo aspeed_soc_type_info = {
322     .name           = TYPE_ASPEED_SOC,
323     .parent         = TYPE_DEVICE,
324     .instance_init  = aspeed_soc_init,
325     .instance_size  = sizeof(AspeedSoCState),
326     .class_size     = sizeof(AspeedSoCClass),
327     .abstract       = true,
328 };
329
330 static void aspeed_soc_register_types(void)
331 {
332     int i;
333
334     type_register_static(&aspeed_soc_type_info);
335     for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) {
336         TypeInfo ti = {
337             .name       = aspeed_socs[i].name,
338             .parent     = TYPE_ASPEED_SOC,
339             .class_init = aspeed_soc_class_init,
340             .class_data = (void *) &aspeed_socs[i],
341         };
342         type_register(&ti);
343     }
344 }
345
346 type_init(aspeed_soc_register_types)
This page took 0.041904 seconds and 4 git commands to generate.