Revision 5493e33f hw/stellaris.c
b/hw/stellaris.c | ||
---|---|---|
8 | 8 |
*/ |
9 | 9 |
|
10 | 10 |
#include "sysbus.h" |
11 |
#include "ssi.h" |
|
11 | 12 |
#include "arm-misc.h" |
12 | 13 |
#include "primecell.h" |
13 | 14 |
#include "devices.h" |
14 | 15 |
#include "qemu-timer.h" |
15 | 16 |
#include "i2c.h" |
16 | 17 |
#include "net.h" |
17 |
#include "sd.h" |
|
18 | 18 |
#include "sysemu.h" |
19 | 19 |
#include "boards.h" |
20 | 20 |
|
... | ... | |
1196 | 1196 |
0xff commands that occur when deselecting the SD card. */ |
1197 | 1197 |
|
1198 | 1198 |
typedef struct { |
1199 |
ssi_xfer_cb xfer_cb[2]; |
|
1200 |
void *opaque[2]; |
|
1199 |
SSISlave ssidev; |
|
1201 | 1200 |
qemu_irq irq; |
1202 | 1201 |
int current_dev; |
1202 |
SSIBus *bus[2]; |
|
1203 | 1203 |
} stellaris_ssi_bus_state; |
1204 | 1204 |
|
1205 | 1205 |
static void stellaris_ssi_bus_select(void *opaque, int irq, int level) |
... | ... | |
1209 | 1209 |
s->current_dev = level; |
1210 | 1210 |
} |
1211 | 1211 |
|
1212 |
static int stellaris_ssi_bus_xfer(void *opaque, int val)
|
|
1212 |
static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
|
|
1213 | 1213 |
{ |
1214 |
stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
|
|
1214 |
stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
|
|
1215 | 1215 |
|
1216 |
return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
|
|
1216 |
return ssi_transfer(s->bus[s->current_dev], val);
|
|
1217 | 1217 |
} |
1218 | 1218 |
|
1219 | 1219 |
static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) |
... | ... | |
1235 | 1235 |
return 0; |
1236 | 1236 |
} |
1237 | 1237 |
|
1238 |
static void *stellaris_ssi_bus_init(qemu_irq *irqp, |
|
1239 |
ssi_xfer_cb cb0, void *opaque0, |
|
1240 |
ssi_xfer_cb cb1, void *opaque1) |
|
1238 |
static void stellaris_ssi_bus_init(SSISlave *dev) |
|
1241 | 1239 |
{ |
1242 |
qemu_irq *qi; |
|
1243 |
stellaris_ssi_bus_state *s; |
|
1244 |
|
|
1245 |
s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state)); |
|
1246 |
s->xfer_cb[0] = cb0; |
|
1247 |
s->opaque[0] = opaque0; |
|
1248 |
s->xfer_cb[1] = cb1; |
|
1249 |
s->opaque[1] = opaque1; |
|
1250 |
qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1); |
|
1251 |
*irqp = *qi; |
|
1240 |
stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev); |
|
1241 |
|
|
1242 |
s->bus[0] = ssi_create_bus(); |
|
1243 |
qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]); |
|
1244 |
s->bus[1] = ssi_create_bus(); |
|
1245 |
qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]); |
|
1246 |
qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1); |
|
1247 |
|
|
1252 | 1248 |
register_savevm("stellaris_ssi_bus", -1, 1, |
1253 | 1249 |
stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); |
1254 |
return s; |
|
1255 | 1250 |
} |
1256 | 1251 |
|
1257 | 1252 |
/* Board init. */ |
... | ... | |
1338 | 1333 |
} |
1339 | 1334 |
} |
1340 | 1335 |
if (board->dc2 & (1 << 4)) { |
1336 |
DeviceState *dev; |
|
1337 |
dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); |
|
1341 | 1338 |
if (board->peripherals & BP_OLED_SSI) { |
1342 |
void * oled; |
|
1343 |
void * sd; |
|
1344 |
void *ssi_bus; |
|
1345 |
int index; |
|
1339 |
DeviceState *mux; |
|
1340 |
void *bus; |
|
1346 | 1341 |
|
1347 |
oled = ssd0323_init(&gpio_out[GPIO_C][7]);
|
|
1348 |
index = drive_get_index(IF_SD, 0, 0);
|
|
1349 |
sd = ssi_sd_init(drives_table[index].bdrv);
|
|
1342 |
bus = qdev_get_child_bus(dev, "ssi");
|
|
1343 |
mux = ssi_create_slave(bus, "evb6965-ssi");
|
|
1344 |
gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
|
|
1350 | 1345 |
|
1351 |
ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0], |
|
1352 |
ssi_sd_xfer, sd, |
|
1353 |
ssd0323_xfer_ssi, oled); |
|
1346 |
bus = qdev_get_child_bus(mux, "ssi0"); |
|
1347 |
dev = ssi_create_slave(bus, "ssi-sd"); |
|
1348 |
|
|
1349 |
bus = qdev_get_child_bus(mux, "ssi1"); |
|
1350 |
dev = ssi_create_slave(bus, "ssd0323"); |
|
1351 |
gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0); |
|
1354 | 1352 |
|
1355 |
pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus); |
|
1356 | 1353 |
/* Make sure the select pin is high. */ |
1357 | 1354 |
qemu_irq_raise(gpio_out[GPIO_D][0]); |
1358 |
} else { |
|
1359 |
pl022_init(0x40008000, pic[7], NULL, NULL); |
|
1360 | 1355 |
} |
1361 | 1356 |
} |
1362 | 1357 |
if (board->dc4 & (1 << 28)) { |
... | ... | |
1413 | 1408 |
.init = lm3s6965evb_init, |
1414 | 1409 |
}; |
1415 | 1410 |
|
1411 |
static SSISlaveInfo stellaris_ssi_bus_info = { |
|
1412 |
.init = stellaris_ssi_bus_init, |
|
1413 |
.transfer = stellaris_ssi_bus_transfer |
|
1414 |
}; |
|
1415 |
|
|
1416 | 1416 |
static void stellaris_register_devices(void) |
1417 | 1417 |
{ |
1418 | 1418 |
sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), |
1419 | 1419 |
stellaris_i2c_init); |
1420 |
ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), |
|
1421 |
&stellaris_ssi_bus_info); |
|
1420 | 1422 |
} |
1421 | 1423 |
|
1422 | 1424 |
device_init(stellaris_register_devices) |
Also available in: Unified diff