[S3C2440] NAND support
[qemu/mini2440.git] / hw / mini2440.c
blob4a0d10936b57cfb59b12b2750a263d2b44e4927e
1 /*
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.
9 */
11 #include "hw.h"
12 #include "s3c.h"
13 #include "arm-misc.h"
14 #include "sysemu.h"
15 #include "i2c.h"
16 #include "qemu-timer.h"
17 #include "devices.h"
18 #include "audio/audio.h"
19 #include "boards.h"
20 #include "console.h"
21 #include "usb.h"
22 #include "net.h"
23 #include "sd.h"
24 #include "dm9000.h"
26 #define mini2440_printf(format, ...) \
27 fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
29 #define GTA01Bv4 1
31 enum {
32 MACH_MINI2440 = 1999
35 /* Wiring common to all revisions */
36 #define GTA01_GPIO_BACKLIGHT S3C_GPB(1)
37 #define GTA01_GPIO_LCD_RESET S3C_GPC(6)
38 #define GTA01_GPIO_nSD_DETECT S3C_GPG(8)
39 #define GTA01_IRQ_nSD_DETECT S3C_EINT(16)
40 #define GTA01_IRQ_DM9000 S3C_EINT(7)
41 #define GTA01_GPIO_DM9000 S3C_GPF(7)
43 #define GTA01_GPIO_SDMMC_ON S3C_GPB(2)
44 #define GTA01_GPIO_USB_PULLUP S3C_GPB(9)
45 #define GTA01_GPIO_USB_ATTACH S3C_GPB(10)
47 struct mini2440_board_s {
48 struct s3c_state_s *cpu;
49 unsigned int ram;
50 i2c_slave *eeprom;
51 const char *kernel;
52 SDState *mmc;
53 uint32_t id;
55 int bl_level;
59 static void mini2440_gpio_setup(struct mini2440_board_s *s)
61 // s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_BACKLIGHT,
62 // *qemu_allocate_irqs(mini2440_bl_switch, s, 1));
64 // s3c_timers_cmp_handler_set(s->cpu->timers, 0, mini2440_bl_intensity, s);
66 sd_set_cb(s->mmc, 0,
67 s3c_gpio_in_get(s->cpu->io)[GTA01_IRQ_nSD_DETECT]);
70 static void mini2440_reset(void *opaque)
72 struct mini2440_board_s *s = (struct mini2440_board_s *) opaque;
73 #if 0
74 s->cpu->env->regs[15] = S3C_SRAM_BASE;
75 #else
76 load_image("u-boot.bin", phys_ram_base + 0x03f80000);
77 load_image(s->kernel, phys_ram_base + 0x02000000);
79 s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000;
80 #if 0
81 if (strstr(s->kernel, "u-boot")) { /* FIXME */
82 /* Exploit preboot-override to set up an initial environment */
83 stl_raw(phys_ram_base + 0x03f80040, S3C_RAM_BASE | 0x000fff00);
84 strcpy(phys_ram_base + 0x000fff00,
85 "setenv stdin serial; "
86 "setenv stdout serial; "
87 "setenv stderr serial; ");
88 /* Disable ENV pre-load */
89 stl_raw(phys_ram_base + 0x03f80044, 0x00000000);
91 #endif
92 #endif
96 /* Typical touchscreen calibration values */
97 static const int mini2440_ts_scale[6] = {
98 0, (90 - 960) * 256 / 1021, -90 * 256 * 32,
99 (940 - 75) * 256 / 1021, 0, 75 * 256 * 32,
102 /* Board init. */
103 static struct mini2440_board_s *mini2440_init_common(int ram_size, DisplayState *ds,
104 const char *kernel_filename, const char *cpu_model,
105 SDState *mmc, uint32_t id)
107 struct mini2440_board_s *s = (struct mini2440_board_s *)
108 qemu_mallocz(sizeof(struct mini2440_board_s));
110 s->ram = 0x08000000;
111 s->kernel = kernel_filename;
112 s->mmc = mmc;
113 s->id = id;
115 /* Setup CPU & memory */
116 if (ram_size < s->ram + S3C_SRAM_SIZE) {
117 fprintf(stderr, "This platform requires %i bytes of memory (not %d)\n",
118 s->ram + S3C_SRAM_SIZE, ram_size);
119 exit(1);
121 if (cpu_model && strcmp(cpu_model, "arm920t")) {
122 fprintf(stderr, "This platform requires an ARM920T core\n");
123 exit(2);
125 s->cpu = s3c24xx_init(S3C_CPU_2440, s->ram, ds, s->mmc);
127 /* Setup peripherals */
128 mini2440_gpio_setup(s);
130 // if (usb_enabled)
131 // usb_device_attach(usb_bt_init(local_piconet));
134 NICInfo* nd;
135 nd = &nd_table[0];
136 if (!nd->model)
137 nd->model = "dm9000";
138 if (strcmp(nd->model, "dm9000") == 0) {
139 // s3c_gpio_out_set(s->cpu->io, GTA01_GPIO_DM9000,
140 // *qemu_allocate_irqs(mini2440_bl_switch, s, 1));
142 dm9000_init(nd, 0x20000300, 0x00, 0x04, s3c_gpio_in_get(s->cpu->io)[7]);
146 s3c_adc_setscale(s->cpu->adc, mini2440_ts_scale);
148 /* Setup initial (reset) machine state */
149 qemu_register_reset(mini2440_reset, s);
150 #if 0
151 arm_load_kernel(s->ram, kernel_filename, kernel_cmdline,
152 initrd_filename, 0x49e, S3C_RAM_BASE);
153 #endif
154 mini2440_reset(s);
156 // dpy_resize(ds, 240, 320);
158 return s;
160 //QEMUMachineInitFunc init;
162 static void mini2440_init(ram_addr_t ram_size, int vga_ram_size,
163 const char *boot_device,
164 const char *kernel_filename, const char *kernel_cmdline,
165 const char *initrd_filename, const char *cpu_model)
167 struct mini2440_board_s *neo;
168 int sd_idx = drive_get_index(IF_SD, 0, 0);
169 SDState *sd = 0;
171 DisplayState *ds = get_displaystate();
173 if (sd_idx >= 0)
174 sd = sd_init(drives_table[sd_idx].bdrv, 0);
176 neo = mini2440_init_common(ram_size, ds,
177 kernel_filename, cpu_model, sd, MACH_MINI2440);
179 neo->cpu->nand->reg(neo->cpu->nand, nand_init(NAND_MFR_SAMSUNG, 0xa2));
184 QEMUMachine mini2440_machine = {
185 "mini2440",
186 "MINI2440 Chinese Samsung SoC dev board (S3C2440A)",
187 .init = mini2440_init,