2 * TomTom GO 730 with Samsung S3C2443X emulation.
4 * Copyright (c) 2010, 2013 Stefan Weil
6 * Code based on hw/musicpal.c
7 * Copyright (c) 2008 Jan Kiszka
9 * This code is licensed under the GNU GPL v2 or later.
12 * http://www.opentom.org/TomTom_GO_730
13 * ARM 920T Technical Reference Manual
16 #include "qemu/osdep.h"
17 #include "hw/sysbus.h"
18 #include "hw/arm/arm.h"
19 #include "hw/devices.h"
20 #include "hw/boards.h"
21 #include "hw/i2c/i2c.h"
22 #include "hw/i386/pc.h"
23 #include "hw/ptimer.h" /* ptimer_state */
24 #include "exec/address-spaces.h" /* get_system_memory */
26 #include "sysemu/sysemu.h"
27 #include "qemu/timer.h"
28 #include "block/block.h"
29 #include "chardev/char.h" /* qemu_chr_new */
30 #include "ui/console.h"
34 #define logout(fmt, ...) \
35 fprintf(stderr, "S3C2443\t%-24s" fmt, __func__, ##__VA_ARGS__)
37 #define TODO() logout("%s:%u: missing\n", __FILE__, __LINE__)
39 #define MiB (1024 * 1024)
42 Base Address of Special Registers
68 0x48000000 Module SDRAM
72 #define S3C2443X_SYSCON 0x4c000000
73 #define S3C2443X_IO_PORT 0x56000000
85 static const char *offset2name(const OffsetNamePair
*o2n
, unsigned offset
)
87 static char buffer
[12];
88 const char *name
= buffer
;
89 snprintf(buffer
, sizeof(buffer
), "0x%08x", offset
);
90 for (; o2n
->name
; o2n
++) {
91 if (offset
== o2n
->offset
) {
100 #define MP_MISC_BASE 0x80002000
101 #define MP_MISC_SIZE 0x00001000
103 #define MP_GPIO_BASE 0x8000D000
104 #define MP_GPIO_SIZE 0x00001000
106 #define MP_AUDIO_BASE 0x90007000
108 #define MP_LCD_BASE 0x9000c000
109 #define MP_LCD_SIZE 0x00001000
111 #define TT_SRAM_BASE 0xC0000000
112 #define TT_SRAM_SIZE 0x00020000
114 #define MP_RAM_DEFAULT_SIZE (64 * MiB)
116 #define MP_TIMER1_IRQ 4
117 #define MP_TIMER2_IRQ 5
118 #define MP_TIMER3_IRQ 6
119 #define MP_TIMER4_IRQ 7
120 #define MP_EHCI_IRQ 8
122 #define MP_GPIO_IRQ 12
123 #define MP_RTC_IRQ 28
124 #define MP_AUDIO_IRQ 30
126 /* Wolfson 8750 I2C address */
127 #define MP_WM_ADDR 0x1A
129 /* LCD register offsets */
130 #define MP_LCD_IRQCTRL 0x180
131 #define MP_LCD_IRQSTAT 0x184
132 #define MP_LCD_SPICTRL 0x1ac
133 #define MP_LCD_INST 0x1bc
134 #define MP_LCD_DATA 0x1c0
137 #define MP_LCD_SPI_DATA 0x00100011
138 #define MP_LCD_SPI_CMD 0x00104011
139 #define MP_LCD_SPI_INVALID 0x00000000
142 #define MP_LCD_INST_SETPAGE0 0xB0
144 #define MP_LCD_INST_SETPAGE7 0xB7
146 #define MP_LCD_TEXTCOLOR 0xe0e0ff /* RRGGBB */
148 #define TYPE_TT_LCD "tt_lcd"
149 #define TT_LCD(obj) OBJECT_CHECK(tt_lcd_state, (obj), TYPE_TT_LCD)
160 uint8_t video_ram
[128*64/8];
163 static uint8_t scale_lcd_color(tt_lcd_state
*s
, uint8_t col
)
165 switch (s
->brightness
) {
171 return (col
* s
->brightness
) / 7;
175 #define SET_LCD_PIXEL(depth, type) \
176 static inline void glue(set_lcd_pixel, depth) \
177 (tt_lcd_state *s, int x, int y, type col) \
180 DisplaySurface *surface = qemu_console_surface(s->con); \
181 type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
183 for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
184 for (dx = 0; dx < 3; dx++, pixel++) \
187 SET_LCD_PIXEL(8, uint8_t)
188 SET_LCD_PIXEL(16, uint16_t)
189 SET_LCD_PIXEL(32, uint32_t)
191 #include "ui/pixel_ops.h"
193 static void lcd_refresh(void *opaque
)
195 tt_lcd_state
*s
= opaque
;
196 DisplaySurface
*surface
= qemu_console_surface(s
->con
);
199 switch (surface_bits_per_pixel(surface
)) {
202 #define LCD_REFRESH(depth, func) \
204 col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
205 scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
206 scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
207 for (x = 0; x < 128; x++) { \
208 for (y = 0; y < 64; y++) { \
209 if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
210 glue(set_lcd_pixel, depth)(s, x, y, col); \
212 glue(set_lcd_pixel, depth)(s, x, y, 0); \
217 LCD_REFRESH(8, rgb_to_pixel8
)
218 LCD_REFRESH(16, rgb_to_pixel16
)
219 LCD_REFRESH(32, (is_surface_bgr(surface
) ?
220 rgb_to_pixel32bgr
: rgb_to_pixel32
))
222 hw_error("unsupported colour depth %i\n",
223 surface_bits_per_pixel(surface
));
226 dpy_gfx_update(s
->con
, 0, 0, 128*3, 64*3);
229 static void lcd_invalidate(void *opaque
)
233 static void tt_lcd_gpio_brigthness_in(void *opaque
, int irq
, int level
)
235 tt_lcd_state
*s
= opaque
;
236 s
->brightness
&= ~(1 << irq
);
237 s
->brightness
|= level
<< irq
;
240 static uint64_t tt_lcd_read(void *opaque
, hwaddr offset
,
243 tt_lcd_state
*s
= opaque
;
254 static void tt_lcd_write(void *opaque
, hwaddr offset
,
255 uint64_t value
, unsigned size
)
257 tt_lcd_state
*s
= opaque
;
265 if (value
== MP_LCD_SPI_DATA
|| value
== MP_LCD_SPI_CMD
) {
268 s
->mode
= MP_LCD_SPI_INVALID
;
273 if (value
>= MP_LCD_INST_SETPAGE0
&& value
<= MP_LCD_INST_SETPAGE7
) {
274 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
280 if (s
->mode
== MP_LCD_SPI_CMD
) {
281 if (value
>= MP_LCD_INST_SETPAGE0
&&
282 value
<= MP_LCD_INST_SETPAGE7
) {
283 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
286 } else if (s
->mode
== MP_LCD_SPI_DATA
) {
287 s
->video_ram
[s
->page
*128 + s
->page_off
] = value
;
288 s
->page_off
= (s
->page_off
+ 1) & 127;
294 static const MemoryRegionOps tt_lcd_ops
= {
296 .write
= tt_lcd_write
,
297 .endianness
= DEVICE_NATIVE_ENDIAN
,
299 .min_access_size
= 4,
304 static const GraphicHwOps tt_gfx_ops
= {
305 .invalidate
= lcd_invalidate
,
306 .gfx_update
= lcd_refresh
,
309 static int tt_lcd_init(SysBusDevice
*sbd
)
311 DeviceState
*dev
= DEVICE(sbd
);
312 tt_lcd_state
*s
= TT_LCD(dev
);
316 memory_region_init_io(&s
->mmio
, OBJECT(s
),
317 &tt_lcd_ops
, s
, "tt-lcd", MP_LCD_SIZE
);
318 sysbus_init_mmio(sbd
, &s
->mmio
);
320 s
->con
= graphic_console_init(DEVICE(dev
), 0, &tt_gfx_ops
, s
);
321 qemu_console_resize(s
->con
, 128*3, 64*3);
323 qdev_init_gpio_in(dev
, tt_lcd_gpio_brigthness_in
, 3);
328 static const VMStateDescription tt_lcd_vmsd
= {
331 .minimum_version_id
= 1,
332 .minimum_version_id_old
= 1,
333 .fields
= (VMStateField
[]) {
334 VMSTATE_UINT32(brightness
, tt_lcd_state
),
335 VMSTATE_UINT32(mode
, tt_lcd_state
),
336 VMSTATE_UINT32(irqctrl
, tt_lcd_state
),
337 VMSTATE_UINT32(page
, tt_lcd_state
),
338 VMSTATE_UINT32(page_off
, tt_lcd_state
),
339 VMSTATE_BUFFER(video_ram
, tt_lcd_state
),
340 VMSTATE_END_OF_LIST()
344 static void tt_lcd_class_init(ObjectClass
*klass
, void *data
)
346 DeviceClass
*dc
= DEVICE_CLASS(klass
);
347 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
349 //~ dc->props = dp8381x_properties;
350 //~ dc->reset = qdev_dp8381x_reset;
351 dc
->vmsd
= &tt_lcd_vmsd
;
352 k
->init
= tt_lcd_init
;
355 static const TypeInfo tt_lcd_info
= {
357 .parent
= TYPE_SYS_BUS_DEVICE
,
358 .instance_size
= sizeof(tt_lcd_state
),
359 .class_init
= tt_lcd_class_init
,
362 /******************************************************************************/
364 #define S3C2443_MPLLCON 0x10
365 #define S3C2443_CLKDIV0 0x24
367 /******************************************************************************/
369 /* SYSCON register offsets. */
370 #define SYSCON_MPLLCON 0x10
371 #define SYSCON_CLKDIV0 0x24
374 static const OffsetNamePair tt_syscon_names
[] = {
378 static uint64_t tt_syscon_read(void *opaque
, hwaddr offset
,
382 logout("%s\n", offset2name(tt_syscon_names
, offset
));
392 static void tt_syscon_write(void *opaque
, hwaddr offset
,
393 uint64_t value
, unsigned size
)
395 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_syscon_names
, offset
), value
);
402 static const MemoryRegionOps tt_syscon_ops
= {
403 .read
= tt_syscon_read
,
404 .write
= tt_syscon_write
,
405 .endianness
= DEVICE_NATIVE_ENDIAN
,
407 .min_access_size
= 4,
413 /******************************************************************************/
415 /* I/O port register offsets. */
416 #define IOPORT_GPBCON 0x10
417 #define IOPORT_GPBDAT 0x14
418 #define IOPORT_GPBUDP 0x18
419 #define IOPORT_EXTINT0 0x88
420 #define IOPORT_EXTINT1 0x8c
421 #define IOPORT_EXTINT2 0x90
422 #define IOPORT_GSTATUS1 0xb0
425 tt_ioport_write: 0x00000010
426 tt_ioport_write: 0x00000018
427 tt_ioport_write: 0x00000010
428 tt_ioport_write: 0x00000018
432 static const OffsetNamePair tt_ioport_names
[] = {
436 static uint64_t tt_ioport_read(void *opaque
, hwaddr offset
,
440 logout("%s\n", offset2name(tt_ioport_names
, offset
));
451 //~ case IOPORT_EXTINT0:
452 //~ case IOPORT_EXTINT1:
453 //~ case IOPORT_EXTINT2:
454 case IOPORT_GSTATUS1
:
463 static void tt_ioport_write(void *opaque
, hwaddr offset
,
464 uint64_t value
, unsigned size
)
466 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_ioport_names
, offset
), value
);
471 //~ case IOPORT_GPBDAT:
484 //~ case IOPORT_GSTATUS1:
490 static const MemoryRegionOps tt_ioport_ops
= {
491 .read
= tt_ioport_read
,
492 .write
= tt_ioport_write
,
493 .endianness
= DEVICE_NATIVE_ENDIAN
,
495 .min_access_size
= 4,
501 /******************************************************************************/
504 static void tt_syscon_init(void)
506 memory_region_init_io(&s
->syscon
, OBJECT(s
), &tt_syscon_ops
, s
,
507 "tt-syscon", 0x10000);
508 memory_region_add_subregion(get_system_memory(), S3C2443X_SYSCON
, &s
->syscon
);
511 static void tt_ioport_init(void)
513 memory_region_init_io(&s
->ioport
, OBJECT(s
), &tt_ioport_ops
, s
,
514 "tt-ioport", 0x10000);
515 memory_region_add_subregion(get_system_memory(), S3C2443X_IO_PORT
, &s
->ioport
);
519 /* GPIO register offsets */
520 #define MP_GPIO_OE_LO 0x008
521 #define MP_GPIO_OUT_LO 0x00c
522 #define MP_GPIO_IN_LO 0x010
523 #define MP_GPIO_IER_LO 0x014
524 #define MP_GPIO_IMR_LO 0x018
525 #define MP_GPIO_ISR_LO 0x020
526 #define MP_GPIO_OE_HI 0x508
527 #define MP_GPIO_OUT_HI 0x50c
528 #define MP_GPIO_IN_HI 0x510
529 #define MP_GPIO_IER_HI 0x514
530 #define MP_GPIO_IMR_HI 0x518
531 #define MP_GPIO_ISR_HI 0x520
533 /* GPIO bits & masks */
534 #define MP_GPIO_LCD_BRIGHTNESS 0x00070000
535 #define MP_GPIO_I2C_DATA_BIT 29
536 #define MP_GPIO_I2C_CLOCK_BIT 30
538 /* LCD brightness bits in GPIO_OE_HI */
539 #define MP_OE_LCD_BRIGHTNESS 0x0007
541 #define TYPE_TT_GPIO "tt_gpio"
542 #define TT_GPIO(obj) \
543 OBJECT_CHECK(tt_gpio_state, (obj), TYPE_TT_GPIO)
548 uint32_t lcd_brightness
;
555 qemu_irq out
[5]; /* 3 brightness out + 2 lcd (data and clock ) */
558 static void tt_gpio_brightness_update(tt_gpio_state
*s
) {
562 /* compute brightness ratio */
563 switch (s
->lcd_brightness
) {
597 /* set lcd brightness GPIOs */
598 for (i
= 0; i
<= 2; i
++) {
599 qemu_set_irq(s
->out
[i
], (brightness
>> i
) & 1);
603 static void tt_gpio_pin_event(void *opaque
, int pin
, int level
)
605 tt_gpio_state
*s
= opaque
;
606 uint32_t mask
= 1 << pin
;
607 uint32_t delta
= level
<< pin
;
608 uint32_t old
= s
->in_state
& mask
;
610 s
->in_state
&= ~mask
;
611 s
->in_state
|= delta
;
614 ((level
&& (s
->imr
& mask
)) || (!level
&& (s
->ier
& mask
)))) {
616 qemu_irq_raise(s
->irq
);
620 static uint64_t tt_gpio_read(void *opaque
, hwaddr offset
,
623 tt_gpio_state
*s
= opaque
;
626 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
627 return s
->lcd_brightness
& MP_OE_LCD_BRIGHTNESS
;
630 return s
->out_state
& 0xFFFF;
632 return s
->out_state
>> 16;
635 return s
->in_state
& 0xFFFF;
637 return s
->in_state
>> 16;
640 return s
->ier
& 0xFFFF;
645 return s
->imr
& 0xFFFF;
650 return s
->isr
& 0xFFFF;
659 static void tt_gpio_write(void *opaque
, hwaddr offset
,
660 uint64_t value
, unsigned size
)
662 tt_gpio_state
*s
= opaque
;
664 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
665 s
->lcd_brightness
= (s
->lcd_brightness
& MP_GPIO_LCD_BRIGHTNESS
) |
666 (value
& MP_OE_LCD_BRIGHTNESS
);
667 tt_gpio_brightness_update(s
);
671 s
->out_state
= (s
->out_state
& 0xFFFF0000) | (value
& 0xFFFF);
674 s
->out_state
= (s
->out_state
& 0xFFFF) | (value
<< 16);
675 s
->lcd_brightness
= (s
->lcd_brightness
& 0xFFFF) |
676 (s
->out_state
& MP_GPIO_LCD_BRIGHTNESS
);
677 tt_gpio_brightness_update(s
);
678 qemu_set_irq(s
->out
[3], (s
->out_state
>> MP_GPIO_I2C_DATA_BIT
) & 1);
679 qemu_set_irq(s
->out
[4], (s
->out_state
>> MP_GPIO_I2C_CLOCK_BIT
) & 1);
683 s
->ier
= (s
->ier
& 0xFFFF0000) | (value
& 0xFFFF);
686 s
->ier
= (s
->ier
& 0xFFFF) | (value
<< 16);
690 s
->imr
= (s
->imr
& 0xFFFF0000) | (value
& 0xFFFF);
693 s
->imr
= (s
->imr
& 0xFFFF) | (value
<< 16);
698 static const MemoryRegionOps tt_gpio_ops
= {
699 .read
= tt_gpio_read
,
700 .write
= tt_gpio_write
,
701 .endianness
= DEVICE_NATIVE_ENDIAN
,
703 .min_access_size
= 4,
708 static void tt_gpio_reset(DeviceState
*d
)
710 tt_gpio_state
*s
= TT_GPIO(d
);
712 s
->lcd_brightness
= 0;
714 s
->in_state
= 0xffffffff;
720 static int tt_gpio_init(SysBusDevice
*sbd
)
722 DeviceState
*dev
= DEVICE(sbd
);
723 tt_gpio_state
*s
= TT_GPIO(dev
);
725 sysbus_init_irq(sbd
, &s
->irq
);
727 memory_region_init_io(&s
->mmio
, OBJECT(s
), &tt_gpio_ops
, s
,
728 "tt-gpio", MP_GPIO_SIZE
);
729 sysbus_init_mmio(sbd
, &s
->mmio
);
731 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
733 qdev_init_gpio_in(dev
, tt_gpio_pin_event
, 32);
738 static const VMStateDescription tt_gpio_vmsd
= {
739 .name
= TYPE_TT_GPIO
,
741 .minimum_version_id
= 1,
742 .minimum_version_id_old
= 1,
743 .fields
= (VMStateField
[]) {
744 VMSTATE_UINT32(lcd_brightness
, tt_gpio_state
),
745 VMSTATE_UINT32(out_state
, tt_gpio_state
),
746 VMSTATE_UINT32(in_state
, tt_gpio_state
),
747 VMSTATE_UINT32(ier
, tt_gpio_state
),
748 VMSTATE_UINT32(imr
, tt_gpio_state
),
749 VMSTATE_UINT32(isr
, tt_gpio_state
),
750 VMSTATE_END_OF_LIST()
754 static void tt_gpio_class_init(ObjectClass
*klass
, void *data
)
756 DeviceClass
*dc
= DEVICE_CLASS(klass
);
757 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
758 dc
->reset
= tt_gpio_reset
;
759 dc
->vmsd
= &tt_gpio_vmsd
;
760 k
->init
= tt_gpio_init
;
763 static const TypeInfo tt_gpio_info
= {
764 .name
= TYPE_TT_GPIO
,
765 .parent
= TYPE_SYS_BUS_DEVICE
,
766 .instance_size
= sizeof(tt_gpio_state
),
767 .class_init
= tt_gpio_class_init
,
770 /* Keyboard codes & masks */
771 #define KEY_RELEASED 0x80
772 #define KEY_CODE 0x7f
774 #define KEYCODE_TAB 0x0f
775 #define KEYCODE_ENTER 0x1c
776 #define KEYCODE_F 0x21
777 #define KEYCODE_M 0x32
779 #define KEYCODE_EXTENDED 0xe0
780 #define KEYCODE_UP 0x48
781 #define KEYCODE_DOWN 0x50
782 #define KEYCODE_LEFT 0x4b
783 #define KEYCODE_RIGHT 0x4d
785 #define MP_KEY_WHEEL_VOL (1 << 0)
786 #define MP_KEY_WHEEL_VOL_INV (1 << 1)
787 #define MP_KEY_WHEEL_NAV (1 << 2)
788 #define MP_KEY_WHEEL_NAV_INV (1 << 3)
789 #define MP_KEY_BTN_FAVORITS (1 << 4)
790 #define MP_KEY_BTN_MENU (1 << 5)
791 #define MP_KEY_BTN_VOLUME (1 << 6)
792 #define MP_KEY_BTN_NAVIGATION (1 << 7)
794 #define TYPE_TT_KEY "tt_key"
795 #define TT_KEY(obj) \
796 OBJECT_CHECK(tt_key_state, (obj), TYPE_TT_KEY)
801 uint32_t kbd_extended
;
802 uint32_t pressed_keys
;
806 static void tt_key_event(void *opaque
, int keycode
)
808 tt_key_state
*s
= opaque
;
812 if (keycode
== KEYCODE_EXTENDED
) {
817 if (s
->kbd_extended
) {
818 switch (keycode
& KEY_CODE
) {
820 event
= MP_KEY_WHEEL_NAV
| MP_KEY_WHEEL_NAV_INV
;
824 event
= MP_KEY_WHEEL_NAV
;
828 event
= MP_KEY_WHEEL_VOL
| MP_KEY_WHEEL_VOL_INV
;
832 event
= MP_KEY_WHEEL_VOL
;
836 switch (keycode
& KEY_CODE
) {
838 event
= MP_KEY_BTN_FAVORITS
;
842 event
= MP_KEY_BTN_VOLUME
;
846 event
= MP_KEY_BTN_NAVIGATION
;
850 event
= MP_KEY_BTN_MENU
;
853 /* Do not repeat already pressed buttons */
854 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
860 /* Raise GPIO pin first if repeating a key */
861 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
862 for (i
= 0; i
<= 7; i
++) {
863 if (event
& (1 << i
)) {
864 qemu_set_irq(s
->out
[i
], 1);
868 for (i
= 0; i
<= 7; i
++) {
869 if (event
& (1 << i
)) {
870 qemu_set_irq(s
->out
[i
], !!(keycode
& KEY_RELEASED
));
873 if (keycode
& KEY_RELEASED
) {
874 s
->pressed_keys
&= ~event
;
876 s
->pressed_keys
|= event
;
883 static int tt_key_init(SysBusDevice
*sbd
)
885 DeviceState
*dev
= DEVICE(sbd
);
886 tt_key_state
*s
= TT_KEY(dev
);
888 sysbus_init_mmio(sbd
, &s
->mmio
);
893 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
895 qemu_add_kbd_event_handler(tt_key_event
, s
);
900 static const VMStateDescription tt_key_vmsd
= {
903 .minimum_version_id
= 1,
904 .minimum_version_id_old
= 1,
905 .fields
= (VMStateField
[]) {
906 VMSTATE_UINT32(kbd_extended
, tt_key_state
),
907 VMSTATE_UINT32(pressed_keys
, tt_key_state
),
908 VMSTATE_END_OF_LIST()
912 static void tt_key_class_init(ObjectClass
*klass
, void *data
)
914 DeviceClass
*dc
= DEVICE_CLASS(klass
);
915 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
916 dc
->vmsd
= &tt_key_vmsd
;
917 k
->init
= tt_key_init
;
920 static const TypeInfo tt_key_info
= {
922 .parent
= TYPE_SYS_BUS_DEVICE
,
923 .instance_size
= sizeof(tt_key_state
),
924 .class_init
= tt_key_class_init
,
927 static struct arm_boot_info tt_binfo
= {
931 .loader_start
= TT_SRAM_BASE
,
935 .atag_revision
= 0x0004000a,
938 static void tt_init(MachineState
*machine
)
945 DeviceState
*i2c_dev
;
946 DeviceState
*lcd_dev
;
947 DeviceState
*key_dev
;
948 DeviceState
*wm8750_dev
;
951 unsigned long flash_size
;
959 if (machine
->cpu_model
&& strcmp(machine
->cpu_model
, "arm920t")) {
960 fprintf(stderr
, "only working with cpu arm920t\n");
965 /* Allocate storage for board state. */
966 s
= g_new0(TTState
, 1);
968 for (i
= 0; i
< serial_max_hds(); i
++) {
971 assert(serial_hd(i
));
973 /* TODO: This code no longer works. Remove or replace. */
974 if (serial_hd(i
) == NULL
) {
976 snprintf(name
, sizeof(name
), "serial%u", i
);
977 serial_hd(i
) = qemu_chr_new(name
, "vc:80Cx24C");
982 /* Initialise SOC. */
983 s
->soc
= s3c2440_init(ram_size
);
987 //~ ram_off = qemu_ram_alloc(NULL, "arm920.ram", ram_size);
988 //~ cpu_register_physical_memory(0x00000000, ram_size, ram_off | IO_MEM_RAM);
989 //~ cpu_register_physical_memory(0x30000000, ram_size, ram_off | IO_MEM_RAM);
990 //~ cpu_register_physical_memory(0x80000000, ram_size, ram_off | IO_MEM_RAM);
991 //~ cpu_register_physical_memory(0xc0000000, ram_size, ram_off | IO_MEM_RAM);
993 //~ tt_syscon_init();
994 //~ tt_ioport_init();
997 dev
= sysbus_create_simple(TYPE_TT_GPIO
, MP_GPIO_BASE
, pic
[MP_GPIO_IRQ
]);
998 i2c_dev
= sysbus_create_simple("gpio_i2c", 0, NULL
);
999 i2c
= (I2CBus
*)qdev_get_child_bus(i2c_dev
, "i2c");
1001 lcd_dev
= sysbus_create_simple(TYPE_TT_LCD
, MP_LCD_BASE
, NULL
);
1002 key_dev
= sysbus_create_simple(TYPE_TT_KEY
, 0, NULL
);
1005 qdev_connect_gpio_out(i2c_dev
, 0,
1006 qdev_get_gpio_in(dev
, MP_GPIO_I2C_DATA_BIT
));
1008 qdev_connect_gpio_out(dev
, 3, qdev_get_gpio_in(i2c_dev
, 0));
1010 qdev_connect_gpio_out(dev
, 4, qdev_get_gpio_in(i2c_dev
, 1));
1012 for (i
= 0; i
< 3; i
++) {
1013 qdev_connect_gpio_out(dev
, i
, qdev_get_gpio_in(lcd_dev
, i
));
1015 for (i
= 0; i
< 4; i
++) {
1016 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 8));
1018 for (i
= 4; i
< 8; i
++) {
1019 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 15));
1022 wm8750_dev
= i2c_create_slave(i2c
, "wm8750", MP_WM_ADDR
);
1023 dev
= qdev_create(NULL
, "mv88w8618_audio");
1024 s
= SYS_BUS_DEVICE(dev
);
1025 qdev_prop_set_ptr(dev
, "wm8750", wm8750_dev
);
1026 qdev_init_nofail(dev
);
1027 sysbus_mmio_map(s
, 0, MP_AUDIO_BASE
);
1028 sysbus_connect_irq(s
, 0, pic
[MP_AUDIO_IRQ
]);
1031 tt_binfo
.ram_size
= ram_size
;
1032 tt_binfo
.kernel_filename
= machine
->kernel_filename
;
1033 tt_binfo
.kernel_cmdline
= machine
->kernel_cmdline
;
1034 tt_binfo
.initrd_filename
= machine
->initrd_filename
;
1035 if (machine
->kernel_filename
!= NULL
) {
1036 /* TODO: load ttsystem. */
1037 //~ sect_size = 0x11b778, sect_addr = 0x31700000
1038 //~ sect_size = 0x6a3f45, sect_addr = 0x31000000
1039 arm_load_kernel(cpu
, &tt_binfo
);
1043 static void tt_init_go(MachineState
*machine
)
1045 tt_binfo
.board_id
= 0x25d;
1046 ram_size
= 64 * MiB
;
1050 static void tt_init_666(MachineState
*machine
)
1052 tt_binfo
.board_id
= 0x666;
1056 static void tt_init_smdk2443(MachineState
*machine
)
1058 tt_binfo
.board_id
= 0x43c;
1062 static void tt_machine_init(MachineClass
*mc
)
1064 mc
->desc
= "OpenTom (ARM920-T)";
1065 mc
->init
= tt_init_go
;
1068 DEFINE_MACHINE("tt", tt_machine_init
)
1070 static void tt_machine_666_init(MachineClass
*mc
)
1072 mc
->desc
= "OpenTom (ARM920-T)";
1073 mc
->init
= tt_init_666
;
1076 DEFINE_MACHINE("tt666", tt_machine_666_init
)
1078 static void tt_machine_smdk2443_init(MachineClass
*mc
)
1080 mc
->desc
= "smdk2443 (ARM920-T)";
1081 mc
->init
= tt_init_smdk2443
;
1084 DEFINE_MACHINE("smdk2443", tt_machine_smdk2443_init
)
1086 static void tt_register_types(void)
1088 type_register_static(&tt_lcd_info
);
1089 type_register_static(&tt_gpio_info
);
1090 type_register_static(&tt_key_info
);
1093 type_init(tt_register_types
)