Statistics
| Branch: | Revision:

root / hw / palm.c @ d7585251

History | View | Annotate | Download (9.5 kB)

1 c3d2689d balrog
/*
2 c3d2689d balrog
 * PalmOne's (TM) PDAs.
3 c3d2689d balrog
 *
4 c3d2689d balrog
 * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
5 c3d2689d balrog
 *
6 c3d2689d balrog
 * This program is free software; you can redistribute it and/or
7 c3d2689d balrog
 * modify it under the terms of the GNU General Public License as
8 827df9f3 balrog
 * published by the Free Software Foundation; either version 2 or
9 827df9f3 balrog
 * (at your option) version 3 of the License.
10 c3d2689d balrog
 *
11 c3d2689d balrog
 * This program is distributed in the hope that it will be useful,
12 c3d2689d balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 c3d2689d balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 c3d2689d balrog
 * GNU General Public License for more details.
15 c3d2689d balrog
 *
16 fad6cb1a aurel32
 * You should have received a copy of the GNU General Public License along
17 fad6cb1a aurel32
 * with this program; if not, write to the Free Software Foundation, Inc.,
18 fad6cb1a aurel32
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 c3d2689d balrog
 */
20 87ecb68b pbrook
#include "hw.h"
21 87ecb68b pbrook
#include "audio/audio.h"
22 87ecb68b pbrook
#include "sysemu.h"
23 87ecb68b pbrook
#include "console.h"
24 87ecb68b pbrook
#include "omap.h"
25 87ecb68b pbrook
#include "boards.h"
26 87ecb68b pbrook
#include "arm-misc.h"
27 827df9f3 balrog
#include "devices.h"
28 c3d2689d balrog
29 c3d2689d balrog
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
30 c3d2689d balrog
{
31 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
32 c3d2689d balrog
    return *val >> ((offset & 3) << 3);
33 c3d2689d balrog
}
34 c3d2689d balrog
35 827df9f3 balrog
static uint32_t static_readh(void *opaque, target_phys_addr_t offset)
36 827df9f3 balrog
{
37 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
38 c3d2689d balrog
    return *val >> ((offset & 1) << 3);
39 c3d2689d balrog
}
40 c3d2689d balrog
41 827df9f3 balrog
static uint32_t static_readw(void *opaque, target_phys_addr_t offset)
42 827df9f3 balrog
{
43 c3d2689d balrog
    uint32_t *val = (uint32_t *) opaque;
44 c3d2689d balrog
    return *val >> ((offset & 0) << 3);
45 c3d2689d balrog
}
46 c3d2689d balrog
47 c3d2689d balrog
static void static_write(void *opaque, target_phys_addr_t offset,
48 d951f6ff balrog
                uint32_t value)
49 d951f6ff balrog
{
50 c3d2689d balrog
#ifdef SPY
51 c3d2689d balrog
    printf("%s: value %08lx written at " PA_FMT "\n",
52 c3d2689d balrog
                    __FUNCTION__, value, offset);
53 c3d2689d balrog
#endif
54 c3d2689d balrog
}
55 c3d2689d balrog
56 c3d2689d balrog
static CPUReadMemoryFunc *static_readfn[] = {
57 c3d2689d balrog
    static_readb,
58 c3d2689d balrog
    static_readh,
59 c3d2689d balrog
    static_readw,
60 c3d2689d balrog
};
61 c3d2689d balrog
62 c3d2689d balrog
static CPUWriteMemoryFunc *static_writefn[] = {
63 c3d2689d balrog
    static_write,
64 c3d2689d balrog
    static_write,
65 c3d2689d balrog
    static_write,
66 c3d2689d balrog
};
67 c3d2689d balrog
68 c3d2689d balrog
/* Palm Tunsgten|E support */
69 8e129e07 balrog
70 8e129e07 balrog
/* Shared GPIOs */
71 8e129e07 balrog
#define PALMTE_USBDETECT_GPIO        0
72 8e129e07 balrog
#define PALMTE_USB_OR_DC_GPIO        1
73 8e129e07 balrog
#define PALMTE_TSC_GPIO                4
74 8e129e07 balrog
#define PALMTE_PINTDAV_GPIO        6
75 8e129e07 balrog
#define PALMTE_MMC_WP_GPIO        8
76 8e129e07 balrog
#define PALMTE_MMC_POWER_GPIO        9
77 8e129e07 balrog
#define PALMTE_HDQ_GPIO                11
78 8e129e07 balrog
#define PALMTE_HEADPHONES_GPIO        14
79 8e129e07 balrog
#define PALMTE_SPEAKER_GPIO        15
80 8e129e07 balrog
/* MPU private GPIOs */
81 8e129e07 balrog
#define PALMTE_DC_GPIO                2
82 8e129e07 balrog
#define PALMTE_MMC_SWITCH_GPIO        4
83 8e129e07 balrog
#define PALMTE_MMC1_GPIO        6
84 8e129e07 balrog
#define PALMTE_MMC2_GPIO        7
85 8e129e07 balrog
#define PALMTE_MMC3_GPIO        11
86 8e129e07 balrog
87 c38b6e25 balrog
static struct mouse_transform_info_s palmte_pointercal = {
88 c38b6e25 balrog
    .x = 320,
89 c38b6e25 balrog
    .y = 320,
90 c38b6e25 balrog
    .a = { -5909, 8, 22465308, 104, 7644, -1219972, 65536 },
91 c38b6e25 balrog
};
92 c38b6e25 balrog
93 c3d2689d balrog
static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
94 c3d2689d balrog
{
95 d8f699cb balrog
    struct uwire_slave_s *tsc;
96 d8f699cb balrog
    AudioState *audio = 0;
97 d8f699cb balrog
98 d8f699cb balrog
#ifdef HAS_AUDIO
99 d8f699cb balrog
    audio = AUD_init();
100 d8f699cb balrog
#endif
101 d8f699cb balrog
102 d8f699cb balrog
    tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO],
103 d8f699cb balrog
                    audio);
104 d8f699cb balrog
105 d8f699cb balrog
    omap_uwire_attach(cpu->microwire, tsc, 0);
106 d8f699cb balrog
    omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
107 c38b6e25 balrog
108 c38b6e25 balrog
    tsc210x_set_transform(tsc, &palmte_pointercal);
109 c3d2689d balrog
}
110 c3d2689d balrog
111 38a34e1d balrog
static struct {
112 38a34e1d balrog
    int row;
113 38a34e1d balrog
    int column;
114 38a34e1d balrog
} palmte_keymap[0x80] = {
115 38a34e1d balrog
    [0 ... 0x7f] = { -1, -1 },
116 38a34e1d balrog
    [0x3b] = { 0, 0 },        /* F1        -> Calendar */
117 38a34e1d balrog
    [0x3c] = { 1, 0 },        /* F2        -> Contacts */
118 38a34e1d balrog
    [0x3d] = { 2, 0 },        /* F3        -> Tasks List */
119 38a34e1d balrog
    [0x3e] = { 3, 0 },        /* F4        -> Note Pad */
120 38a34e1d balrog
    [0x01] = { 4, 0 },        /* Esc        -> Power */
121 38a34e1d balrog
    [0x4b] = { 0, 1 },        /*            Left */
122 38a34e1d balrog
    [0x50] = { 1, 1 },        /*            Down */
123 38a34e1d balrog
    [0x48] = { 2, 1 },        /*           Up */
124 38a34e1d balrog
    [0x4d] = { 3, 1 },        /*           Right */
125 38a34e1d balrog
    [0x4c] = { 4, 1 },        /*            Centre */
126 38a34e1d balrog
    [0x39] = { 4, 1 },        /* Spc        -> Centre */
127 38a34e1d balrog
};
128 38a34e1d balrog
129 38a34e1d balrog
static void palmte_button_event(void *opaque, int keycode)
130 38a34e1d balrog
{
131 38a34e1d balrog
    struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
132 38a34e1d balrog
133 38a34e1d balrog
    if (palmte_keymap[keycode & 0x7f].row != -1)
134 38a34e1d balrog
        omap_mpuio_key(cpu->mpuio,
135 38a34e1d balrog
                        palmte_keymap[keycode & 0x7f].row,
136 38a34e1d balrog
                        palmte_keymap[keycode & 0x7f].column,
137 38a34e1d balrog
                        !(keycode & 0x80));
138 38a34e1d balrog
}
139 38a34e1d balrog
140 7fc42b4b balrog
static void palmte_onoff_gpios(void *opaque, int line, int level)
141 7fc42b4b balrog
{
142 7fc42b4b balrog
    switch (line) {
143 7fc42b4b balrog
    case 0:
144 7fc42b4b balrog
        printf("%s: current to MMC/SD card %sabled.\n",
145 7fc42b4b balrog
                        __FUNCTION__, level ? "dis" : "en");
146 7fc42b4b balrog
        break;
147 7fc42b4b balrog
    case 1:
148 7fc42b4b balrog
        printf("%s: internal speaker amplifier %s.\n",
149 7fc42b4b balrog
                        __FUNCTION__, level ? "down" : "on");
150 7fc42b4b balrog
        break;
151 7fc42b4b balrog
152 7fc42b4b balrog
    /* These LCD & Audio output signals have not been identified yet.  */
153 7fc42b4b balrog
    case 2:
154 7fc42b4b balrog
    case 3:
155 7fc42b4b balrog
    case 4:
156 7fc42b4b balrog
        printf("%s: LCD GPIO%i %s.\n",
157 7fc42b4b balrog
                        __FUNCTION__, line - 1, level ? "high" : "low");
158 7fc42b4b balrog
        break;
159 7fc42b4b balrog
    case 5:
160 7fc42b4b balrog
    case 6:
161 7fc42b4b balrog
        printf("%s: Audio GPIO%i %s.\n",
162 7fc42b4b balrog
                        __FUNCTION__, line - 4, level ? "high" : "low");
163 7fc42b4b balrog
        break;
164 7fc42b4b balrog
    }
165 7fc42b4b balrog
}
166 7fc42b4b balrog
167 7fc42b4b balrog
static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
168 7fc42b4b balrog
{
169 7fc42b4b balrog
    qemu_irq *misc_gpio;
170 7fc42b4b balrog
171 7fc42b4b balrog
    omap_mmc_handlers(cpu->mmc,
172 7fc42b4b balrog
                    omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO],
173 7fc42b4b balrog
                    qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
174 7fc42b4b balrog
                            [PALMTE_MMC_SWITCH_GPIO]));
175 7fc42b4b balrog
176 7fc42b4b balrog
    misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
177 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO,        misc_gpio[0]);
178 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO,        misc_gpio[1]);
179 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 11,                        misc_gpio[2]);
180 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 12,                        misc_gpio[3]);
181 7fc42b4b balrog
    omap_gpio_out_set(cpu->gpio, 13,                        misc_gpio[4]);
182 7fc42b4b balrog
    omap_mpuio_out_set(cpu->mpuio, 1,                        misc_gpio[5]);
183 7fc42b4b balrog
    omap_mpuio_out_set(cpu->mpuio, 3,                        misc_gpio[6]);
184 7fc42b4b balrog
185 7fc42b4b balrog
    /* Reset some inputs to initial state.  */
186 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]);
187 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]);
188 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]);
189 7fc42b4b balrog
    qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]);
190 7fc42b4b balrog
    qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
191 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
192 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
193 7fc42b4b balrog
    qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]);
194 7fc42b4b balrog
}
195 7fc42b4b balrog
196 f93eb9ff balrog
static struct arm_boot_info palmte_binfo = {
197 f93eb9ff balrog
    .loader_start = OMAP_EMIFF_BASE,
198 f93eb9ff balrog
    .ram_size = 0x02000000,
199 f93eb9ff balrog
    .board_id = 0x331,
200 f93eb9ff balrog
};
201 f93eb9ff balrog
202 00f82b8a aurel32
static void palmte_init(ram_addr_t ram_size, int vga_ram_size,
203 3023f332 aliguori
                const char *boot_device,
204 c3d2689d balrog
                const char *kernel_filename, const char *kernel_cmdline,
205 c3d2689d balrog
                const char *initrd_filename, const char *cpu_model)
206 c3d2689d balrog
{
207 c3d2689d balrog
    struct omap_mpu_state_s *cpu;
208 c3d2689d balrog
    int flash_size = 0x00800000;
209 f93eb9ff balrog
    int sdram_size = palmte_binfo.ram_size;
210 c3d2689d balrog
    int io;
211 c3d2689d balrog
    static uint32_t cs0val = 0xffffffff;
212 c3d2689d balrog
    static uint32_t cs1val = 0x0000e1a0;
213 c3d2689d balrog
    static uint32_t cs2val = 0x0000e1a0;
214 c3d2689d balrog
    static uint32_t cs3val = 0xe1a0e1a0;
215 c3d2689d balrog
    ram_addr_t phys_flash;
216 c3d2689d balrog
    int rom_size, rom_loaded = 0;
217 3023f332 aliguori
    DisplayState *ds = get_displaystate();
218 c3d2689d balrog
219 c3d2689d balrog
    if (ram_size < flash_size + sdram_size + OMAP15XX_SRAM_SIZE) {
220 c3d2689d balrog
        fprintf(stderr, "This architecture uses %i bytes of memory\n",
221 c3d2689d balrog
                        flash_size + sdram_size + OMAP15XX_SRAM_SIZE);
222 c3d2689d balrog
        exit(1);
223 c3d2689d balrog
    }
224 c3d2689d balrog
225 3023f332 aliguori
    cpu = omap310_mpu_init(sdram_size, cpu_model);
226 c3d2689d balrog
227 c3d2689d balrog
    /* External Flash (EMIFS) */
228 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
229 c3d2689d balrog
                    (phys_flash = qemu_ram_alloc(flash_size)) | IO_MEM_ROM);
230 c3d2689d balrog
231 c3d2689d balrog
    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs0val);
232 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS0_BASE + flash_size,
233 c3d2689d balrog
                    OMAP_CS0_SIZE - flash_size, io);
234 c3d2689d balrog
    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs1val);
235 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io);
236 c3d2689d balrog
    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs2val);
237 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io);
238 c3d2689d balrog
    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs3val);
239 c3d2689d balrog
    cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io);
240 c3d2689d balrog
241 c3d2689d balrog
    palmte_microwire_setup(cpu);
242 c3d2689d balrog
243 38a34e1d balrog
    qemu_add_kbd_event_handler(palmte_button_event, cpu);
244 38a34e1d balrog
245 7fc42b4b balrog
    palmte_gpio_setup(cpu);
246 8e129e07 balrog
247 c3d2689d balrog
    /* Setup initial (reset) machine state */
248 c3d2689d balrog
    if (nb_option_roms) {
249 c3d2689d balrog
        rom_size = get_image_size(option_rom[0]);
250 dcac9679 pbrook
        if (rom_size > flash_size) {
251 c3d2689d balrog
            fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
252 c3d2689d balrog
                            __FUNCTION__, rom_size, flash_size);
253 dcac9679 pbrook
            rom_size = 0;
254 dcac9679 pbrook
        }
255 dcac9679 pbrook
        if (rom_size > 0) {
256 dcac9679 pbrook
            rom_size = load_image_targphys(option_rom[0], OMAP_CS0_BASE,
257 dcac9679 pbrook
                                           flash_size);
258 c3d2689d balrog
            rom_loaded = 1;
259 c3d2689d balrog
            cpu->env->regs[15] = 0x00000000;
260 dcac9679 pbrook
        }
261 dcac9679 pbrook
        if (rom_size < 0) {
262 c3d2689d balrog
            fprintf(stderr, "%s: error loading '%s'\n",
263 c3d2689d balrog
                            __FUNCTION__, option_rom[0]);
264 dcac9679 pbrook
        }
265 c3d2689d balrog
    }
266 c3d2689d balrog
267 c3d2689d balrog
    if (!rom_loaded && !kernel_filename) {
268 c3d2689d balrog
        fprintf(stderr, "Kernel or ROM image must be specified\n");
269 c3d2689d balrog
        exit(1);
270 c3d2689d balrog
    }
271 c3d2689d balrog
272 c3d2689d balrog
    /* Load the kernel.  */
273 c3d2689d balrog
    if (kernel_filename) {
274 c3d2689d balrog
        /* Start at bootloader.  */
275 f93eb9ff balrog
        cpu->env->regs[15] = palmte_binfo.loader_start;
276 c3d2689d balrog
277 f93eb9ff balrog
        palmte_binfo.kernel_filename = kernel_filename;
278 f93eb9ff balrog
        palmte_binfo.kernel_cmdline = kernel_cmdline;
279 f93eb9ff balrog
        palmte_binfo.initrd_filename = initrd_filename;
280 f93eb9ff balrog
        arm_load_kernel(cpu->env, &palmte_binfo);
281 c3d2689d balrog
    }
282 c3d2689d balrog
283 c60e08d9 pbrook
    /* FIXME: We shouldn't really be doing this here.  The LCD controller
284 c60e08d9 pbrook
       will set the size once configured, so this just sets an initial
285 c60e08d9 pbrook
       size until the guest activates the display.  */
286 7b5d76da aliguori
    ds->surface = qemu_resize_displaysurface(ds, 320, 320);
287 7d957bd8 aliguori
    dpy_resize(ds);
288 c3d2689d balrog
}
289 c3d2689d balrog
290 c3d2689d balrog
QEMUMachine palmte_machine = {
291 4b32e168 aliguori
    .name = "cheetah",
292 4b32e168 aliguori
    .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
293 4b32e168 aliguori
    .init = palmte_init,
294 3d878caa balrog
    .ram_require = (0x02000000 + 0x00800000 + OMAP15XX_SRAM_SIZE) |
295 3d878caa balrog
            RAMSIZE_FIXED,
296 c3d2689d balrog
};