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 void tt_lcd_realize(DeviceState
*dev
, Error
**errp
)
311 tt_lcd_state
*s
= TT_LCD(dev
);
312 SysBusDevice
*sbd
= SYS_BUS_DEVICE(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);
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
);
346 //~ dc->props = dp8381x_properties;
347 dc
->realize
= tt_lcd_realize
;
348 //~ dc->reset = qdev_dp8381x_reset;
349 dc
->vmsd
= &tt_lcd_vmsd
;
352 static const TypeInfo tt_lcd_info
= {
354 .parent
= TYPE_SYS_BUS_DEVICE
,
355 .instance_size
= sizeof(tt_lcd_state
),
356 .class_init
= tt_lcd_class_init
,
359 /******************************************************************************/
361 #define S3C2443_MPLLCON 0x10
362 #define S3C2443_CLKDIV0 0x24
364 /******************************************************************************/
366 /* SYSCON register offsets. */
367 #define SYSCON_MPLLCON 0x10
368 #define SYSCON_CLKDIV0 0x24
371 static const OffsetNamePair tt_syscon_names
[] = {
375 static uint64_t tt_syscon_read(void *opaque
, hwaddr offset
,
379 logout("%s\n", offset2name(tt_syscon_names
, offset
));
389 static void tt_syscon_write(void *opaque
, hwaddr offset
,
390 uint64_t value
, unsigned size
)
392 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_syscon_names
, offset
), value
);
399 static const MemoryRegionOps tt_syscon_ops
= {
400 .read
= tt_syscon_read
,
401 .write
= tt_syscon_write
,
402 .endianness
= DEVICE_NATIVE_ENDIAN
,
404 .min_access_size
= 4,
410 /******************************************************************************/
412 /* I/O port register offsets. */
413 #define IOPORT_GPBCON 0x10
414 #define IOPORT_GPBDAT 0x14
415 #define IOPORT_GPBUDP 0x18
416 #define IOPORT_EXTINT0 0x88
417 #define IOPORT_EXTINT1 0x8c
418 #define IOPORT_EXTINT2 0x90
419 #define IOPORT_GSTATUS1 0xb0
422 tt_ioport_write: 0x00000010
423 tt_ioport_write: 0x00000018
424 tt_ioport_write: 0x00000010
425 tt_ioport_write: 0x00000018
429 static const OffsetNamePair tt_ioport_names
[] = {
433 static uint64_t tt_ioport_read(void *opaque
, hwaddr offset
,
437 logout("%s\n", offset2name(tt_ioport_names
, offset
));
448 //~ case IOPORT_EXTINT0:
449 //~ case IOPORT_EXTINT1:
450 //~ case IOPORT_EXTINT2:
451 case IOPORT_GSTATUS1
:
460 static void tt_ioport_write(void *opaque
, hwaddr offset
,
461 uint64_t value
, unsigned size
)
463 logout("%s 0x%08" PRIx64
"\n", offset2name(tt_ioport_names
, offset
), value
);
468 //~ case IOPORT_GPBDAT:
481 //~ case IOPORT_GSTATUS1:
487 static const MemoryRegionOps tt_ioport_ops
= {
488 .read
= tt_ioport_read
,
489 .write
= tt_ioport_write
,
490 .endianness
= DEVICE_NATIVE_ENDIAN
,
492 .min_access_size
= 4,
498 /******************************************************************************/
501 static void tt_syscon_init(void)
503 memory_region_init_io(&s
->syscon
, OBJECT(s
), &tt_syscon_ops
, s
,
504 "tt-syscon", 0x10000);
505 memory_region_add_subregion(get_system_memory(), S3C2443X_SYSCON
, &s
->syscon
);
508 static void tt_ioport_init(void)
510 memory_region_init_io(&s
->ioport
, OBJECT(s
), &tt_ioport_ops
, s
,
511 "tt-ioport", 0x10000);
512 memory_region_add_subregion(get_system_memory(), S3C2443X_IO_PORT
, &s
->ioport
);
516 /* GPIO register offsets */
517 #define MP_GPIO_OE_LO 0x008
518 #define MP_GPIO_OUT_LO 0x00c
519 #define MP_GPIO_IN_LO 0x010
520 #define MP_GPIO_IER_LO 0x014
521 #define MP_GPIO_IMR_LO 0x018
522 #define MP_GPIO_ISR_LO 0x020
523 #define MP_GPIO_OE_HI 0x508
524 #define MP_GPIO_OUT_HI 0x50c
525 #define MP_GPIO_IN_HI 0x510
526 #define MP_GPIO_IER_HI 0x514
527 #define MP_GPIO_IMR_HI 0x518
528 #define MP_GPIO_ISR_HI 0x520
530 /* GPIO bits & masks */
531 #define MP_GPIO_LCD_BRIGHTNESS 0x00070000
532 #define MP_GPIO_I2C_DATA_BIT 29
533 #define MP_GPIO_I2C_CLOCK_BIT 30
535 /* LCD brightness bits in GPIO_OE_HI */
536 #define MP_OE_LCD_BRIGHTNESS 0x0007
538 #define TYPE_TT_GPIO "tt_gpio"
539 #define TT_GPIO(obj) \
540 OBJECT_CHECK(tt_gpio_state, (obj), TYPE_TT_GPIO)
545 uint32_t lcd_brightness
;
552 qemu_irq out
[5]; /* 3 brightness out + 2 lcd (data and clock ) */
555 static void tt_gpio_brightness_update(tt_gpio_state
*s
) {
559 /* compute brightness ratio */
560 switch (s
->lcd_brightness
) {
594 /* set lcd brightness GPIOs */
595 for (i
= 0; i
<= 2; i
++) {
596 qemu_set_irq(s
->out
[i
], (brightness
>> i
) & 1);
600 static void tt_gpio_pin_event(void *opaque
, int pin
, int level
)
602 tt_gpio_state
*s
= opaque
;
603 uint32_t mask
= 1 << pin
;
604 uint32_t delta
= level
<< pin
;
605 uint32_t old
= s
->in_state
& mask
;
607 s
->in_state
&= ~mask
;
608 s
->in_state
|= delta
;
611 ((level
&& (s
->imr
& mask
)) || (!level
&& (s
->ier
& mask
)))) {
613 qemu_irq_raise(s
->irq
);
617 static uint64_t tt_gpio_read(void *opaque
, hwaddr offset
,
620 tt_gpio_state
*s
= opaque
;
623 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
624 return s
->lcd_brightness
& MP_OE_LCD_BRIGHTNESS
;
627 return s
->out_state
& 0xFFFF;
629 return s
->out_state
>> 16;
632 return s
->in_state
& 0xFFFF;
634 return s
->in_state
>> 16;
637 return s
->ier
& 0xFFFF;
642 return s
->imr
& 0xFFFF;
647 return s
->isr
& 0xFFFF;
656 static void tt_gpio_write(void *opaque
, hwaddr offset
,
657 uint64_t value
, unsigned size
)
659 tt_gpio_state
*s
= opaque
;
661 case MP_GPIO_OE_HI
: /* used for LCD brightness control */
662 s
->lcd_brightness
= (s
->lcd_brightness
& MP_GPIO_LCD_BRIGHTNESS
) |
663 (value
& MP_OE_LCD_BRIGHTNESS
);
664 tt_gpio_brightness_update(s
);
668 s
->out_state
= (s
->out_state
& 0xFFFF0000) | (value
& 0xFFFF);
671 s
->out_state
= (s
->out_state
& 0xFFFF) | (value
<< 16);
672 s
->lcd_brightness
= (s
->lcd_brightness
& 0xFFFF) |
673 (s
->out_state
& MP_GPIO_LCD_BRIGHTNESS
);
674 tt_gpio_brightness_update(s
);
675 qemu_set_irq(s
->out
[3], (s
->out_state
>> MP_GPIO_I2C_DATA_BIT
) & 1);
676 qemu_set_irq(s
->out
[4], (s
->out_state
>> MP_GPIO_I2C_CLOCK_BIT
) & 1);
680 s
->ier
= (s
->ier
& 0xFFFF0000) | (value
& 0xFFFF);
683 s
->ier
= (s
->ier
& 0xFFFF) | (value
<< 16);
687 s
->imr
= (s
->imr
& 0xFFFF0000) | (value
& 0xFFFF);
690 s
->imr
= (s
->imr
& 0xFFFF) | (value
<< 16);
695 static const MemoryRegionOps tt_gpio_ops
= {
696 .read
= tt_gpio_read
,
697 .write
= tt_gpio_write
,
698 .endianness
= DEVICE_NATIVE_ENDIAN
,
700 .min_access_size
= 4,
705 static void tt_gpio_reset(DeviceState
*d
)
707 tt_gpio_state
*s
= TT_GPIO(d
);
709 s
->lcd_brightness
= 0;
711 s
->in_state
= 0xffffffff;
717 static void tt_gpio_realize(DeviceState
*dev
, Error
**errp
)
719 tt_gpio_state
*s
= TT_GPIO(dev
);
720 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
722 sysbus_init_irq(sbd
, &s
->irq
);
724 memory_region_init_io(&s
->mmio
, OBJECT(s
), &tt_gpio_ops
, s
,
725 "tt-gpio", MP_GPIO_SIZE
);
726 sysbus_init_mmio(sbd
, &s
->mmio
);
728 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
730 qdev_init_gpio_in(dev
, tt_gpio_pin_event
, 32);
733 static const VMStateDescription tt_gpio_vmsd
= {
734 .name
= TYPE_TT_GPIO
,
736 .minimum_version_id
= 1,
737 .minimum_version_id_old
= 1,
738 .fields
= (VMStateField
[]) {
739 VMSTATE_UINT32(lcd_brightness
, tt_gpio_state
),
740 VMSTATE_UINT32(out_state
, tt_gpio_state
),
741 VMSTATE_UINT32(in_state
, tt_gpio_state
),
742 VMSTATE_UINT32(ier
, tt_gpio_state
),
743 VMSTATE_UINT32(imr
, tt_gpio_state
),
744 VMSTATE_UINT32(isr
, tt_gpio_state
),
745 VMSTATE_END_OF_LIST()
749 static void tt_gpio_class_init(ObjectClass
*klass
, void *data
)
751 DeviceClass
*dc
= DEVICE_CLASS(klass
);
752 dc
->realize
= tt_gpio_realize
;
753 dc
->reset
= tt_gpio_reset
;
754 dc
->vmsd
= &tt_gpio_vmsd
;
757 static const TypeInfo tt_gpio_info
= {
758 .name
= TYPE_TT_GPIO
,
759 .parent
= TYPE_SYS_BUS_DEVICE
,
760 .instance_size
= sizeof(tt_gpio_state
),
761 .class_init
= tt_gpio_class_init
,
764 /* Keyboard codes & masks */
765 #define KEY_RELEASED 0x80
766 #define KEY_CODE 0x7f
768 #define KEYCODE_TAB 0x0f
769 #define KEYCODE_ENTER 0x1c
770 #define KEYCODE_F 0x21
771 #define KEYCODE_M 0x32
773 #define KEYCODE_EXTENDED 0xe0
774 #define KEYCODE_UP 0x48
775 #define KEYCODE_DOWN 0x50
776 #define KEYCODE_LEFT 0x4b
777 #define KEYCODE_RIGHT 0x4d
779 #define MP_KEY_WHEEL_VOL (1 << 0)
780 #define MP_KEY_WHEEL_VOL_INV (1 << 1)
781 #define MP_KEY_WHEEL_NAV (1 << 2)
782 #define MP_KEY_WHEEL_NAV_INV (1 << 3)
783 #define MP_KEY_BTN_FAVORITS (1 << 4)
784 #define MP_KEY_BTN_MENU (1 << 5)
785 #define MP_KEY_BTN_VOLUME (1 << 6)
786 #define MP_KEY_BTN_NAVIGATION (1 << 7)
788 #define TYPE_TT_KEY "tt_key"
789 #define TT_KEY(obj) \
790 OBJECT_CHECK(tt_key_state, (obj), TYPE_TT_KEY)
795 uint32_t kbd_extended
;
796 uint32_t pressed_keys
;
800 static void tt_key_event(void *opaque
, int keycode
)
802 tt_key_state
*s
= opaque
;
806 if (keycode
== KEYCODE_EXTENDED
) {
811 if (s
->kbd_extended
) {
812 switch (keycode
& KEY_CODE
) {
814 event
= MP_KEY_WHEEL_NAV
| MP_KEY_WHEEL_NAV_INV
;
818 event
= MP_KEY_WHEEL_NAV
;
822 event
= MP_KEY_WHEEL_VOL
| MP_KEY_WHEEL_VOL_INV
;
826 event
= MP_KEY_WHEEL_VOL
;
830 switch (keycode
& KEY_CODE
) {
832 event
= MP_KEY_BTN_FAVORITS
;
836 event
= MP_KEY_BTN_VOLUME
;
840 event
= MP_KEY_BTN_NAVIGATION
;
844 event
= MP_KEY_BTN_MENU
;
847 /* Do not repeat already pressed buttons */
848 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
854 /* Raise GPIO pin first if repeating a key */
855 if (!(keycode
& KEY_RELEASED
) && (s
->pressed_keys
& event
)) {
856 for (i
= 0; i
<= 7; i
++) {
857 if (event
& (1 << i
)) {
858 qemu_set_irq(s
->out
[i
], 1);
862 for (i
= 0; i
<= 7; i
++) {
863 if (event
& (1 << i
)) {
864 qemu_set_irq(s
->out
[i
], !!(keycode
& KEY_RELEASED
));
867 if (keycode
& KEY_RELEASED
) {
868 s
->pressed_keys
&= ~event
;
870 s
->pressed_keys
|= event
;
877 static void tt_key_realize(DeviceState
*dev
, Error
**errp
)
879 tt_key_state
*s
= TT_KEY(dev
);
880 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
882 sysbus_init_mmio(sbd
, &s
->mmio
);
887 qdev_init_gpio_out(dev
, s
->out
, ARRAY_SIZE(s
->out
));
889 qemu_add_kbd_event_handler(tt_key_event
, s
);
892 static const VMStateDescription tt_key_vmsd
= {
895 .minimum_version_id
= 1,
896 .minimum_version_id_old
= 1,
897 .fields
= (VMStateField
[]) {
898 VMSTATE_UINT32(kbd_extended
, tt_key_state
),
899 VMSTATE_UINT32(pressed_keys
, tt_key_state
),
900 VMSTATE_END_OF_LIST()
904 static void tt_key_class_init(ObjectClass
*klass
, void *data
)
906 DeviceClass
*dc
= DEVICE_CLASS(klass
);
907 dc
->realize
= tt_key_realize
;
908 dc
->vmsd
= &tt_key_vmsd
;
911 static const TypeInfo tt_key_info
= {
913 .parent
= TYPE_SYS_BUS_DEVICE
,
914 .instance_size
= sizeof(tt_key_state
),
915 .class_init
= tt_key_class_init
,
918 static struct arm_boot_info tt_binfo
= {
922 .loader_start
= TT_SRAM_BASE
,
926 .atag_revision
= 0x0004000a,
929 static void tt_init(MachineState
*machine
)
936 DeviceState
*i2c_dev
;
937 DeviceState
*lcd_dev
;
938 DeviceState
*key_dev
;
939 DeviceState
*wm8750_dev
;
942 unsigned long flash_size
;
950 if (machine
->cpu_model
&& strcmp(machine
->cpu_model
, "arm920t")) {
951 fprintf(stderr
, "only working with cpu arm920t\n");
956 /* Allocate storage for board state. */
957 s
= g_new0(TTState
, 1);
959 for (i
= 0; i
< serial_max_hds(); i
++) {
962 assert(serial_hd(i
));
964 /* TODO: This code no longer works. Remove or replace. */
965 if (serial_hd(i
) == NULL
) {
967 snprintf(name
, sizeof(name
), "serial%u", i
);
968 serial_hd(i
) = qemu_chr_new(name
, "vc:80Cx24C");
973 /* Initialise SOC. */
974 s
->soc
= s3c2440_init(ram_size
);
978 //~ ram_off = qemu_ram_alloc(NULL, "arm920.ram", ram_size);
979 //~ cpu_register_physical_memory(0x00000000, ram_size, ram_off | IO_MEM_RAM);
980 //~ cpu_register_physical_memory(0x30000000, ram_size, ram_off | IO_MEM_RAM);
981 //~ cpu_register_physical_memory(0x80000000, ram_size, ram_off | IO_MEM_RAM);
982 //~ cpu_register_physical_memory(0xc0000000, ram_size, ram_off | IO_MEM_RAM);
984 //~ tt_syscon_init();
985 //~ tt_ioport_init();
988 dev
= sysbus_create_simple(TYPE_TT_GPIO
, MP_GPIO_BASE
, pic
[MP_GPIO_IRQ
]);
989 i2c_dev
= sysbus_create_simple("gpio_i2c", 0, NULL
);
990 i2c
= (I2CBus
*)qdev_get_child_bus(i2c_dev
, "i2c");
992 lcd_dev
= sysbus_create_simple(TYPE_TT_LCD
, MP_LCD_BASE
, NULL
);
993 key_dev
= sysbus_create_simple(TYPE_TT_KEY
, 0, NULL
);
996 qdev_connect_gpio_out(i2c_dev
, 0,
997 qdev_get_gpio_in(dev
, MP_GPIO_I2C_DATA_BIT
));
999 qdev_connect_gpio_out(dev
, 3, qdev_get_gpio_in(i2c_dev
, 0));
1001 qdev_connect_gpio_out(dev
, 4, qdev_get_gpio_in(i2c_dev
, 1));
1003 for (i
= 0; i
< 3; i
++) {
1004 qdev_connect_gpio_out(dev
, i
, qdev_get_gpio_in(lcd_dev
, i
));
1006 for (i
= 0; i
< 4; i
++) {
1007 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 8));
1009 for (i
= 4; i
< 8; i
++) {
1010 qdev_connect_gpio_out(key_dev
, i
, qdev_get_gpio_in(dev
, i
+ 15));
1013 wm8750_dev
= i2c_create_slave(i2c
, "wm8750", MP_WM_ADDR
);
1014 dev
= qdev_create(NULL
, "mv88w8618_audio");
1015 s
= SYS_BUS_DEVICE(dev
);
1016 qdev_prop_set_ptr(dev
, "wm8750", wm8750_dev
);
1017 qdev_init_nofail(dev
);
1018 sysbus_mmio_map(s
, 0, MP_AUDIO_BASE
);
1019 sysbus_connect_irq(s
, 0, pic
[MP_AUDIO_IRQ
]);
1022 tt_binfo
.ram_size
= ram_size
;
1023 tt_binfo
.kernel_filename
= machine
->kernel_filename
;
1024 tt_binfo
.kernel_cmdline
= machine
->kernel_cmdline
;
1025 tt_binfo
.initrd_filename
= machine
->initrd_filename
;
1026 if (machine
->kernel_filename
!= NULL
) {
1027 /* TODO: load ttsystem. */
1028 //~ sect_size = 0x11b778, sect_addr = 0x31700000
1029 //~ sect_size = 0x6a3f45, sect_addr = 0x31000000
1030 arm_load_kernel(cpu
, &tt_binfo
);
1034 static void tt_init_go(MachineState
*machine
)
1036 tt_binfo
.board_id
= 0x25d;
1037 ram_size
= 64 * MiB
;
1041 static void tt_init_666(MachineState
*machine
)
1043 tt_binfo
.board_id
= 0x666;
1047 static void tt_init_smdk2443(MachineState
*machine
)
1049 tt_binfo
.board_id
= 0x43c;
1053 static void tt_machine_init(MachineClass
*mc
)
1055 mc
->desc
= "OpenTom (ARM920-T)";
1056 mc
->init
= tt_init_go
;
1059 DEFINE_MACHINE("tt", tt_machine_init
)
1061 static void tt_machine_666_init(MachineClass
*mc
)
1063 mc
->desc
= "OpenTom (ARM920-T)";
1064 mc
->init
= tt_init_666
;
1067 DEFINE_MACHINE("tt666", tt_machine_666_init
)
1069 static void tt_machine_smdk2443_init(MachineClass
*mc
)
1071 mc
->desc
= "smdk2443 (ARM920-T)";
1072 mc
->init
= tt_init_smdk2443
;
1075 DEFINE_MACHINE("smdk2443", tt_machine_smdk2443_init
)
1077 static void tt_register_types(void)
1079 type_register_static(&tt_lcd_info
);
1080 type_register_static(&tt_gpio_info
);
1081 type_register_static(&tt_key_info
);
1084 type_init(tt_register_types
)