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__)
40 Base Address of Special Registers
66 0x48000000 Module SDRAM
70 #define S3C2443X_SYSCON 0x4c000000
71 #define S3C2443X_IO_PORT 0x56000000
83 static const char *offset2name(const OffsetNamePair
*o2n
, unsigned offset
)
85 static char buffer
[12];
86 const char *name
= buffer
;
87 snprintf(buffer
, sizeof(buffer
), "0x%08x", offset
);
88 for (; o2n
->name
; o2n
++) {
89 if (offset
== o2n
->offset
) {
98 #define MP_MISC_BASE 0x80002000
99 #define MP_MISC_SIZE 0x00001000
101 #define MP_GPIO_BASE 0x8000D000
102 #define MP_GPIO_SIZE 0x00001000
104 #define MP_AUDIO_BASE 0x90007000
106 #define MP_LCD_BASE 0x9000c000
107 #define MP_LCD_SIZE 0x00001000
109 #define TT_SRAM_BASE 0xC0000000
110 #define TT_SRAM_SIZE 0x00020000
112 #define MP_RAM_DEFAULT_SIZE (64 * MiB)
114 #define MP_TIMER1_IRQ 4
115 #define MP_TIMER2_IRQ 5
116 #define MP_TIMER3_IRQ 6
117 #define MP_TIMER4_IRQ 7
118 #define MP_EHCI_IRQ 8
120 #define MP_GPIO_IRQ 12
121 #define MP_RTC_IRQ 28
122 #define MP_AUDIO_IRQ 30
124 /* Wolfson 8750 I2C address */
125 #define MP_WM_ADDR 0x1A
127 /* LCD register offsets */
128 #define MP_LCD_IRQCTRL 0x180
129 #define MP_LCD_IRQSTAT 0x184
130 #define MP_LCD_SPICTRL 0x1ac
131 #define MP_LCD_INST 0x1bc
132 #define MP_LCD_DATA 0x1c0
135 #define MP_LCD_SPI_DATA 0x00100011
136 #define MP_LCD_SPI_CMD 0x00104011
137 #define MP_LCD_SPI_INVALID 0x00000000
140 #define MP_LCD_INST_SETPAGE0 0xB0
142 #define MP_LCD_INST_SETPAGE7 0xB7
144 #define MP_LCD_TEXTCOLOR 0xe0e0ff /* RRGGBB */
146 #define TYPE_TT_LCD "tt_lcd"
147 #define TT_LCD(obj) OBJECT_CHECK(tt_lcd_state, (obj), TYPE_TT_LCD)
158 uint8_t video_ram
[128*64/8];
161 static uint8_t scale_lcd_color(tt_lcd_state
*s
, uint8_t col
)
163 switch (s
->brightness
) {
169 return (col
* s
->brightness
) / 7;
173 #define SET_LCD_PIXEL(depth, type) \
174 static inline void glue(set_lcd_pixel, depth) \
175 (tt_lcd_state *s, int x, int y, type col) \
178 DisplaySurface *surface = qemu_console_surface(s->con); \
179 type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
181 for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
182 for (dx = 0; dx < 3; dx++, pixel++) \
185 SET_LCD_PIXEL(8, uint8_t)
186 SET_LCD_PIXEL(16, uint16_t)
187 SET_LCD_PIXEL(32, uint32_t)
189 #include "ui/pixel_ops.h"
191 static void lcd_refresh(void *opaque
)
193 tt_lcd_state
*s
= opaque
;
194 DisplaySurface
*surface
= qemu_console_surface(s
->con
);
197 switch (surface_bits_per_pixel(surface
)) {
200 #define LCD_REFRESH(depth, func) \
202 col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
203 scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
204 scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
205 for (x = 0; x < 128; x++) { \
206 for (y = 0; y < 64; y++) { \
207 if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
208 glue(set_lcd_pixel, depth)(s, x, y, col); \
210 glue(set_lcd_pixel, depth)(s, x, y, 0); \
215 LCD_REFRESH(8, rgb_to_pixel8
)
216 LCD_REFRESH(16, rgb_to_pixel16
)
217 LCD_REFRESH(32, (is_surface_bgr(surface
) ?
218 rgb_to_pixel32bgr
: rgb_to_pixel32
))
220 hw_error("unsupported colour depth %i\n",
221 surface_bits_per_pixel(surface
));
224 dpy_gfx_update(s
->con
, 0, 0, 128*3, 64*3);
227 static void lcd_invalidate(void *opaque
)
231 static void tt_lcd_gpio_brigthness_in(void *opaque
, int irq
, int level
)
233 tt_lcd_state
*s
= opaque
;
234 s
->brightness
&= ~(1 << irq
);
235 s
->brightness
|= level
<< irq
;
238 static uint64_t tt_lcd_read(void *opaque
, hwaddr offset
,
241 tt_lcd_state
*s
= opaque
;
252 static void tt_lcd_write(void *opaque
, hwaddr offset
,
253 uint64_t value
, unsigned size
)
255 tt_lcd_state
*s
= opaque
;
263 if (value
== MP_LCD_SPI_DATA
|| value
== MP_LCD_SPI_CMD
) {
266 s
->mode
= MP_LCD_SPI_INVALID
;
271 if (value
>= MP_LCD_INST_SETPAGE0
&& value
<= MP_LCD_INST_SETPAGE7
) {
272 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
278 if (s
->mode
== MP_LCD_SPI_CMD
) {
279 if (value
>= MP_LCD_INST_SETPAGE0
&&
280 value
<= MP_LCD_INST_SETPAGE7
) {
281 s
->page
= value
- MP_LCD_INST_SETPAGE0
;
284 } else if (s
->mode
== MP_LCD_SPI_DATA
) {
285 s
->video_ram
[s
->page
*128 + s
->page_off
] = value
;
286 s
->page_off
= (s
->page_off
+ 1) & 127;
292 static const MemoryRegionOps tt_lcd_ops
= {
294 .write
= tt_lcd_write
,
295 .endianness
= DEVICE_NATIVE_ENDIAN
,
297 .min_access_size
= 4,
302 static const GraphicHwOps tt_gfx_ops
= {
303 .invalidate
= lcd_invalidate
,
304 .gfx_update
= lcd_refresh
,
307 static int tt_lcd_init(SysBusDevice
*sbd
)
309 DeviceState
*dev
= DEVICE(sbd
);
310 tt_lcd_state
*s
= TT_LCD(dev
);
314 memory_region_init_io(&s
->mmio
, OBJECT(s
),
315 &tt_lcd_ops
, s
, "tt-lcd", MP_LCD_SIZE
);
316 sysbus_init_mmio(sbd
, &s
->mmio
);
318 s
->con
= graphic_console_init(DEVICE(dev
), 0, &tt_gfx_ops
, s
);
319 qemu_console_resize(s
->con
, 128*3, 64*3);
321 qdev_init_gpio_in(dev
, tt_lcd_gpio_brigthness_in
, 3);
326 static const VMStateDescription tt_lcd_vmsd
= {
329 .minimum_version_id
= 1,
330 .minimum_version_id_old
= 1,
331 .fields
= (VMStateField
[]) {
332 VMSTATE_UINT32(brightness
, tt_lcd_state
),
333 VMSTATE_UINT32(mode
, tt_lcd_state
),
334 VMSTATE_UINT32(irqctrl
, tt_lcd_state
),
335 VMSTATE_UINT32(page
, tt_lcd_state
),
336 VMSTATE_UINT32(page_off
, tt_lcd_state
),
337 VMSTATE_BUFFER(video_ram
, tt_lcd_state
),
338 VMSTATE_END_OF_LIST()
342 static void tt_lcd_class_init(ObjectClass
*klass
, void *data
)
344 DeviceClass
*dc
= DEVICE_CLASS(klass
);
345 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
347 //~ dc->props = dp8381x_properties;
348 //~ dc->reset = qdev_dp8381x_reset;
349 dc
->vmsd
= &tt_lcd_vmsd
;
350 k
->init
= tt_lcd_init
;
353 static const TypeInfo tt_lcd_info
= {
355 .parent
= TYPE_SYS_BUS_DEVICE
,
356 .instance_size
= sizeof(tt_lcd_state
),
357 .class_init
= tt_lcd_class_init
,
360 /******************************************************************************/
362 #define S3C2443_MPLLCON 0x10
363 #define S3C2443_CLKDIV0 0x24
365 /******************************************************************************/
367 /* SYSCON register offsets. */
368 #define SYSCON_MPLLCON 0x10
369 #define SYSCON_CLKDIV0 0x24
372 static const OffsetNamePair tt_syscon_names
[] = {
376 static uint64_t tt_syscon_read(void *opaque
, hwaddr offset
,
380 logout("%s\n", offset2name(tt_syscon_names
, offset
));
390 static void tt_syscon_write(void *opaque
, hwaddr offset
,
391 uint64_t value
, unsigned size
)
393 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_syscon_names
, offset
), value
);
400 static const MemoryRegionOps tt_syscon_ops
= {
401 .read
= tt_syscon_read
,
402 .write
= tt_syscon_write
,
403 .endianness
= DEVICE_NATIVE_ENDIAN
,
405 .min_access_size
= 4,
411 /******************************************************************************/
413 /* I/O port register offsets. */
414 #define IOPORT_GPBCON 0x10
415 #define IOPORT_GPBDAT 0x14
416 #define IOPORT_GPBUDP 0x18
417 #define IOPORT_EXTINT0 0x88
418 #define IOPORT_EXTINT1 0x8c
419 #define IOPORT_EXTINT2 0x90
420 #define IOPORT_GSTATUS1 0xb0
423 tt_ioport_write: 0x00000010
424 tt_ioport_write: 0x00000018
425 tt_ioport_write: 0x00000010
426 tt_ioport_write: 0x00000018
430 static const OffsetNamePair tt_ioport_names
[] = {
434 static uint64_t tt_ioport_read(void *opaque
, hwaddr offset
,
438 logout("%s\n", offset2name(tt_ioport_names
, offset
));
449 //~ case IOPORT_EXTINT0:
450 //~ case IOPORT_EXTINT1:
451 //~ case IOPORT_EXTINT2:
452 case IOPORT_GSTATUS1
:
461 static void tt_ioport_write(void *opaque
, hwaddr offset
,
462 uint64_t value
, unsigned size
)
464 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_ioport_names
, offset
), value
);
469 //~ case IOPORT_GPBDAT:
482 //~ case IOPORT_GSTATUS1:
488 static const MemoryRegionOps tt_ioport_ops
= {
489 .read
= tt_ioport_read
,
490 .write
= tt_ioport_write
,
491 .endianness
= DEVICE_NATIVE_ENDIAN
,
493 .min_access_size
= 4,
499 /******************************************************************************/
502 static void tt_syscon_init(void)
504 memory_region_init_io(&s
->syscon
, OBJECT(s
), &tt_syscon_ops
, s
,
505 "tt-syscon", 0x10000);
506 memory_region_add_subregion(get_system_memory(), S3C2443X_SYSCON
, &s
->syscon
);
509 static void tt_ioport_init(void)
511 memory_region_init_io(&s
->ioport
, OBJECT(s
), &tt_ioport_ops
, s
,
512 "tt-ioport", 0x10000);
513 memory_region_add_subregion(get_system_memory(), S3C2443X_IO_PORT
, &s
->ioport
);
517 /* GPIO register offsets */
518 #define MP_GPIO_OE_LO 0x008
519 #define MP_GPIO_OUT_LO 0x00c
520 #define MP_GPIO_IN_LO 0x010
521 #define MP_GPIO_IER_LO 0x014
522 #define MP_GPIO_IMR_LO 0x018
523 #define MP_GPIO_ISR_LO 0x020
524 #define MP_GPIO_OE_HI 0x508
525 #define MP_GPIO_OUT_HI 0x50c
526 #define MP_GPIO_IN_HI 0x510
527 #define MP_GPIO_IER_HI 0x514
528 #define MP_GPIO_IMR_HI 0x518
529 #define MP_GPIO_ISR_HI 0x520
531 /* GPIO bits & masks */
532 #define MP_GPIO_LCD_BRIGHTNESS 0x00070000
533 #define MP_GPIO_I2C_DATA_BIT 29
534 #define MP_GPIO_I2C_CLOCK_BIT 30
536 /* LCD brightness bits in GPIO_OE_HI */
537 #define MP_OE_LCD_BRIGHTNESS 0x0007
539 #define TYPE_TT_GPIO "tt_gpio"
540 #define TT_GPIO(obj) \
541 OBJECT_CHECK(tt_gpio_state, (obj), TYPE_TT_GPIO)
546 uint32_t lcd_brightness
;
553 qemu_irq out
[5]; /* 3 brightness out + 2 lcd (data and clock ) */
556 static void tt_gpio_brightness_update(tt_gpio_state
*s
) {
560 /* compute brightness ratio */
561 switch (s
->lcd_brightness
) {
595 /* set lcd brightness GPIOs */
596 for (i
= 0; i
<= 2; i
++) {
597 qemu_set_irq(s
->out
[i
], (brightness
>> i
) & 1);
601 static void tt_gpio_pin_event(void *opaque
, int pin
, int level
)
603 tt_gpio_state
*s
= opaque
;
604 uint32_t mask
= 1 << pin
;
605 uint32_t delta
= level
<< pin
;
606 uint32_t old
= s
->in_state
& mask
;
608 s
->in_state
&= ~mask
;
609 s
->in_state
|= delta
;
612 ((level
&& (s
->imr
& mask
)) || (!level
&& (s
->ier
& mask
)))) {
614 qemu_irq_raise(s
->irq
);
618 static uint64_t tt_gpio_read(void *opaque
, hwaddr offset
,
621 tt_gpio_state
*s
= opaque
;
624 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
625 return s
->lcd_brightness
& MP_OE_LCD_BRIGHTNESS
;
628 return s
->out_state
& 0xFFFF;
630 return s
->out_state
>> 16;
633 return s
->in_state
& 0xFFFF;
635 return s
->in_state
>> 16;
638 return s
->ier
& 0xFFFF;
643 return s
->imr
& 0xFFFF;
648 return s
->isr
& 0xFFFF;
657 static void tt_gpio_write(void *opaque
, hwaddr offset
,
658 uint64_t value
, unsigned size
)
660 tt_gpio_state
*s
= opaque
;
662 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
663 s
->lcd_brightness
= (s
->lcd_brightness
& MP_GPIO_LCD_BRIGHTNESS
) |
664 (value
& MP_OE_LCD_BRIGHTNESS
);
665 tt_gpio_brightness_update(s
);
669 s
->out_state
= (s
->out_state
& 0xFFFF0000) | (value
& 0xFFFF);
672 s
->out_state
= (s
->out_state
& 0xFFFF) | (value
<< 16);
673 s
->lcd_brightness
= (s
->lcd_brightness
& 0xFFFF) |
674 (s
->out_state
& MP_GPIO_LCD_BRIGHTNESS
);
675 tt_gpio_brightness_update(s
);
676 qemu_set_irq(s
->out
[3], (s
->out_state
>> MP_GPIO_I2C_DATA_BIT
) & 1);
677 qemu_set_irq(s
->out
[4], (s
->out_state
>> MP_GPIO_I2C_CLOCK_BIT
) & 1);
681 s
->ier
= (s
->ier
& 0xFFFF0000) | (value
& 0xFFFF);
684 s
->ier
= (s
->ier
& 0xFFFF) | (value
<< 16);
688 s
->imr
= (s
->imr
& 0xFFFF0000) | (value
& 0xFFFF);
691 s
->imr
= (s
->imr
& 0xFFFF) | (value
<< 16);
696 static const MemoryRegionOps tt_gpio_ops
= {
697 .read
= tt_gpio_read
,
698 .write
= tt_gpio_write
,
699 .endianness
= DEVICE_NATIVE_ENDIAN
,
701 .min_access_size
= 4,
706 static void tt_gpio_reset(DeviceState
*d
)
708 tt_gpio_state
*s
= TT_GPIO(d
);
710 s
->lcd_brightness
= 0;
712 s
->in_state
= 0xffffffff;
718 static int tt_gpio_init(SysBusDevice
*sbd
)
720 DeviceState
*dev
= DEVICE(sbd
);
721 tt_gpio_state
*s
= TT_GPIO(dev
);
723 sysbus_init_irq(sbd
, &s
->irq
);
725 memory_region_init_io(&s
->mmio
, OBJECT(s
), &tt_gpio_ops
, s
,
726 "tt-gpio", MP_GPIO_SIZE
);
727 sysbus_init_mmio(sbd
, &s
->mmio
);
729 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
731 qdev_init_gpio_in(dev
, tt_gpio_pin_event
, 32);
736 static const VMStateDescription tt_gpio_vmsd
= {
737 .name
= TYPE_TT_GPIO
,
739 .minimum_version_id
= 1,
740 .minimum_version_id_old
= 1,
741 .fields
= (VMStateField
[]) {
742 VMSTATE_UINT32(lcd_brightness
, tt_gpio_state
),
743 VMSTATE_UINT32(out_state
, tt_gpio_state
),
744 VMSTATE_UINT32(in_state
, tt_gpio_state
),
745 VMSTATE_UINT32(ier
, tt_gpio_state
),
746 VMSTATE_UINT32(imr
, tt_gpio_state
),
747 VMSTATE_UINT32(isr
, tt_gpio_state
),
748 VMSTATE_END_OF_LIST()
752 static void tt_gpio_class_init(ObjectClass
*klass
, void *data
)
754 DeviceClass
*dc
= DEVICE_CLASS(klass
);
755 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
756 dc
->reset
= tt_gpio_reset
;
757 dc
->vmsd
= &tt_gpio_vmsd
;
758 k
->init
= tt_gpio_init
;
761 static const TypeInfo tt_gpio_info
= {
762 .name
= TYPE_TT_GPIO
,
763 .parent
= TYPE_SYS_BUS_DEVICE
,
764 .instance_size
= sizeof(tt_gpio_state
),
765 .class_init
= tt_gpio_class_init
,
768 /* Keyboard codes & masks */
769 #define KEY_RELEASED 0x80
770 #define KEY_CODE 0x7f
772 #define KEYCODE_TAB 0x0f
773 #define KEYCODE_ENTER 0x1c
774 #define KEYCODE_F 0x21
775 #define KEYCODE_M 0x32
777 #define KEYCODE_EXTENDED 0xe0
778 #define KEYCODE_UP 0x48
779 #define KEYCODE_DOWN 0x50
780 #define KEYCODE_LEFT 0x4b
781 #define KEYCODE_RIGHT 0x4d
783 #define MP_KEY_WHEEL_VOL (1 << 0)
784 #define MP_KEY_WHEEL_VOL_INV (1 << 1)
785 #define MP_KEY_WHEEL_NAV (1 << 2)
786 #define MP_KEY_WHEEL_NAV_INV (1 << 3)
787 #define MP_KEY_BTN_FAVORITS (1 << 4)
788 #define MP_KEY_BTN_MENU (1 << 5)
789 #define MP_KEY_BTN_VOLUME (1 << 6)
790 #define MP_KEY_BTN_NAVIGATION (1 << 7)
792 #define TYPE_TT_KEY "tt_key"
793 #define TT_KEY(obj) \
794 OBJECT_CHECK(tt_key_state, (obj), TYPE_TT_KEY)
799 uint32_t kbd_extended
;
800 uint32_t pressed_keys
;
804 static void tt_key_event(void *opaque
, int keycode
)
806 tt_key_state
*s
= opaque
;
810 if (keycode
== KEYCODE_EXTENDED
) {
815 if (s
->kbd_extended
) {
816 switch (keycode
& KEY_CODE
) {
818 event
= MP_KEY_WHEEL_NAV
| MP_KEY_WHEEL_NAV_INV
;
822 event
= MP_KEY_WHEEL_NAV
;
826 event
= MP_KEY_WHEEL_VOL
| MP_KEY_WHEEL_VOL_INV
;
830 event
= MP_KEY_WHEEL_VOL
;
834 switch (keycode
& KEY_CODE
) {
836 event
= MP_KEY_BTN_FAVORITS
;
840 event
= MP_KEY_BTN_VOLUME
;
844 event
= MP_KEY_BTN_NAVIGATION
;
848 event
= MP_KEY_BTN_MENU
;
851 /* Do not repeat already pressed buttons */
852 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
858 /* Raise GPIO pin first if repeating a key */
859 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
860 for (i
= 0; i
<= 7; i
++) {
861 if (event
& (1 << i
)) {
862 qemu_set_irq(s
->out
[i
], 1);
866 for (i
= 0; i
<= 7; i
++) {
867 if (event
& (1 << i
)) {
868 qemu_set_irq(s
->out
[i
], !!(keycode
& KEY_RELEASED
));
871 if (keycode
& KEY_RELEASED
) {
872 s
->pressed_keys
&= ~event
;
874 s
->pressed_keys
|= event
;
881 static int tt_key_init(SysBusDevice
*sbd
)
883 DeviceState
*dev
= DEVICE(sbd
);
884 tt_key_state
*s
= TT_KEY(dev
);
886 sysbus_init_mmio(sbd
, &s
->mmio
);
891 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
893 qemu_add_kbd_event_handler(tt_key_event
, s
);
898 static const VMStateDescription tt_key_vmsd
= {
901 .minimum_version_id
= 1,
902 .minimum_version_id_old
= 1,
903 .fields
= (VMStateField
[]) {
904 VMSTATE_UINT32(kbd_extended
, tt_key_state
),
905 VMSTATE_UINT32(pressed_keys
, tt_key_state
),
906 VMSTATE_END_OF_LIST()
910 static void tt_key_class_init(ObjectClass
*klass
, void *data
)
912 DeviceClass
*dc
= DEVICE_CLASS(klass
);
913 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
914 dc
->vmsd
= &tt_key_vmsd
;
915 k
->init
= tt_key_init
;
918 static const TypeInfo tt_key_info
= {
920 .parent
= TYPE_SYS_BUS_DEVICE
,
921 .instance_size
= sizeof(tt_key_state
),
922 .class_init
= tt_key_class_init
,
925 static struct arm_boot_info tt_binfo
= {
929 .loader_start
= TT_SRAM_BASE
,
933 .atag_revision
= 0x0004000a,
936 static void tt_init(MachineState
*machine
)
943 DeviceState
*i2c_dev
;
944 DeviceState
*lcd_dev
;
945 DeviceState
*key_dev
;
946 DeviceState
*wm8750_dev
;
949 unsigned long flash_size
;
956 if (machine
->cpu_model
&& strcmp(machine
->cpu_model
, "arm920t")) {
957 fprintf(stderr
, "only working with cpu arm920t\n");
961 /* Allocate storage for board state. */
962 s
= g_new0(TTState
, 1);
964 for (i
= 0; i
< 3; i
++) {
965 if (serial_hds
[i
] == NULL
) {
967 snprintf(name
, sizeof(name
), "serial%u", i
);
968 serial_hds
[i
] = qemu_chr_new(name
, "vc:80Cx24C");
972 /* Initialise SOC. */
973 s
->soc
= s3c2440_init(ram_size
);
977 //~ ram_off = qemu_ram_alloc(NULL, "arm920.ram", ram_size);
978 //~ cpu_register_physical_memory(0x00000000, ram_size, ram_off | IO_MEM_RAM);
979 //~ cpu_register_physical_memory(0x30000000, ram_size, ram_off | IO_MEM_RAM);
980 //~ cpu_register_physical_memory(0x80000000, ram_size, ram_off | IO_MEM_RAM);
981 //~ cpu_register_physical_memory(0xc0000000, ram_size, ram_off | IO_MEM_RAM);
983 //~ tt_syscon_init();
984 //~ tt_ioport_init();
987 dev
= sysbus_create_simple(TYPE_TT_GPIO
, MP_GPIO_BASE
, pic
[MP_GPIO_IRQ
]);
988 i2c_dev
= sysbus_create_simple("gpio_i2c", 0, NULL
);
989 i2c
= (I2CBus
*)qdev_get_child_bus(i2c_dev
, "i2c");
991 lcd_dev
= sysbus_create_simple(TYPE_TT_LCD
, MP_LCD_BASE
, NULL
);
992 key_dev
= sysbus_create_simple(TYPE_TT_KEY
, 0, NULL
);
995 qdev_connect_gpio_out(i2c_dev
, 0,
996 qdev_get_gpio_in(dev
, MP_GPIO_I2C_DATA_BIT
));
998 qdev_connect_gpio_out(dev
, 3, qdev_get_gpio_in(i2c_dev
, 0));
1000 qdev_connect_gpio_out(dev
, 4, qdev_get_gpio_in(i2c_dev
, 1));
1002 for (i
= 0; i
< 3; i
++) {
1003 qdev_connect_gpio_out(dev
, i
, qdev_get_gpio_in(lcd_dev
, i
));
1005 for (i
= 0; i
< 4; i
++) {
1006 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 8));
1008 for (i
= 4; i
< 8; i
++) {
1009 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 15));
1012 wm8750_dev
= i2c_create_slave(i2c
, "wm8750", MP_WM_ADDR
);
1013 dev
= qdev_create(NULL
, "mv88w8618_audio");
1014 s
= SYS_BUS_DEVICE(dev
);
1015 qdev_prop_set_ptr(dev
, "wm8750", wm8750_dev
);
1016 qdev_init_nofail(dev
);
1017 sysbus_mmio_map(s
, 0, MP_AUDIO_BASE
);
1018 sysbus_connect_irq(s
, 0, pic
[MP_AUDIO_IRQ
]);
1021 tt_binfo
.ram_size
= ram_size
;
1022 tt_binfo
.kernel_filename
= machine
->kernel_filename
;
1023 tt_binfo
.kernel_cmdline
= machine
->kernel_cmdline
;
1024 tt_binfo
.initrd_filename
= machine
->initrd_filename
;
1025 if (machine
->kernel_filename
!= NULL
) {
1026 /* TODO: load ttsystem. */
1027 //~ sect_size = 0x11b778, sect_addr = 0x31700000
1028 //~ sect_size = 0x6a3f45, sect_addr = 0x31000000
1029 arm_load_kernel(cpu
, &tt_binfo
);
1033 static void tt_init_go(MachineState
*machine
)
1035 tt_binfo
.board_id
= 0x25d;
1036 ram_size
= 64 * MiB
;
1040 static void tt_init_666(MachineState
*machine
)
1042 tt_binfo
.board_id
= 0x666;
1046 static void tt_init_smdk2443(MachineState
*machine
)
1048 tt_binfo
.board_id
= 0x43c;
1052 static void tt_machine_init(MachineClass
*mc
)
1054 mc
->desc
= "OpenTom (ARM920-T)";
1055 mc
->init
= tt_init_go
;
1058 DEFINE_MACHINE("tt", tt_machine_init
)
1060 static void tt_machine_666_init(MachineClass
*mc
)
1062 mc
->desc
= "OpenTom (ARM920-T)";
1063 mc
->init
= tt_init_666
;
1066 DEFINE_MACHINE("tt666", tt_machine_666_init
)
1068 static void tt_machine_smdk2443_init(MachineClass
*mc
)
1070 mc
->desc
= "smdk2443 (ARM920-T)";
1071 mc
->init
= tt_init_smdk2443
;
1074 DEFINE_MACHINE("smdk2443", tt_machine_smdk2443_init
)
1076 static void tt_register_types(void)
1078 type_register_static(&tt_lcd_info
);
1079 type_register_static(&tt_gpio_info
);
1080 type_register_static(&tt_key_info
);
1083 type_init(tt_register_types
)