]> Git Repo - qemu.git/blob - hw/arm/aspeed_soc.c
ast2400: rename the Aspeed SoC files to aspeed_soc
[qemu.git] / hw / arm / aspeed_soc.c
1 /*
2  * AST2400 SoC
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/arm/aspeed_soc.h"
19 #include "hw/char/serial.h"
20 #include "qemu/log.h"
21 #include "hw/i2c/aspeed_i2c.h"
22
23 #define AST2400_UART_5_BASE      0x00184000
24 #define AST2400_IOMEM_SIZE       0x00200000
25 #define AST2400_IOMEM_BASE       0x1E600000
26 #define AST2400_SMC_BASE         AST2400_IOMEM_BASE /* Legacy SMC */
27 #define AST2400_FMC_BASE         0X1E620000
28 #define AST2400_SPI_BASE         0X1E630000
29 #define AST2400_VIC_BASE         0x1E6C0000
30 #define AST2400_SDMC_BASE        0x1E6E0000
31 #define AST2400_SCU_BASE         0x1E6E2000
32 #define AST2400_TIMER_BASE       0x1E782000
33 #define AST2400_I2C_BASE         0x1E78A000
34
35 #define AST2400_FMC_FLASH_BASE   0x20000000
36 #define AST2400_SPI_FLASH_BASE   0x30000000
37
38 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
39 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
40
41 /*
42  * IO handlers: simply catch any reads/writes to IO addresses that aren't
43  * handled by a device mapping.
44  */
45
46 static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
47 {
48     qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
49                   __func__, offset, size);
50     return 0;
51 }
52
53 static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
54                 unsigned size)
55 {
56     qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
57                   __func__, offset, value, size);
58 }
59
60 static const MemoryRegionOps ast2400_io_ops = {
61     .read = ast2400_io_read,
62     .write = ast2400_io_write,
63     .endianness = DEVICE_LITTLE_ENDIAN,
64 };
65
66 static void ast2400_init(Object *obj)
67 {
68     AST2400State *s = AST2400(obj);
69
70     s->cpu = cpu_arm_init("arm926");
71
72     object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
73     object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
74     qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
75
76     object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
77     object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
78     qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
79
80     object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
81     object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
82     qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
83
84     object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
85     object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
86     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
87     qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
88                          AST2400_A0_SILICON_REV);
89     object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
90                               "hw-strap1", &error_abort);
91     object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
92                               "hw-strap2", &error_abort);
93
94     object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
95     object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
96     qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
97
98     object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
99     object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
100     qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
101
102     object_initialize(&s->sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
103     object_property_add_child(obj, "sdmc", OBJECT(&s->sdmc), NULL);
104     qdev_set_parent_bus(DEVICE(&s->sdmc), sysbus_get_default());
105     qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev",
106                          AST2400_A0_SILICON_REV);
107 }
108
109 static void ast2400_realize(DeviceState *dev, Error **errp)
110 {
111     int i;
112     AST2400State *s = AST2400(dev);
113     Error *err = NULL, *local_err = NULL;
114
115     /* IO space */
116     memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
117             "ast2400.io", AST2400_IOMEM_SIZE);
118     memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
119             &s->iomem, -1);
120
121     /* VIC */
122     object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
123     if (err) {
124         error_propagate(errp, err);
125         return;
126     }
127     sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
128     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
129                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
130     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
131                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
132
133     /* Timer */
134     object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
135     if (err) {
136         error_propagate(errp, err);
137         return;
138     }
139     sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
140     for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
141         qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
142         sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
143     }
144
145     /* SCU */
146     object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
147     if (err) {
148         error_propagate(errp, err);
149         return;
150     }
151     sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
152
153     /* UART - attach an 8250 to the IO space as our UART5 */
154     if (serial_hds[0]) {
155         qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
156         serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
157                        uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
158     }
159
160     /* I2C */
161     object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
162     if (err) {
163         error_propagate(errp, err);
164         return;
165     }
166     sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
167     sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
168                        qdev_get_gpio_in(DEVICE(&s->vic), 12));
169
170     /* SMC */
171     object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
172     object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
173     error_propagate(&err, local_err);
174     if (err) {
175         error_propagate(errp, err);
176         return;
177     }
178     sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
179     sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
180     sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
181                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
182
183     /* SPI */
184     object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
185     object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
186     error_propagate(&err, local_err);
187     if (err) {
188         error_propagate(errp, err);
189         return;
190     }
191     sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
192     sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
193
194     /* SDMC - SDRAM Memory Controller */
195     object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
196     if (err) {
197         error_propagate(errp, err);
198         return;
199     }
200     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, AST2400_SDMC_BASE);
201 }
202
203 static void ast2400_class_init(ObjectClass *oc, void *data)
204 {
205     DeviceClass *dc = DEVICE_CLASS(oc);
206
207     dc->realize = ast2400_realize;
208
209     /*
210      * Reason: creates an ARM CPU, thus use after free(), see
211      * arm_cpu_class_init()
212      */
213     dc->cannot_destroy_with_object_finalize_yet = true;
214 }
215
216 static const TypeInfo ast2400_type_info = {
217     .name = TYPE_AST2400,
218     .parent = TYPE_SYS_BUS_DEVICE,
219     .instance_size = sizeof(AST2400State),
220     .instance_init = ast2400_init,
221     .class_init = ast2400_class_init,
222 };
223
224 static void ast2400_register_types(void)
225 {
226     type_register_static(&ast2400_type_info);
227 }
228
229 type_init(ast2400_register_types)
This page took 0.037682 seconds and 4 git commands to generate.