Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 1 | /* |
| 2 | * PXA270-based Zipit Z2 device |
| 3 | * |
| 4 | * Copyright (c) 2011 by Vasily Khoruzhick <anarsoul@gmail.com> |
| 5 | * |
| 6 | * Code is based on mainstone platform. |
| 7 | * |
| 8 | * This code is licensed under the GNU GPL v2. |
Paolo Bonzini | 6b620ca | 2012-01-13 17:44:23 +0100 | [diff] [blame] | 9 | * |
| 10 | * Contributions after 2012-01-13 are licensed under the terms of the |
| 11 | * GNU GPL, version 2 or (at your option) any later version. |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 12 | */ |
| 13 | |
Peter Maydell | 12b1672 | 2015-12-07 16:23:45 +0000 | [diff] [blame] | 14 | #include "qemu/osdep.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 15 | #include "hw/hw.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 16 | #include "hw/arm/pxa.h" |
Peter Maydell | bd2be15 | 2013-04-09 15:26:55 +0100 | [diff] [blame] | 17 | #include "hw/arm/arm.h" |
| 18 | #include "hw/devices.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 19 | #include "hw/i2c/i2c.h" |
Alistair Francis | 8fd0671 | 2016-01-21 14:15:03 +0000 | [diff] [blame] | 20 | #include "hw/ssi/ssi.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 21 | #include "hw/boards.h" |
Paolo Bonzini | 9c17d61 | 2012-12-17 18:20:04 +0100 | [diff] [blame] | 22 | #include "sysemu/sysemu.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 23 | #include "hw/block/flash.h" |
Markus Armbruster | fa1d36d | 2014-10-07 13:59:13 +0200 | [diff] [blame] | 24 | #include "sysemu/block-backend.h" |
Paolo Bonzini | 28ecbae | 2012-11-28 12:06:30 +0100 | [diff] [blame] | 25 | #include "ui/console.h" |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 26 | #include "audio/audio.h" |
Paolo Bonzini | 022c62c | 2012-12-17 18:19:49 +0100 | [diff] [blame] | 27 | #include "exec/address-spaces.h" |
Andreas Färber | e25ac5f | 2013-07-29 17:15:55 +0200 | [diff] [blame] | 28 | #include "sysemu/qtest.h" |
Igor Mammedov | ba1ba5c | 2017-09-13 18:04:57 +0200 | [diff] [blame] | 29 | #include "cpu.h" |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 30 | |
| 31 | #ifdef DEBUG_Z2 |
| 32 | #define DPRINTF(fmt, ...) \ |
| 33 | printf(fmt, ## __VA_ARGS__) |
| 34 | #else |
| 35 | #define DPRINTF(fmt, ...) |
| 36 | #endif |
| 37 | |
Stefan Weil | 52975c3 | 2013-12-22 15:22:57 +0100 | [diff] [blame] | 38 | static const struct keymap map[0x100] = { |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 39 | [0 ... 0xff] = { -1, -1 }, |
| 40 | [0x3b] = {0, 0}, /* Option = F1 */ |
| 41 | [0xc8] = {0, 1}, /* Up */ |
| 42 | [0xd0] = {0, 2}, /* Down */ |
| 43 | [0xcb] = {0, 3}, /* Left */ |
| 44 | [0xcd] = {0, 4}, /* Right */ |
| 45 | [0xcf] = {0, 5}, /* End */ |
| 46 | [0x0d] = {0, 6}, /* KPPLUS */ |
| 47 | [0xc7] = {1, 0}, /* Home */ |
| 48 | [0x10] = {1, 1}, /* Q */ |
| 49 | [0x17] = {1, 2}, /* I */ |
| 50 | [0x22] = {1, 3}, /* G */ |
| 51 | [0x2d] = {1, 4}, /* X */ |
| 52 | [0x1c] = {1, 5}, /* Enter */ |
| 53 | [0x0c] = {1, 6}, /* KPMINUS */ |
| 54 | [0xc9] = {2, 0}, /* PageUp */ |
| 55 | [0x11] = {2, 1}, /* W */ |
| 56 | [0x18] = {2, 2}, /* O */ |
| 57 | [0x23] = {2, 3}, /* H */ |
| 58 | [0x2e] = {2, 4}, /* C */ |
| 59 | [0x38] = {2, 5}, /* LeftAlt */ |
| 60 | [0xd1] = {3, 0}, /* PageDown */ |
| 61 | [0x12] = {3, 1}, /* E */ |
| 62 | [0x19] = {3, 2}, /* P */ |
| 63 | [0x24] = {3, 3}, /* J */ |
| 64 | [0x2f] = {3, 4}, /* V */ |
| 65 | [0x2a] = {3, 5}, /* LeftShift */ |
| 66 | [0x01] = {4, 0}, /* Esc */ |
| 67 | [0x13] = {4, 1}, /* R */ |
| 68 | [0x1e] = {4, 2}, /* A */ |
| 69 | [0x25] = {4, 3}, /* K */ |
| 70 | [0x30] = {4, 4}, /* B */ |
| 71 | [0x1d] = {4, 5}, /* LeftCtrl */ |
| 72 | [0x0f] = {5, 0}, /* Tab */ |
| 73 | [0x14] = {5, 1}, /* T */ |
| 74 | [0x1f] = {5, 2}, /* S */ |
| 75 | [0x26] = {5, 3}, /* L */ |
| 76 | [0x31] = {5, 4}, /* N */ |
| 77 | [0x39] = {5, 5}, /* Space */ |
| 78 | [0x3c] = {6, 0}, /* Stop = F2 */ |
| 79 | [0x15] = {6, 1}, /* Y */ |
| 80 | [0x20] = {6, 2}, /* D */ |
| 81 | [0x0e] = {6, 3}, /* Backspace */ |
| 82 | [0x32] = {6, 4}, /* M */ |
| 83 | [0x33] = {6, 5}, /* Comma */ |
| 84 | [0x3d] = {7, 0}, /* Play = F3 */ |
| 85 | [0x16] = {7, 1}, /* U */ |
| 86 | [0x21] = {7, 2}, /* F */ |
| 87 | [0x2c] = {7, 3}, /* Z */ |
| 88 | [0x27] = {7, 4}, /* Semicolon */ |
| 89 | [0x34] = {7, 5}, /* Dot */ |
| 90 | }; |
| 91 | |
| 92 | #define Z2_RAM_SIZE 0x02000000 |
| 93 | #define Z2_FLASH_BASE 0x00000000 |
| 94 | #define Z2_FLASH_SIZE 0x00800000 |
| 95 | |
| 96 | static struct arm_boot_info z2_binfo = { |
| 97 | .loader_start = PXA2XX_SDRAM_BASE, |
| 98 | .ram_size = Z2_RAM_SIZE, |
| 99 | }; |
| 100 | |
| 101 | #define Z2_GPIO_SD_DETECT 96 |
| 102 | #define Z2_GPIO_AC_IN 0 |
| 103 | #define Z2_GPIO_KEY_ON 1 |
| 104 | #define Z2_GPIO_LCD_CS 88 |
| 105 | |
| 106 | typedef struct { |
| 107 | SSISlave ssidev; |
| 108 | int32_t selected; |
| 109 | int32_t enabled; |
| 110 | uint8_t buf[3]; |
| 111 | uint32_t cur_reg; |
| 112 | int pos; |
| 113 | } ZipitLCD; |
| 114 | |
| 115 | static uint32_t zipit_lcd_transfer(SSISlave *dev, uint32_t value) |
| 116 | { |
| 117 | ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev); |
| 118 | uint16_t val; |
| 119 | if (z->selected) { |
| 120 | z->buf[z->pos] = value & 0xff; |
| 121 | z->pos++; |
| 122 | } |
| 123 | if (z->pos == 3) { |
| 124 | switch (z->buf[0]) { |
| 125 | case 0x74: |
| 126 | DPRINTF("%s: reg: 0x%.2x\n", __func__, z->buf[2]); |
| 127 | z->cur_reg = z->buf[2]; |
| 128 | break; |
| 129 | case 0x76: |
| 130 | val = z->buf[1] << 8 | z->buf[2]; |
| 131 | DPRINTF("%s: value: 0x%.4x\n", __func__, val); |
| 132 | if (z->cur_reg == 0x22 && val == 0x0000) { |
| 133 | z->enabled = 1; |
| 134 | printf("%s: LCD enabled\n", __func__); |
| 135 | } else if (z->cur_reg == 0x10 && val == 0x0000) { |
| 136 | z->enabled = 0; |
| 137 | printf("%s: LCD disabled\n", __func__); |
| 138 | } |
| 139 | break; |
| 140 | default: |
| 141 | DPRINTF("%s: unknown command!\n", __func__); |
| 142 | break; |
| 143 | } |
| 144 | z->pos = 0; |
| 145 | } |
| 146 | return 0; |
| 147 | } |
| 148 | |
| 149 | static void z2_lcd_cs(void *opaque, int line, int level) |
| 150 | { |
| 151 | ZipitLCD *z2_lcd = opaque; |
| 152 | z2_lcd->selected = !level; |
| 153 | } |
| 154 | |
Cédric Le Goater | 7673bb4 | 2016-07-04 13:06:37 +0100 | [diff] [blame] | 155 | static void zipit_lcd_realize(SSISlave *dev, Error **errp) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 156 | { |
| 157 | ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev); |
| 158 | z->selected = 0; |
| 159 | z->enabled = 0; |
| 160 | z->pos = 0; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | static VMStateDescription vmstate_zipit_lcd_state = { |
| 164 | .name = "zipit-lcd", |
Peter A. G. Crosthwaite | 6653095 | 2012-07-24 12:23:22 +1000 | [diff] [blame] | 165 | .version_id = 2, |
| 166 | .minimum_version_id = 2, |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 167 | .fields = (VMStateField[]) { |
Peter A. G. Crosthwaite | 6653095 | 2012-07-24 12:23:22 +1000 | [diff] [blame] | 168 | VMSTATE_SSI_SLAVE(ssidev, ZipitLCD), |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 169 | VMSTATE_INT32(selected, ZipitLCD), |
| 170 | VMSTATE_INT32(enabled, ZipitLCD), |
| 171 | VMSTATE_BUFFER(buf, ZipitLCD), |
| 172 | VMSTATE_UINT32(cur_reg, ZipitLCD), |
| 173 | VMSTATE_INT32(pos, ZipitLCD), |
| 174 | VMSTATE_END_OF_LIST(), |
| 175 | } |
| 176 | }; |
| 177 | |
Anthony Liguori | cd6c4cf | 2011-12-16 13:36:39 -0600 | [diff] [blame] | 178 | static void zipit_lcd_class_init(ObjectClass *klass, void *data) |
| 179 | { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 180 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | cd6c4cf | 2011-12-16 13:36:39 -0600 | [diff] [blame] | 181 | SSISlaveClass *k = SSI_SLAVE_CLASS(klass); |
| 182 | |
Cédric Le Goater | 7673bb4 | 2016-07-04 13:06:37 +0100 | [diff] [blame] | 183 | k->realize = zipit_lcd_realize; |
Anthony Liguori | cd6c4cf | 2011-12-16 13:36:39 -0600 | [diff] [blame] | 184 | k->transfer = zipit_lcd_transfer; |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 185 | dc->vmsd = &vmstate_zipit_lcd_state; |
Anthony Liguori | cd6c4cf | 2011-12-16 13:36:39 -0600 | [diff] [blame] | 186 | } |
| 187 | |
Andreas Färber | 8c43a6f | 2013-01-10 16:19:07 +0100 | [diff] [blame] | 188 | static const TypeInfo zipit_lcd_info = { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 189 | .name = "zipit-lcd", |
| 190 | .parent = TYPE_SSI_SLAVE, |
| 191 | .instance_size = sizeof(ZipitLCD), |
| 192 | .class_init = zipit_lcd_class_init, |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 193 | }; |
| 194 | |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 195 | #define TYPE_AER915 "aer915" |
| 196 | #define AER915(obj) OBJECT_CHECK(AER915State, (obj), TYPE_AER915) |
| 197 | |
| 198 | typedef struct AER915State { |
| 199 | I2CSlave parent_obj; |
| 200 | |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 201 | int len; |
| 202 | uint8_t buf[3]; |
| 203 | } AER915State; |
| 204 | |
Anthony Liguori | 9e07bdf | 2011-12-04 20:28:27 -0600 | [diff] [blame] | 205 | static int aer915_send(I2CSlave *i2c, uint8_t data) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 206 | { |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 207 | AER915State *s = AER915(i2c); |
| 208 | |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 209 | s->buf[s->len] = data; |
| 210 | if (s->len++ > 2) { |
| 211 | DPRINTF("%s: message too long (%i bytes)\n", |
| 212 | __func__, s->len); |
| 213 | return 1; |
| 214 | } |
| 215 | |
| 216 | if (s->len == 2) { |
| 217 | DPRINTF("%s: reg %d value 0x%02x\n", __func__, |
| 218 | s->buf[0], s->buf[1]); |
| 219 | } |
| 220 | |
| 221 | return 0; |
| 222 | } |
| 223 | |
Corey Minyard | d307c28 | 2017-01-09 11:40:20 +0000 | [diff] [blame] | 224 | static int aer915_event(I2CSlave *i2c, enum i2c_event event) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 225 | { |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 226 | AER915State *s = AER915(i2c); |
| 227 | |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 228 | switch (event) { |
| 229 | case I2C_START_SEND: |
| 230 | s->len = 0; |
| 231 | break; |
| 232 | case I2C_START_RECV: |
| 233 | if (s->len != 1) { |
| 234 | DPRINTF("%s: short message!?\n", __func__); |
| 235 | } |
| 236 | break; |
| 237 | case I2C_FINISH: |
| 238 | break; |
| 239 | default: |
| 240 | break; |
| 241 | } |
Corey Minyard | d307c28 | 2017-01-09 11:40:20 +0000 | [diff] [blame] | 242 | |
| 243 | return 0; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 244 | } |
| 245 | |
Anthony Liguori | 9e07bdf | 2011-12-04 20:28:27 -0600 | [diff] [blame] | 246 | static int aer915_recv(I2CSlave *slave) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 247 | { |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 248 | AER915State *s = AER915(slave); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 249 | int retval = 0x00; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 250 | |
| 251 | switch (s->buf[0]) { |
| 252 | /* Return hardcoded battery voltage, |
| 253 | * 0xf0 means ~4.1V |
| 254 | */ |
| 255 | case 0x02: |
| 256 | retval = 0xf0; |
| 257 | break; |
| 258 | /* Return 0x00 for other regs, |
| 259 | * we don't know what they are for, |
| 260 | * anyway they return 0x00 on real hardware. |
| 261 | */ |
| 262 | default: |
| 263 | break; |
| 264 | } |
| 265 | |
| 266 | return retval; |
| 267 | } |
| 268 | |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 269 | static VMStateDescription vmstate_aer915_state = { |
| 270 | .name = "aer915", |
| 271 | .version_id = 1, |
| 272 | .minimum_version_id = 1, |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 273 | .fields = (VMStateField[]) { |
| 274 | VMSTATE_INT32(len, AER915State), |
| 275 | VMSTATE_BUFFER(buf, AER915State), |
| 276 | VMSTATE_END_OF_LIST(), |
| 277 | } |
| 278 | }; |
| 279 | |
Anthony Liguori | b5ea932 | 2011-12-04 20:39:20 -0600 | [diff] [blame] | 280 | static void aer915_class_init(ObjectClass *klass, void *data) |
| 281 | { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 282 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | b5ea932 | 2011-12-04 20:39:20 -0600 | [diff] [blame] | 283 | I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); |
| 284 | |
Anthony Liguori | b5ea932 | 2011-12-04 20:39:20 -0600 | [diff] [blame] | 285 | k->event = aer915_event; |
| 286 | k->recv = aer915_recv; |
| 287 | k->send = aer915_send; |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 288 | dc->vmsd = &vmstate_aer915_state; |
Anthony Liguori | b5ea932 | 2011-12-04 20:39:20 -0600 | [diff] [blame] | 289 | } |
| 290 | |
Andreas Färber | 8c43a6f | 2013-01-10 16:19:07 +0100 | [diff] [blame] | 291 | static const TypeInfo aer915_info = { |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 292 | .name = TYPE_AER915, |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 293 | .parent = TYPE_I2C_SLAVE, |
| 294 | .instance_size = sizeof(AER915State), |
| 295 | .class_init = aer915_class_init, |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 296 | }; |
| 297 | |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 298 | static void z2_init(MachineState *machine) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 299 | { |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 300 | const char *kernel_filename = machine->kernel_filename; |
| 301 | const char *kernel_cmdline = machine->kernel_cmdline; |
| 302 | const char *initrd_filename = machine->initrd_filename; |
Richard Henderson | a6dc4c2 | 2011-08-11 16:07:19 -0700 | [diff] [blame] | 303 | MemoryRegion *address_space_mem = get_system_memory(); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 304 | uint32_t sector_len = 0x10000; |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 305 | PXA2xxState *mpu; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 306 | DriveInfo *dinfo; |
Anthony Liguori | 01e0451 | 2011-08-25 14:39:18 -0500 | [diff] [blame] | 307 | int be; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 308 | void *z2_lcd; |
Andreas Färber | a5c8285 | 2013-08-03 00:18:51 +0200 | [diff] [blame] | 309 | I2CBus *bus; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 310 | DeviceState *wm; |
| 311 | |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 312 | /* Setup CPU & memory */ |
Igor Mammedov | ba1ba5c | 2017-09-13 18:04:57 +0200 | [diff] [blame] | 313 | mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 314 | |
| 315 | #ifdef TARGET_WORDS_BIGENDIAN |
Anthony Liguori | 01e0451 | 2011-08-25 14:39:18 -0500 | [diff] [blame] | 316 | be = 1; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 317 | #else |
Anthony Liguori | 01e0451 | 2011-08-25 14:39:18 -0500 | [diff] [blame] | 318 | be = 0; |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 319 | #endif |
| 320 | dinfo = drive_get(IF_PFLASH, 0, 0); |
Andreas Färber | e25ac5f | 2013-07-29 17:15:55 +0200 | [diff] [blame] | 321 | if (!dinfo && !qtest_enabled()) { |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 322 | fprintf(stderr, "Flash image must be given with the " |
| 323 | "'pflash' parameter\n"); |
| 324 | exit(1); |
| 325 | } |
| 326 | |
Anthony Liguori | 01e0451 | 2011-08-25 14:39:18 -0500 | [diff] [blame] | 327 | if (!pflash_cfi01_register(Z2_FLASH_BASE, |
Avi Kivity | cfe5f01 | 2011-08-04 15:55:30 +0300 | [diff] [blame] | 328 | NULL, "z2.flash0", Z2_FLASH_SIZE, |
Markus Armbruster | 4be7463 | 2014-10-07 13:59:18 +0200 | [diff] [blame] | 329 | dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, |
Markus Armbruster | fa1d36d | 2014-10-07 13:59:13 +0200 | [diff] [blame] | 330 | sector_len, Z2_FLASH_SIZE / sector_len, |
| 331 | 4, 0, 0, 0, 0, be)) { |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 332 | fprintf(stderr, "qemu: Error registering flash memory.\n"); |
| 333 | exit(1); |
| 334 | } |
| 335 | |
| 336 | /* setup keypad */ |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 337 | pxa27x_register_keypad(mpu->kp, map, 0x100); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 338 | |
| 339 | /* MMC/SD host */ |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 340 | pxa2xx_mmci_handlers(mpu->mmc, |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 341 | NULL, |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 342 | qdev_get_gpio_in(mpu->gpio, Z2_GPIO_SD_DETECT)); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 343 | |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 344 | type_register_static(&zipit_lcd_info); |
| 345 | type_register_static(&aer915_info); |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 346 | z2_lcd = ssi_create_slave(mpu->ssp[1], "zipit-lcd"); |
| 347 | bus = pxa2xx_i2c_bus(mpu->i2c[0]); |
Andreas Färber | a5f96db | 2013-12-19 21:55:44 +0100 | [diff] [blame] | 348 | i2c_create_slave(bus, TYPE_AER915, 0x55); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 349 | wm = i2c_create_slave(bus, "wm8750", 0x1b); |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 350 | mpu->i2s->opaque = wm; |
| 351 | mpu->i2s->codec_out = wm8750_dac_dat; |
| 352 | mpu->i2s->codec_in = wm8750_adc_dat; |
| 353 | wm8750_data_req_set(wm, mpu->i2s->data_req, mpu->i2s); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 354 | |
Andreas Färber | 5c6f4f1 | 2012-05-14 01:25:55 +0200 | [diff] [blame] | 355 | qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS, |
Andreas Färber | f3c7d03 | 2014-06-18 00:55:18 -0700 | [diff] [blame] | 356 | qemu_allocate_irq(z2_lcd_cs, z2_lcd, 0)); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 357 | |
Peter Maydell | dacecf5 | 2013-10-25 15:44:38 +0100 | [diff] [blame] | 358 | z2_binfo.kernel_filename = kernel_filename; |
| 359 | z2_binfo.kernel_cmdline = kernel_cmdline; |
| 360 | z2_binfo.initrd_filename = initrd_filename; |
| 361 | z2_binfo.board_id = 0x6dd; |
| 362 | arm_load_kernel(mpu->cpu, &z2_binfo); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 363 | } |
| 364 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 365 | static void z2_machine_init(MachineClass *mc) |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 366 | { |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 367 | mc->desc = "Zipit Z2 (PXA27x)"; |
| 368 | mc->init = z2_init; |
Peter Maydell | 4672cbd | 2017-09-07 13:54:54 +0100 | [diff] [blame] | 369 | mc->ignore_memory_transaction_failures = true; |
Igor Mammedov | ba1ba5c | 2017-09-13 18:04:57 +0200 | [diff] [blame] | 370 | mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5"); |
Vasily Khoruzhick | 3bf1120 | 2011-07-06 16:52:49 +0300 | [diff] [blame] | 371 | } |
| 372 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 373 | DEFINE_MACHINE("z2", z2_machine_init) |