Revision 8a231487 hw/pxa2xx.c
b/hw/pxa2xx.c | ||
---|---|---|
13 | 13 |
#include "pc.h" |
14 | 14 |
#include "i2c.h" |
15 | 15 |
#include "ssi.h" |
16 |
#include "qemu-timer.h" |
|
17 | 16 |
#include "qemu-char.h" |
18 | 17 |
#include "blockdev.h" |
19 | 18 |
|
... | ... | |
886 | 885 |
#define RTCPICR 0x34 /* RTC Periodic Interrupt Counter register */ |
887 | 886 |
#define PIAR 0x38 /* RTC Periodic Interrupt Alarm register */ |
888 | 887 |
|
889 |
static inline void pxa2xx_rtc_int_update(PXA2xxState *s) |
|
888 |
typedef struct { |
|
889 |
SysBusDevice busdev; |
|
890 |
uint32_t rttr; |
|
891 |
uint32_t rtsr; |
|
892 |
uint32_t rtar; |
|
893 |
uint32_t rdar1; |
|
894 |
uint32_t rdar2; |
|
895 |
uint32_t ryar1; |
|
896 |
uint32_t ryar2; |
|
897 |
uint32_t swar1; |
|
898 |
uint32_t swar2; |
|
899 |
uint32_t piar; |
|
900 |
uint32_t last_rcnr; |
|
901 |
uint32_t last_rdcr; |
|
902 |
uint32_t last_rycr; |
|
903 |
uint32_t last_swcr; |
|
904 |
uint32_t last_rtcpicr; |
|
905 |
int64_t last_hz; |
|
906 |
int64_t last_sw; |
|
907 |
int64_t last_pi; |
|
908 |
QEMUTimer *rtc_hz; |
|
909 |
QEMUTimer *rtc_rdal1; |
|
910 |
QEMUTimer *rtc_rdal2; |
|
911 |
QEMUTimer *rtc_swal1; |
|
912 |
QEMUTimer *rtc_swal2; |
|
913 |
QEMUTimer *rtc_pi; |
|
914 |
qemu_irq rtc_irq; |
|
915 |
} PXA2xxRTCState; |
|
916 |
|
|
917 |
static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s) |
|
890 | 918 |
{ |
891 | 919 |
qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553)); |
892 | 920 |
} |
893 | 921 |
|
894 |
static void pxa2xx_rtc_hzupdate(PXA2xxState *s) |
|
922 |
static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
|
|
895 | 923 |
{ |
896 | 924 |
int64_t rt = qemu_get_clock(rt_clock); |
897 | 925 |
s->last_rcnr += ((rt - s->last_hz) << 15) / |
... | ... | |
901 | 929 |
s->last_hz = rt; |
902 | 930 |
} |
903 | 931 |
|
904 |
static void pxa2xx_rtc_swupdate(PXA2xxState *s) |
|
932 |
static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
|
|
905 | 933 |
{ |
906 | 934 |
int64_t rt = qemu_get_clock(rt_clock); |
907 | 935 |
if (s->rtsr & (1 << 12)) |
... | ... | |
909 | 937 |
s->last_sw = rt; |
910 | 938 |
} |
911 | 939 |
|
912 |
static void pxa2xx_rtc_piupdate(PXA2xxState *s) |
|
940 |
static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
|
|
913 | 941 |
{ |
914 | 942 |
int64_t rt = qemu_get_clock(rt_clock); |
915 | 943 |
if (s->rtsr & (1 << 15)) |
... | ... | |
917 | 945 |
s->last_pi = rt; |
918 | 946 |
} |
919 | 947 |
|
920 |
static inline void pxa2xx_rtc_alarm_update(PXA2xxState *s, |
|
948 |
static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s,
|
|
921 | 949 |
uint32_t rtsr) |
922 | 950 |
{ |
923 | 951 |
if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0))) |
... | ... | |
962 | 990 |
|
963 | 991 |
static inline void pxa2xx_rtc_hz_tick(void *opaque) |
964 | 992 |
{ |
965 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
993 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
966 | 994 |
s->rtsr |= (1 << 0); |
967 | 995 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
968 | 996 |
pxa2xx_rtc_int_update(s); |
... | ... | |
970 | 998 |
|
971 | 999 |
static inline void pxa2xx_rtc_rdal1_tick(void *opaque) |
972 | 1000 |
{ |
973 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1001 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
974 | 1002 |
s->rtsr |= (1 << 4); |
975 | 1003 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
976 | 1004 |
pxa2xx_rtc_int_update(s); |
... | ... | |
978 | 1006 |
|
979 | 1007 |
static inline void pxa2xx_rtc_rdal2_tick(void *opaque) |
980 | 1008 |
{ |
981 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1009 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
982 | 1010 |
s->rtsr |= (1 << 6); |
983 | 1011 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
984 | 1012 |
pxa2xx_rtc_int_update(s); |
... | ... | |
986 | 1014 |
|
987 | 1015 |
static inline void pxa2xx_rtc_swal1_tick(void *opaque) |
988 | 1016 |
{ |
989 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1017 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
990 | 1018 |
s->rtsr |= (1 << 8); |
991 | 1019 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
992 | 1020 |
pxa2xx_rtc_int_update(s); |
... | ... | |
994 | 1022 |
|
995 | 1023 |
static inline void pxa2xx_rtc_swal2_tick(void *opaque) |
996 | 1024 |
{ |
997 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1025 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
998 | 1026 |
s->rtsr |= (1 << 10); |
999 | 1027 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
1000 | 1028 |
pxa2xx_rtc_int_update(s); |
... | ... | |
1002 | 1030 |
|
1003 | 1031 |
static inline void pxa2xx_rtc_pi_tick(void *opaque) |
1004 | 1032 |
{ |
1005 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1033 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
1006 | 1034 |
s->rtsr |= (1 << 13); |
1007 | 1035 |
pxa2xx_rtc_piupdate(s); |
1008 | 1036 |
s->last_rtcpicr = 0; |
... | ... | |
1012 | 1040 |
|
1013 | 1041 |
static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr) |
1014 | 1042 |
{ |
1015 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1043 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
1016 | 1044 |
|
1017 | 1045 |
switch (addr) { |
1018 | 1046 |
case RTTR: |
... | ... | |
1058 | 1086 |
static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr, |
1059 | 1087 |
uint32_t value) |
1060 | 1088 |
{ |
1061 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1089 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
1062 | 1090 |
|
1063 | 1091 |
switch (addr) { |
1064 | 1092 |
case RTTR: |
... | ... | |
1170 | 1198 |
pxa2xx_rtc_write, |
1171 | 1199 |
}; |
1172 | 1200 |
|
1173 |
static void pxa2xx_rtc_init(PXA2xxState *s)
|
|
1201 |
static int pxa2xx_rtc_init(SysBusDevice *dev)
|
|
1174 | 1202 |
{ |
1203 |
PXA2xxRTCState *s = FROM_SYSBUS(PXA2xxRTCState, dev); |
|
1175 | 1204 |
struct tm tm; |
1176 | 1205 |
int wom; |
1206 |
int iomemtype; |
|
1177 | 1207 |
|
1178 | 1208 |
s->rttr = 0x7fff; |
1179 | 1209 |
s->rtsr = 0; |
... | ... | |
1198 | 1228 |
s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s); |
1199 | 1229 |
s->rtc_pi = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick, s); |
1200 | 1230 |
|
1201 |
s->rtc_irq = qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM); |
|
1231 |
sysbus_init_irq(dev, &s->rtc_irq); |
|
1232 |
|
|
1233 |
iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn, |
|
1234 |
pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); |
|
1235 |
sysbus_init_mmio(dev, 0x10000, iomemtype); |
|
1236 |
|
|
1237 |
return 0; |
|
1202 | 1238 |
} |
1203 | 1239 |
|
1204 |
static void pxa2xx_rtc_save(QEMUFile *f, void *opaque)
|
|
1240 |
static void pxa2xx_rtc_pre_save(void *opaque)
|
|
1205 | 1241 |
{ |
1206 |
PXA2xxState *s = (PXA2xxState *) opaque;
|
|
1242 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
|
|
1207 | 1243 |
|
1208 | 1244 |
pxa2xx_rtc_hzupdate(s); |
1209 | 1245 |
pxa2xx_rtc_piupdate(s); |
1210 | 1246 |
pxa2xx_rtc_swupdate(s); |
1247 |
} |
|
1211 | 1248 |
|
1212 |
qemu_put_be32s(f, &s->rttr); |
|
1213 |
qemu_put_be32s(f, &s->rtsr); |
|
1214 |
qemu_put_be32s(f, &s->rtar); |
|
1215 |
qemu_put_be32s(f, &s->rdar1); |
|
1216 |
qemu_put_be32s(f, &s->rdar2); |
|
1217 |
qemu_put_be32s(f, &s->ryar1); |
|
1218 |
qemu_put_be32s(f, &s->ryar2); |
|
1219 |
qemu_put_be32s(f, &s->swar1); |
|
1220 |
qemu_put_be32s(f, &s->swar2); |
|
1221 |
qemu_put_be32s(f, &s->piar); |
|
1222 |
qemu_put_be32s(f, &s->last_rcnr); |
|
1223 |
qemu_put_be32s(f, &s->last_rdcr); |
|
1224 |
qemu_put_be32s(f, &s->last_rycr); |
|
1225 |
qemu_put_be32s(f, &s->last_swcr); |
|
1226 |
qemu_put_be32s(f, &s->last_rtcpicr); |
|
1227 |
qemu_put_sbe64s(f, &s->last_hz); |
|
1228 |
qemu_put_sbe64s(f, &s->last_sw); |
|
1229 |
qemu_put_sbe64s(f, &s->last_pi); |
|
1230 |
} |
|
1231 |
|
|
1232 |
static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id) |
|
1249 |
static int pxa2xx_rtc_post_load(void *opaque, int version_id) |
|
1233 | 1250 |
{ |
1234 |
PXA2xxState *s = (PXA2xxState *) opaque; |
|
1235 |
|
|
1236 |
qemu_get_be32s(f, &s->rttr); |
|
1237 |
qemu_get_be32s(f, &s->rtsr); |
|
1238 |
qemu_get_be32s(f, &s->rtar); |
|
1239 |
qemu_get_be32s(f, &s->rdar1); |
|
1240 |
qemu_get_be32s(f, &s->rdar2); |
|
1241 |
qemu_get_be32s(f, &s->ryar1); |
|
1242 |
qemu_get_be32s(f, &s->ryar2); |
|
1243 |
qemu_get_be32s(f, &s->swar1); |
|
1244 |
qemu_get_be32s(f, &s->swar2); |
|
1245 |
qemu_get_be32s(f, &s->piar); |
|
1246 |
qemu_get_be32s(f, &s->last_rcnr); |
|
1247 |
qemu_get_be32s(f, &s->last_rdcr); |
|
1248 |
qemu_get_be32s(f, &s->last_rycr); |
|
1249 |
qemu_get_be32s(f, &s->last_swcr); |
|
1250 |
qemu_get_be32s(f, &s->last_rtcpicr); |
|
1251 |
qemu_get_sbe64s(f, &s->last_hz); |
|
1252 |
qemu_get_sbe64s(f, &s->last_sw); |
|
1253 |
qemu_get_sbe64s(f, &s->last_pi); |
|
1251 |
PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; |
|
1254 | 1252 |
|
1255 | 1253 |
pxa2xx_rtc_alarm_update(s, s->rtsr); |
1256 | 1254 |
|
1257 | 1255 |
return 0; |
1258 | 1256 |
} |
1259 | 1257 |
|
1258 |
static const VMStateDescription vmstate_pxa2xx_rtc_regs = { |
|
1259 |
.name = "pxa2xx_rtc", |
|
1260 |
.version_id = 0, |
|
1261 |
.minimum_version_id = 0, |
|
1262 |
.minimum_version_id_old = 0, |
|
1263 |
.pre_save = pxa2xx_rtc_pre_save, |
|
1264 |
.post_load = pxa2xx_rtc_post_load, |
|
1265 |
.fields = (VMStateField[]) { |
|
1266 |
VMSTATE_UINT32(rttr, PXA2xxRTCState), |
|
1267 |
VMSTATE_UINT32(rtsr, PXA2xxRTCState), |
|
1268 |
VMSTATE_UINT32(rtar, PXA2xxRTCState), |
|
1269 |
VMSTATE_UINT32(rdar1, PXA2xxRTCState), |
|
1270 |
VMSTATE_UINT32(rdar2, PXA2xxRTCState), |
|
1271 |
VMSTATE_UINT32(ryar1, PXA2xxRTCState), |
|
1272 |
VMSTATE_UINT32(ryar2, PXA2xxRTCState), |
|
1273 |
VMSTATE_UINT32(swar1, PXA2xxRTCState), |
|
1274 |
VMSTATE_UINT32(swar2, PXA2xxRTCState), |
|
1275 |
VMSTATE_UINT32(piar, PXA2xxRTCState), |
|
1276 |
VMSTATE_UINT32(last_rcnr, PXA2xxRTCState), |
|
1277 |
VMSTATE_UINT32(last_rdcr, PXA2xxRTCState), |
|
1278 |
VMSTATE_UINT32(last_rycr, PXA2xxRTCState), |
|
1279 |
VMSTATE_UINT32(last_swcr, PXA2xxRTCState), |
|
1280 |
VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState), |
|
1281 |
VMSTATE_INT64(last_hz, PXA2xxRTCState), |
|
1282 |
VMSTATE_INT64(last_sw, PXA2xxRTCState), |
|
1283 |
VMSTATE_INT64(last_pi, PXA2xxRTCState), |
|
1284 |
VMSTATE_END_OF_LIST(), |
|
1285 |
}, |
|
1286 |
}; |
|
1287 |
|
|
1288 |
static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = { |
|
1289 |
.init = pxa2xx_rtc_init, |
|
1290 |
.qdev.name = "pxa2xx_rtc", |
|
1291 |
.qdev.desc = "PXA2xx RTC Controller", |
|
1292 |
.qdev.size = sizeof(PXA2xxRTCState), |
|
1293 |
.qdev.vmsd = &vmstate_pxa2xx_rtc_regs, |
|
1294 |
}; |
|
1295 |
|
|
1260 | 1296 |
/* I2C Interface */ |
1261 | 1297 |
typedef struct { |
1262 | 1298 |
i2c_slave i2c; |
... | ... | |
2188 | 2224 |
s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000); |
2189 | 2225 |
s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000); |
2190 | 2226 |
|
2191 |
s->rtc_base = 0x40900000; |
|
2192 |
iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn, |
|
2193 |
pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); |
|
2194 |
cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype); |
|
2195 |
pxa2xx_rtc_init(s); |
|
2196 |
register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, |
|
2197 |
pxa2xx_rtc_load, s); |
|
2227 |
sysbus_create_simple("pxa2xx_rtc", 0x40900000, |
|
2228 |
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); |
|
2198 | 2229 |
|
2199 | 2230 |
s->i2c[0] = pxa2xx_i2c_init(0x40301600, |
2200 | 2231 |
qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); |
... | ... | |
2329 | 2360 |
s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000); |
2330 | 2361 |
s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000); |
2331 | 2362 |
|
2332 |
s->rtc_base = 0x40900000; |
|
2333 |
iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn, |
|
2334 |
pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); |
|
2335 |
cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype); |
|
2336 |
pxa2xx_rtc_init(s); |
|
2337 |
register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, |
|
2338 |
pxa2xx_rtc_load, s); |
|
2363 |
sysbus_create_simple("pxa2xx_rtc", 0x40900000, |
|
2364 |
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); |
|
2339 | 2365 |
|
2340 | 2366 |
s->i2c[0] = pxa2xx_i2c_init(0x40301600, |
2341 | 2367 |
qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); |
... | ... | |
2358 | 2384 |
i2c_register_slave(&pxa2xx_i2c_slave_info); |
2359 | 2385 |
sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init); |
2360 | 2386 |
sysbus_register_withprop(&pxa2xx_i2c_info); |
2387 |
sysbus_register_withprop(&pxa2xx_rtc_sysbus_info); |
|
2361 | 2388 |
} |
2362 | 2389 |
|
2363 | 2390 |
device_init(pxa2xx_register_devices) |
Also available in: Unified diff