2 * Neo1973 mobile telephone platforms emulation.
3 * Detailed information at openmoko.org.
5 * Copyright (c) 2007 OpenMoko, Inc.
6 * Author: Andrzej Zaborowski <andrew@openedhand.com>
8 * This code is licensed under the GNU GPL v2.
16 #include "qemu-timer.h"
18 #include "audio/audio.h"
25 #include "eeprom24c0x.h"
27 #define mini2440_printf(format, ...) \
28 fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
30 /* Wiring common to all revisions */
31 #define MINI2440_GPIO_BACKLIGHT S3C_GPB(1)
32 #define MINI2440_GPIO_LCD_RESET S3C_GPC(6)
33 #define MINI2440_GPIO_nSD_DETECT S3C_GPG(8)
34 #define MINI2440_IRQ_nSD_DETECT S3C_EINT(16)
35 #define MINI2440_IRQ_DM9000 S3C_EINT(7)
36 #define MINI2440_GPIO_DM9000 S3C_GPF(7)
38 #define MINI2440_GPIO_SDMMC_ON S3C_GPB(2)
39 #define MINI2440_GPIO_USB_PULLUP S3C_GPB(9)
40 #define MINI2440_GPIO_USB_ATTACH S3C_GPB(10)
42 struct mini2440_board_s
{
43 struct s3c_state_s
*cpu
;
48 struct nand_flash_s
*nand
;
52 static void mini2440_gpio_setup(struct mini2440_board_s
*s
)
54 // s3c_gpio_out_set(s->cpu->io, MINI2440_GPIO_BACKLIGHT,
55 // *qemu_allocate_irqs(mini2440_bl_switch, s, 1));
57 // s3c_timers_cmp_handler_set(s->cpu->timers, 0, mini2440_bl_intensity, s);
59 sd_set_cb(s
->mmc
, 0, s3c_gpio_in_get(s
->cpu
->io
)[MINI2440_IRQ_nSD_DETECT
]);
62 static void mini2440_reset(void *opaque
)
64 struct mini2440_board_s
*s
= (struct mini2440_board_s
*) opaque
;
69 * Performs Samsung S3C2440 bootup, but loading 4KB of the nand at the base of the RAM
72 uint8_t * src
= s
->cpu
->nand
->storage
;
73 uint8_t * dst
= phys_ram_base
;
75 for (page
= 0; page
< 4 page
++, src
+= 264, dst
+= 256)
76 memcpy(dst
, src
, 256);
77 s
->cpu
->env
->regs
[15] = S3C_RAM_BASE
; // start address, u-boot relocating code
80 image_size
= load_image("u-boot.bin", phys_ram_base
+ 0x03f80000);
82 if (image_size
& (512 -1)) /* round size to a NAND block size */
83 image_size
= (image_size
+ 512) & ~(512-1);
84 fprintf(stderr
, "%s: loaded override u-boot (size %x)\n", __FUNCTION__
, image_size
);
85 s
->cpu
->env
->regs
[15] = S3C_RAM_BASE
| 0x03f80000; // start address, u-boot already relocated
88 image_size
= load_image(s
->kernel
, phys_ram_base
+ 0x02000000);
92 /* Typical touchscreen calibration values */
93 static const int mini2440_ts_scale
[6] = {
94 0, (90 - 960) * 256 / 1021, -90 * 256 * 32,
95 (940 - 75) * 256 / 1021, 0, 75 * 256 * 32,
99 static struct mini2440_board_s
*mini2440_init_common(int ram_size
,
100 const char *kernel_filename
, const char *cpu_model
,
103 struct mini2440_board_s
*s
= (struct mini2440_board_s
*)
104 qemu_mallocz(sizeof(struct mini2440_board_s
));
107 s
->kernel
= kernel_filename
;
110 /* Setup CPU & memory */
111 if (ram_size
< s
->ram
+ S3C_SRAM_SIZE
) {
112 fprintf(stderr
, "This platform requires %i bytes of memory (not %d)\n",
113 s
->ram
+ S3C_SRAM_SIZE
, ram_size
);
116 if (cpu_model
&& strcmp(cpu_model
, "arm920t")) {
117 fprintf(stderr
, "This platform requires an ARM920T core\n");
120 s
->cpu
= s3c24xx_init(S3C_CPU_2440
, s
->ram
, S3C_SRAM_BASE_NANDBOOT
, s
->mmc
);
122 /* Setup peripherals */
123 mini2440_gpio_setup(s
);
126 // usb_device_attach(usb_bt_init(local_piconet));
132 nd
->model
= "dm9000";
133 if (strcmp(nd
->model
, "dm9000") == 0) {
134 // s3c_gpio_out_set(s->cpu->io, MINI2440_GPIO_DM9000,
135 // *qemu_allocate_irqs(mini2440_bl_switch, s, 1));
137 dm9000_init(nd
, 0x20000000, 0x300, 0x304, s3c_gpio_in_get(s
->cpu
->io
)[MINI2440_IRQ_DM9000
]);
141 s3c_adc_setscale(s
->cpu
->adc
, mini2440_ts_scale
);
143 /* Setup initial (reset) machine state */
144 qemu_register_reset(mini2440_reset
, s
);
146 arm_load_kernel(s
->ram
, kernel_filename
, kernel_cmdline
,
147 initrd_filename
, 0x49e, S3C_RAM_BASE
);
150 // dpy_resize(ds, 240, 320);
155 static void mini2440_init(ram_addr_t ram_size
, int vga_ram_size
,
156 const char *boot_device
,
157 const char *kernel_filename
, const char *kernel_cmdline
,
158 const char *initrd_filename
, const char *cpu_model
)
160 struct mini2440_board_s
*mini
;
161 int sd_idx
= drive_get_index(IF_SD
, 0, 0);
165 sd
= sd_init(drives_table
[sd_idx
].bdrv
, 0);
167 mini
= mini2440_init_common(ram_size
,
168 kernel_filename
, cpu_model
, sd
);
170 mini
->nand
= nand_init(NAND_MFR_SAMSUNG
, 0x36);
171 mini
->cpu
->nand
->reg(mini
->cpu
->nand
, mini
->nand
);
173 mini2440_reset(mini
);
176 QEMUMachine mini2440_machine
= {
178 "MINI2440 Chinese Samsung SoC dev board (S3C2440A)",
179 .init
= mini2440_init
,