2 * TomTom GO 730 with Samsung S3C2443X emulation.
4 * Copyright (c) 2010, 2013, 2019 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/boot.h"
19 #include "hw/boards.h"
20 #include "hw/hw.h" /* hw_error */
21 #include "hw/i2c/i2c.h"
22 #include "hw/i386/pc.h"
23 #include "hw/irq.h" /* qemu_irq_raise */
24 #include "hw/ptimer.h" /* ptimer_state */
25 #include "exec/address-spaces.h" /* get_system_memory */
26 #include "migration/vmstate.h" /* VMStateDescription */
28 #include "sysemu/sysemu.h"
29 #include "qemu/timer.h"
30 #include "block/block.h"
31 #include "chardev/char.h" /* qemu_chr_new */
32 #include "ui/console.h"
36 #define logout(fmt, ...) \
37 fprintf(stderr, "S3C2443\t%-24s" fmt, __func__, ##__VA_ARGS__)
39 #define TODO() logout("%s:%u: missing\n", __FILE__, __LINE__)
41 #define MiB (1024 * 1024)
44 Base Address of Special Registers
70 0x48000000 Module SDRAM
74 #define S3C2443X_SYSCON 0x4c000000
75 #define S3C2443X_IO_PORT 0x56000000
87 static const char *offset2name(const OffsetNamePair
*o2n
, unsigned offset
)
89 static char buffer
[12];
90 const char *name
= buffer
;
91 snprintf(buffer
, sizeof(buffer
), "0x%08x", offset
);
92 for (; o2n
->name
; o2n
++) {
93 if (offset
== o2n
->offset
) {
102 #define MP_MISC_BASE 0x80002000
103 #define MP_MISC_SIZE 0x00001000
105 #define MP_GPIO_BASE 0x8000D000
106 #define MP_GPIO_SIZE 0x00001000
108 #define MP_AUDIO_BASE 0x90007000
110 #define MP_LCD_BASE 0x9000c000
111 #define MP_LCD_SIZE 0x00001000
113 #define TT_SRAM_BASE 0xC0000000
114 #define TT_SRAM_SIZE 0x00020000
116 #define MP_RAM_DEFAULT_SIZE (64 * MiB)
118 #define MP_TIMER1_IRQ 4
119 #define MP_TIMER2_IRQ 5
120 #define MP_TIMER3_IRQ 6
121 #define MP_TIMER4_IRQ 7
122 #define MP_EHCI_IRQ 8
124 #define MP_GPIO_IRQ 12
125 #define MP_RTC_IRQ 28
126 #define MP_AUDIO_IRQ 30
128 /* Wolfson 8750 I2C address */
129 #define MP_WM_ADDR 0x1A
131 /* LCD register offsets */
132 #define MP_LCD_IRQCTRL 0x180
133 #define MP_LCD_IRQSTAT 0x184
134 #define MP_LCD_SPICTRL 0x1ac
135 #define MP_LCD_INST 0x1bc
136 #define MP_LCD_DATA 0x1c0
139 #define MP_LCD_SPI_DATA 0x00100011
140 #define MP_LCD_SPI_CMD 0x00104011
141 #define MP_LCD_SPI_INVALID 0x00000000
144 #define MP_LCD_INST_SETPAGE0 0xB0
146 #define MP_LCD_INST_SETPAGE7 0xB7
148 #define MP_LCD_TEXTCOLOR 0xe0e0ff /* RRGGBB */
150 #define TYPE_TT_LCD "tt_lcd"
151 #define TT_LCD(obj) OBJECT_CHECK(tt_lcd_state, (obj), TYPE_TT_LCD)
162 uint8_t video_ram
[128*64/8];
165 static uint8_t scale_lcd_color(tt_lcd_state
*s
, uint8_t col
)
167 switch (s
->brightness
) {
173 return (col
* s
->brightness
) / 7;
177 #define SET_LCD_PIXEL(depth, type) \
178 static inline void glue(set_lcd_pixel, depth) \
179 (tt_lcd_state *s, int x, int y, type col) \
182 DisplaySurface *surface = qemu_console_surface(s->con); \
183 type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
185 for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
186 for (dx = 0; dx < 3; dx++, pixel++) \
189 SET_LCD_PIXEL(8, uint8_t)
190 SET_LCD_PIXEL(16, uint16_t)
191 SET_LCD_PIXEL(32, uint32_t)
193 #include "ui/pixel_ops.h"
195 static void lcd_refresh(void *opaque
)
197 tt_lcd_state
*s
= opaque
;
198 DisplaySurface
*surface
= qemu_console_surface(s
->con
);
201 switch (surface_bits_per_pixel(surface
)) {
204 #define LCD_REFRESH(depth, func) \
206 col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
207 scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
208 scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
209 for (x = 0; x < 128; x++) { \
210 for (y = 0; y < 64; y++) { \
211 if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
212 glue(set_lcd_pixel, depth)(s, x, y, col); \
214 glue(set_lcd_pixel, depth)(s, x, y, 0); \
219 LCD_REFRESH(8, rgb_to_pixel8
)
220 LCD_REFRESH(16, rgb_to_pixel16
)
221 LCD_REFRESH(32, (is_surface_bgr(surface
) ?
222 rgb_to_pixel32bgr
: rgb_to_pixel32
))
224 hw_error("unsupported colour depth %i\n",
225 surface_bits_per_pixel(surface
));
228 dpy_gfx_update(s
->con
, 0, 0, 128*3, 64*3);
231 static void lcd_invalidate(void *opaque
)
235 static void tt_lcd_gpio_brigthness_in(void *opaque
, int irq
, int level
)
237 tt_lcd_state
*s
= opaque
;
238 s
->brightness
&= ~(1 << irq
);
239 s
->brightness
|= level
<< irq
;
242 static uint64_t tt_lcd_read(void *opaque
, hwaddr offset
,
245 tt_lcd_state
*s
= opaque
;
256 static void tt_lcd_write(void *opaque
, hwaddr offset
,
257 uint64_t value
, unsigned size
)
259 tt_lcd_state
*s
= opaque
;
267 if (value
== MP_LCD_SPI_DATA
|| value
== MP_LCD_SPI_CMD
) {
270 s
->mode
= MP_LCD_SPI_INVALID
;
275 if (value
>= MP_LCD_INST_SETPAGE0
&& value
<= MP_LCD_INST_SETPAGE7
) {
276 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
282 if (s
->mode
== MP_LCD_SPI_CMD
) {
283 if (value
>= MP_LCD_INST_SETPAGE0
&&
284 value
<= MP_LCD_INST_SETPAGE7
) {
285 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
288 } else if (s
->mode
== MP_LCD_SPI_DATA
) {
289 s
->video_ram
[s
->page
*128 + s
->page_off
] = value
;
290 s
->page_off
= (s
->page_off
+ 1) & 127;
296 static const MemoryRegionOps tt_lcd_ops
= {
298 .write
= tt_lcd_write
,
299 .endianness
= DEVICE_NATIVE_ENDIAN
,
301 .min_access_size
= 4,
306 static const GraphicHwOps tt_gfx_ops
= {
307 .invalidate
= lcd_invalidate
,
308 .gfx_update
= lcd_refresh
,
311 static void tt_lcd_realize(DeviceState
*dev
, Error
**errp
)
313 tt_lcd_state
*s
= TT_LCD(dev
);
314 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
318 memory_region_init_io(&s
->mmio
, OBJECT(s
),
319 &tt_lcd_ops
, s
, "tt-lcd", MP_LCD_SIZE
);
320 sysbus_init_mmio(sbd
, &s
->mmio
);
322 s
->con
= graphic_console_init(DEVICE(dev
), 0, &tt_gfx_ops
, s
);
323 qemu_console_resize(s
->con
, 128*3, 64*3);
325 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
);
348 //~ dc->props = dp8381x_properties;
349 dc
->realize
= tt_lcd_realize
;
350 //~ dc->reset = qdev_dp8381x_reset;
351 dc
->vmsd
= &tt_lcd_vmsd
;
354 static const TypeInfo tt_lcd_info
= {
356 .parent
= TYPE_SYS_BUS_DEVICE
,
357 .instance_size
= sizeof(tt_lcd_state
),
358 .class_init
= tt_lcd_class_init
,
361 /******************************************************************************/
363 #define S3C2443_MPLLCON 0x10
364 #define S3C2443_CLKDIV0 0x24
366 /******************************************************************************/
368 /* SYSCON register offsets. */
369 #define SYSCON_MPLLCON 0x10
370 #define SYSCON_CLKDIV0 0x24
373 static const OffsetNamePair tt_syscon_names
[] = {
377 static uint64_t tt_syscon_read(void *opaque
, hwaddr offset
,
381 logout("%s\n", offset2name(tt_syscon_names
, offset
));
391 static void tt_syscon_write(void *opaque
, hwaddr offset
,
392 uint64_t value
, unsigned size
)
394 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_syscon_names
, offset
), value
);
401 static const MemoryRegionOps tt_syscon_ops
= {
402 .read
= tt_syscon_read
,
403 .write
= tt_syscon_write
,
404 .endianness
= DEVICE_NATIVE_ENDIAN
,
406 .min_access_size
= 4,
412 /******************************************************************************/
414 /* I/O port register offsets. */
415 #define IOPORT_GPBCON 0x10
416 #define IOPORT_GPBDAT 0x14
417 #define IOPORT_GPBUDP 0x18
418 #define IOPORT_EXTINT0 0x88
419 #define IOPORT_EXTINT1 0x8c
420 #define IOPORT_EXTINT2 0x90
421 #define IOPORT_GSTATUS1 0xb0
424 tt_ioport_write: 0x00000010
425 tt_ioport_write: 0x00000018
426 tt_ioport_write: 0x00000010
427 tt_ioport_write: 0x00000018
431 static const OffsetNamePair tt_ioport_names
[] = {
435 static uint64_t tt_ioport_read(void *opaque
, hwaddr offset
,
439 logout("%s\n", offset2name(tt_ioport_names
, offset
));
450 //~ case IOPORT_EXTINT0:
451 //~ case IOPORT_EXTINT1:
452 //~ case IOPORT_EXTINT2:
453 case IOPORT_GSTATUS1
:
462 static void tt_ioport_write(void *opaque
, hwaddr offset
,
463 uint64_t value
, unsigned size
)
465 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_ioport_names
, offset
), value
);
470 //~ case IOPORT_GPBDAT:
483 //~ case IOPORT_GSTATUS1:
489 static const MemoryRegionOps tt_ioport_ops
= {
490 .read
= tt_ioport_read
,
491 .write
= tt_ioport_write
,
492 .endianness
= DEVICE_NATIVE_ENDIAN
,
494 .min_access_size
= 4,
500 /******************************************************************************/
503 static void tt_syscon_init(void)
505 memory_region_init_io(&s
->syscon
, OBJECT(s
), &tt_syscon_ops
, s
,
506 "tt-syscon", 0x10000);
507 memory_region_add_subregion(get_system_memory(), S3C2443X_SYSCON
, &s
->syscon
);
510 static void tt_ioport_init(void)
512 memory_region_init_io(&s
->ioport
, OBJECT(s
), &tt_ioport_ops
, s
,
513 "tt-ioport", 0x10000);
514 memory_region_add_subregion(get_system_memory(), S3C2443X_IO_PORT
, &s
->ioport
);
518 /* GPIO register offsets */
519 #define MP_GPIO_OE_LO 0x008
520 #define MP_GPIO_OUT_LO 0x00c
521 #define MP_GPIO_IN_LO 0x010
522 #define MP_GPIO_IER_LO 0x014
523 #define MP_GPIO_IMR_LO 0x018
524 #define MP_GPIO_ISR_LO 0x020
525 #define MP_GPIO_OE_HI 0x508
526 #define MP_GPIO_OUT_HI 0x50c
527 #define MP_GPIO_IN_HI 0x510
528 #define MP_GPIO_IER_HI 0x514
529 #define MP_GPIO_IMR_HI 0x518
530 #define MP_GPIO_ISR_HI 0x520
532 /* GPIO bits & masks */
533 #define MP_GPIO_LCD_BRIGHTNESS 0x00070000
534 #define MP_GPIO_I2C_DATA_BIT 29
535 #define MP_GPIO_I2C_CLOCK_BIT 30
537 /* LCD brightness bits in GPIO_OE_HI */
538 #define MP_OE_LCD_BRIGHTNESS 0x0007
540 #define TYPE_TT_GPIO "tt_gpio"
541 #define TT_GPIO(obj) \
542 OBJECT_CHECK(tt_gpio_state, (obj), TYPE_TT_GPIO)
547 uint32_t lcd_brightness
;
554 qemu_irq out
[5]; /* 3 brightness out + 2 lcd (data and clock ) */
557 static void tt_gpio_brightness_update(tt_gpio_state
*s
) {
561 /* compute brightness ratio */
562 switch (s
->lcd_brightness
) {
596 /* set lcd brightness GPIOs */
597 for (i
= 0; i
<= 2; i
++) {
598 qemu_set_irq(s
->out
[i
], (brightness
>> i
) & 1);
602 static void tt_gpio_pin_event(void *opaque
, int pin
, int level
)
604 tt_gpio_state
*s
= opaque
;
605 uint32_t mask
= 1 << pin
;
606 uint32_t delta
= level
<< pin
;
607 uint32_t old
= s
->in_state
& mask
;
609 s
->in_state
&= ~mask
;
610 s
->in_state
|= delta
;
613 ((level
&& (s
->imr
& mask
)) || (!level
&& (s
->ier
& mask
)))) {
615 qemu_irq_raise(s
->irq
);
619 static uint64_t tt_gpio_read(void *opaque
, hwaddr offset
,
622 tt_gpio_state
*s
= opaque
;
625 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
626 return s
->lcd_brightness
& MP_OE_LCD_BRIGHTNESS
;
629 return s
->out_state
& 0xFFFF;
631 return s
->out_state
>> 16;
634 return s
->in_state
& 0xFFFF;
636 return s
->in_state
>> 16;
639 return s
->ier
& 0xFFFF;
644 return s
->imr
& 0xFFFF;
649 return s
->isr
& 0xFFFF;
658 static void tt_gpio_write(void *opaque
, hwaddr offset
,
659 uint64_t value
, unsigned size
)
661 tt_gpio_state
*s
= opaque
;
663 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
664 s
->lcd_brightness
= (s
->lcd_brightness
& MP_GPIO_LCD_BRIGHTNESS
) |
665 (value
& MP_OE_LCD_BRIGHTNESS
);
666 tt_gpio_brightness_update(s
);
670 s
->out_state
= (s
->out_state
& 0xFFFF0000) | (value
& 0xFFFF);
673 s
->out_state
= (s
->out_state
& 0xFFFF) | (value
<< 16);
674 s
->lcd_brightness
= (s
->lcd_brightness
& 0xFFFF) |
675 (s
->out_state
& MP_GPIO_LCD_BRIGHTNESS
);
676 tt_gpio_brightness_update(s
);
677 qemu_set_irq(s
->out
[3], (s
->out_state
>> MP_GPIO_I2C_DATA_BIT
) & 1);
678 qemu_set_irq(s
->out
[4], (s
->out_state
>> MP_GPIO_I2C_CLOCK_BIT
) & 1);
682 s
->ier
= (s
->ier
& 0xFFFF0000) | (value
& 0xFFFF);
685 s
->ier
= (s
->ier
& 0xFFFF) | (value
<< 16);
689 s
->imr
= (s
->imr
& 0xFFFF0000) | (value
& 0xFFFF);
692 s
->imr
= (s
->imr
& 0xFFFF) | (value
<< 16);
697 static const MemoryRegionOps tt_gpio_ops
= {
698 .read
= tt_gpio_read
,
699 .write
= tt_gpio_write
,
700 .endianness
= DEVICE_NATIVE_ENDIAN
,
702 .min_access_size
= 4,
707 static void tt_gpio_reset(DeviceState
*d
)
709 tt_gpio_state
*s
= TT_GPIO(d
);
711 s
->lcd_brightness
= 0;
713 s
->in_state
= 0xffffffff;
719 static void tt_gpio_realize(DeviceState
*dev
, Error
**errp
)
721 tt_gpio_state
*s
= TT_GPIO(dev
);
722 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
724 sysbus_init_irq(sbd
, &s
->irq
);
726 memory_region_init_io(&s
->mmio
, OBJECT(s
), &tt_gpio_ops
, s
,
727 "tt-gpio", MP_GPIO_SIZE
);
728 sysbus_init_mmio(sbd
, &s
->mmio
);
730 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
732 qdev_init_gpio_in(dev
, tt_gpio_pin_event
, 32);
735 static const VMStateDescription tt_gpio_vmsd
= {
736 .name
= TYPE_TT_GPIO
,
738 .minimum_version_id
= 1,
739 .minimum_version_id_old
= 1,
740 .fields
= (VMStateField
[]) {
741 VMSTATE_UINT32(lcd_brightness
, tt_gpio_state
),
742 VMSTATE_UINT32(out_state
, tt_gpio_state
),
743 VMSTATE_UINT32(in_state
, tt_gpio_state
),
744 VMSTATE_UINT32(ier
, tt_gpio_state
),
745 VMSTATE_UINT32(imr
, tt_gpio_state
),
746 VMSTATE_UINT32(isr
, tt_gpio_state
),
747 VMSTATE_END_OF_LIST()
751 static void tt_gpio_class_init(ObjectClass
*klass
, void *data
)
753 DeviceClass
*dc
= DEVICE_CLASS(klass
);
754 dc
->realize
= tt_gpio_realize
;
755 dc
->reset
= tt_gpio_reset
;
756 dc
->vmsd
= &tt_gpio_vmsd
;
759 static const TypeInfo tt_gpio_info
= {
760 .name
= TYPE_TT_GPIO
,
761 .parent
= TYPE_SYS_BUS_DEVICE
,
762 .instance_size
= sizeof(tt_gpio_state
),
763 .class_init
= tt_gpio_class_init
,
766 /* Keyboard codes & masks */
767 #define KEY_RELEASED 0x80
768 #define KEY_CODE 0x7f
770 #define KEYCODE_TAB 0x0f
771 #define KEYCODE_ENTER 0x1c
772 #define KEYCODE_F 0x21
773 #define KEYCODE_M 0x32
775 #define KEYCODE_EXTENDED 0xe0
776 #define KEYCODE_UP 0x48
777 #define KEYCODE_DOWN 0x50
778 #define KEYCODE_LEFT 0x4b
779 #define KEYCODE_RIGHT 0x4d
781 #define MP_KEY_WHEEL_VOL (1 << 0)
782 #define MP_KEY_WHEEL_VOL_INV (1 << 1)
783 #define MP_KEY_WHEEL_NAV (1 << 2)
784 #define MP_KEY_WHEEL_NAV_INV (1 << 3)
785 #define MP_KEY_BTN_FAVORITS (1 << 4)
786 #define MP_KEY_BTN_MENU (1 << 5)
787 #define MP_KEY_BTN_VOLUME (1 << 6)
788 #define MP_KEY_BTN_NAVIGATION (1 << 7)
790 #define TYPE_TT_KEY "tt_key"
791 #define TT_KEY(obj) \
792 OBJECT_CHECK(tt_key_state, (obj), TYPE_TT_KEY)
797 uint32_t kbd_extended
;
798 uint32_t pressed_keys
;
802 static void tt_key_event(void *opaque
, int keycode
)
804 tt_key_state
*s
= opaque
;
808 if (keycode
== KEYCODE_EXTENDED
) {
813 if (s
->kbd_extended
) {
814 switch (keycode
& KEY_CODE
) {
816 event
= MP_KEY_WHEEL_NAV
| MP_KEY_WHEEL_NAV_INV
;
820 event
= MP_KEY_WHEEL_NAV
;
824 event
= MP_KEY_WHEEL_VOL
| MP_KEY_WHEEL_VOL_INV
;
828 event
= MP_KEY_WHEEL_VOL
;
832 switch (keycode
& KEY_CODE
) {
834 event
= MP_KEY_BTN_FAVORITS
;
838 event
= MP_KEY_BTN_VOLUME
;
842 event
= MP_KEY_BTN_NAVIGATION
;
846 event
= MP_KEY_BTN_MENU
;
849 /* Do not repeat already pressed buttons */
850 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
856 /* Raise GPIO pin first if repeating a key */
857 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
858 for (i
= 0; i
<= 7; i
++) {
859 if (event
& (1 << i
)) {
860 qemu_set_irq(s
->out
[i
], 1);
864 for (i
= 0; i
<= 7; i
++) {
865 if (event
& (1 << i
)) {
866 qemu_set_irq(s
->out
[i
], !!(keycode
& KEY_RELEASED
));
869 if (keycode
& KEY_RELEASED
) {
870 s
->pressed_keys
&= ~event
;
872 s
->pressed_keys
|= event
;
879 static void tt_key_realize(DeviceState
*dev
, Error
**errp
)
881 tt_key_state
*s
= TT_KEY(dev
);
882 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
884 sysbus_init_mmio(sbd
, &s
->mmio
);
889 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
891 qemu_add_kbd_event_handler(tt_key_event
, s
);
894 static const VMStateDescription tt_key_vmsd
= {
897 .minimum_version_id
= 1,
898 .minimum_version_id_old
= 1,
899 .fields
= (VMStateField
[]) {
900 VMSTATE_UINT32(kbd_extended
, tt_key_state
),
901 VMSTATE_UINT32(pressed_keys
, tt_key_state
),
902 VMSTATE_END_OF_LIST()
906 static void tt_key_class_init(ObjectClass
*klass
, void *data
)
908 DeviceClass
*dc
= DEVICE_CLASS(klass
);
909 dc
->realize
= tt_key_realize
;
910 dc
->vmsd
= &tt_key_vmsd
;
913 static const TypeInfo tt_key_info
= {
915 .parent
= TYPE_SYS_BUS_DEVICE
,
916 .instance_size
= sizeof(tt_key_state
),
917 .class_init
= tt_key_class_init
,
920 static struct arm_boot_info tt_binfo
= {
924 .loader_start
= TT_SRAM_BASE
,
928 .atag_revision
= 0x0004000a,
931 static void tt_init(MachineState
*machine
)
938 DeviceState
*i2c_dev
;
939 DeviceState
*lcd_dev
;
940 DeviceState
*key_dev
;
941 DeviceState
*wm8750_dev
;
944 unsigned long flash_size
;
952 if (machine
->cpu_model
&& strcmp(machine
->cpu_model
, "arm920t")) {
953 fprintf(stderr
, "only working with cpu arm920t\n");
958 /* Allocate storage for board state. */
959 s
= g_new0(TTState
, 1);
961 for (i
= 0; i
< serial_max_hds(); i
++) {
964 assert(serial_hd(i
));
966 /* TODO: This code no longer works. Remove or replace. */
967 if (serial_hd(i
) == NULL
) {
969 snprintf(name
, sizeof(name
), "serial%u", i
);
970 serial_hd(i
) = qemu_chr_new(name
, "vc:80Cx24C", NULL
);
975 /* Initialise SOC. */
976 s
->soc
= s3c2440_init(ram_size
);
980 //~ ram_off = qemu_ram_alloc(NULL, "arm920.ram", ram_size);
981 //~ cpu_register_physical_memory(0x00000000, ram_size, ram_off | IO_MEM_RAM);
982 //~ cpu_register_physical_memory(0x30000000, ram_size, ram_off | IO_MEM_RAM);
983 //~ cpu_register_physical_memory(0x80000000, ram_size, ram_off | IO_MEM_RAM);
984 //~ cpu_register_physical_memory(0xc0000000, ram_size, ram_off | IO_MEM_RAM);
986 //~ tt_syscon_init();
987 //~ tt_ioport_init();
990 dev
= sysbus_create_simple(TYPE_TT_GPIO
, MP_GPIO_BASE
, pic
[MP_GPIO_IRQ
]);
991 i2c_dev
= sysbus_create_simple("gpio_i2c", 0, NULL
);
992 i2c
= (I2CBus
*)qdev_get_child_bus(i2c_dev
, "i2c");
994 lcd_dev
= sysbus_create_simple(TYPE_TT_LCD
, MP_LCD_BASE
, NULL
);
995 key_dev
= sysbus_create_simple(TYPE_TT_KEY
, 0, NULL
);
998 qdev_connect_gpio_out(i2c_dev
, 0,
999 qdev_get_gpio_in(dev
, MP_GPIO_I2C_DATA_BIT
));
1001 qdev_connect_gpio_out(dev
, 3, qdev_get_gpio_in(i2c_dev
, 0));
1003 qdev_connect_gpio_out(dev
, 4, qdev_get_gpio_in(i2c_dev
, 1));
1005 for (i
= 0; i
< 3; i
++) {
1006 qdev_connect_gpio_out(dev
, i
, qdev_get_gpio_in(lcd_dev
, i
));
1008 for (i
= 0; i
< 4; i
++) {
1009 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 8));
1011 for (i
= 4; i
< 8; i
++) {
1012 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 15));
1015 wm8750_dev
= i2c_create_slave(i2c
, "wm8750", MP_WM_ADDR
);
1016 dev
= qdev_create(NULL
, "mv88w8618_audio");
1017 s
= SYS_BUS_DEVICE(dev
);
1018 qdev_prop_set_ptr(dev
, "wm8750", wm8750_dev
);
1019 qdev_init_nofail(dev
);
1020 sysbus_mmio_map(s
, 0, MP_AUDIO_BASE
);
1021 sysbus_connect_irq(s
, 0, pic
[MP_AUDIO_IRQ
]);
1024 tt_binfo
.ram_size
= ram_size
;
1025 tt_binfo
.kernel_filename
= machine
->kernel_filename
;
1026 tt_binfo
.kernel_cmdline
= machine
->kernel_cmdline
;
1027 tt_binfo
.initrd_filename
= machine
->initrd_filename
;
1028 if (machine
->kernel_filename
!= NULL
) {
1029 /* TODO: load ttsystem. */
1030 //~ sect_size = 0x11b778, sect_addr = 0x31700000
1031 //~ sect_size = 0x6a3f45, sect_addr = 0x31000000
1032 arm_load_kernel(cpu
, machine
, &tt_binfo
);
1036 static void tt_init_go(MachineState
*machine
)
1038 tt_binfo
.board_id
= 0x25d;
1039 ram_size
= 64 * MiB
;
1043 static void tt_init_666(MachineState
*machine
)
1045 tt_binfo
.board_id
= 0x666;
1049 static void tt_init_smdk2443(MachineState
*machine
)
1051 tt_binfo
.board_id
= 0x43c;
1055 static void tt_machine_init(MachineClass
*mc
)
1057 mc
->desc
= "OpenTom (ARM920-T)";
1058 mc
->init
= tt_init_go
;
1061 DEFINE_MACHINE("tt", tt_machine_init
)
1063 static void tt_machine_666_init(MachineClass
*mc
)
1065 mc
->desc
= "OpenTom (ARM920-T)";
1066 mc
->init
= tt_init_666
;
1069 DEFINE_MACHINE("tt666", tt_machine_666_init
)
1071 static void tt_machine_smdk2443_init(MachineClass
*mc
)
1073 mc
->desc
= "smdk2443 (ARM920-T)";
1074 mc
->init
= tt_init_smdk2443
;
1077 DEFINE_MACHINE("smdk2443", tt_machine_smdk2443_init
)
1079 static void tt_register_types(void)
1081 type_register_static(&tt_lcd_info
);
1082 type_register_static(&tt_gpio_info
);
1083 type_register_static(&tt_key_info
);
1086 type_init(tt_register_types
)