Statistics
| Branch: | Revision:

root / hw / nseries.c @ 7ba1e619

History | View | Annotate | Download (43.3 kB)

1 7e7c5e4c balrog
/*
2 7e7c5e4c balrog
 * Nokia N-series internet tablets.
3 7e7c5e4c balrog
 *
4 7e7c5e4c balrog
 * Copyright (C) 2007 Nokia Corporation
5 7e7c5e4c balrog
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
6 7e7c5e4c balrog
 *
7 7e7c5e4c balrog
 * This program is free software; you can redistribute it and/or
8 7e7c5e4c balrog
 * modify it under the terms of the GNU General Public License as
9 7e7c5e4c balrog
 * published by the Free Software Foundation; either version 2 or
10 7e7c5e4c balrog
 * (at your option) version 3 of the License.
11 7e7c5e4c balrog
 *
12 7e7c5e4c balrog
 * This program is distributed in the hope that it will be useful,
13 7e7c5e4c balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 7e7c5e4c balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 7e7c5e4c balrog
 * GNU General Public License for more details.
16 7e7c5e4c balrog
 *
17 7e7c5e4c balrog
 * You should have received a copy of the GNU General Public License
18 7e7c5e4c balrog
 * along with this program; if not, write to the Free Software
19 7e7c5e4c balrog
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 7e7c5e4c balrog
 * MA 02111-1307 USA
21 7e7c5e4c balrog
 */
22 7e7c5e4c balrog
23 7e7c5e4c balrog
#include "qemu-common.h"
24 7e7c5e4c balrog
#include "sysemu.h"
25 7e7c5e4c balrog
#include "omap.h"
26 7e7c5e4c balrog
#include "arm-misc.h"
27 7e7c5e4c balrog
#include "irq.h"
28 7e7c5e4c balrog
#include "console.h"
29 7e7c5e4c balrog
#include "boards.h"
30 7e7c5e4c balrog
#include "i2c.h"
31 7e7c5e4c balrog
#include "devices.h"
32 7e7c5e4c balrog
#include "flash.h"
33 7e7c5e4c balrog
#include "hw.h"
34 1ae26a18 balrog
#include "bt.h"
35 7e7c5e4c balrog
36 7e7c5e4c balrog
/* Nokia N8x0 support */
37 7e7c5e4c balrog
struct n800_s {
38 7e7c5e4c balrog
    struct omap_mpu_state_s *cpu;
39 7e7c5e4c balrog
40 7e7c5e4c balrog
    struct rfbi_chip_s blizzard;
41 e927bb00 balrog
    struct {
42 e927bb00 balrog
        void *opaque;
43 e927bb00 balrog
        uint32_t (*txrx)(void *opaque, uint32_t value, int len);
44 e927bb00 balrog
        struct uwire_slave_s *chip;
45 e927bb00 balrog
    } ts;
46 7e7c5e4c balrog
    i2c_bus *i2c;
47 7e7c5e4c balrog
48 7e7c5e4c balrog
    int keymap[0x80];
49 1d4e547b balrog
    i2c_slave *kbd;
50 7e7c5e4c balrog
51 942ac052 balrog
    struct tusb_s *usb;
52 7e7c5e4c balrog
    void *retu;
53 7e7c5e4c balrog
    void *tahvo;
54 c580d92b balrog
    void *nand;
55 7e7c5e4c balrog
};
56 7e7c5e4c balrog
57 7e7c5e4c balrog
/* GPIO pins */
58 e927bb00 balrog
#define N8X0_TUSB_ENABLE_GPIO                0
59 7e7c5e4c balrog
#define N800_MMC2_WP_GPIO                8
60 7e7c5e4c balrog
#define N800_UNKNOWN_GPIO0                9        /* out */
61 0941041e balrog
#define N810_MMC2_VIOSD_GPIO                9
62 99570a40 balrog
#define N810_HEADSET_AMP_GPIO                10
63 7e7c5e4c balrog
#define N800_CAM_TURN_GPIO                12
64 e927bb00 balrog
#define N810_GPS_RESET_GPIO                12
65 7e7c5e4c balrog
#define N800_BLIZZARD_POWERDOWN_GPIO        15
66 7e7c5e4c balrog
#define N800_MMC1_WP_GPIO                23
67 0941041e balrog
#define N810_MMC2_VSD_GPIO                23
68 7e7c5e4c balrog
#define N8X0_ONENAND_GPIO                26
69 e927bb00 balrog
#define N810_BLIZZARD_RESET_GPIO        30
70 7e7c5e4c balrog
#define N800_UNKNOWN_GPIO2                53        /* out */
71 7e7c5e4c balrog
#define N8X0_TUSB_INT_GPIO                58
72 e927bb00 balrog
#define N8X0_BT_WKUP_GPIO                61
73 e927bb00 balrog
#define N8X0_STI_GPIO                        62
74 7e7c5e4c balrog
#define N8X0_CBUS_SEL_GPIO                64
75 e927bb00 balrog
#define N8X0_CBUS_DAT_GPIO                65
76 e927bb00 balrog
#define N8X0_CBUS_CLK_GPIO                66
77 e927bb00 balrog
#define N8X0_WLAN_IRQ_GPIO                87
78 e927bb00 balrog
#define N8X0_BT_RESET_GPIO                92
79 e927bb00 balrog
#define N8X0_TEA5761_CS_GPIO                93
80 7e7c5e4c balrog
#define N800_UNKNOWN_GPIO                94
81 e927bb00 balrog
#define N810_TSC_RESET_GPIO                94
82 7e7c5e4c balrog
#define N800_CAM_ACT_GPIO                95
83 e927bb00 balrog
#define N810_GPS_WAKEUP_GPIO                95
84 e927bb00 balrog
#define N8X0_MMC_CS_GPIO                96
85 e927bb00 balrog
#define N8X0_WLAN_PWR_GPIO                97
86 7e7c5e4c balrog
#define N8X0_BT_HOST_WKUP_GPIO                98
87 99570a40 balrog
#define N810_SPEAKER_AMP_GPIO                101
88 7e7c5e4c balrog
#define N810_KB_LOCK_GPIO                102
89 7e7c5e4c balrog
#define N800_TSC_TS_GPIO                103
90 e927bb00 balrog
#define N810_TSC_TS_GPIO                106
91 e927bb00 balrog
#define N8X0_HEADPHONE_GPIO                107
92 7e7c5e4c balrog
#define N8X0_RETU_GPIO                        108
93 7e7c5e4c balrog
#define N800_TSC_KP_IRQ_GPIO                109
94 7e7c5e4c balrog
#define N810_KEYBOARD_GPIO                109
95 7e7c5e4c balrog
#define N800_BAT_COVER_GPIO                110
96 7e7c5e4c balrog
#define N810_SLIDE_GPIO                        110
97 7e7c5e4c balrog
#define N8X0_TAHVO_GPIO                        111
98 7e7c5e4c balrog
#define N800_UNKNOWN_GPIO4                112        /* out */
99 e927bb00 balrog
#define N810_SLEEPX_LED_GPIO                112
100 1d4e547b balrog
#define N800_TSC_RESET_GPIO                118        /* ? */
101 99570a40 balrog
#define N810_AIC33_RESET_GPIO                118
102 1d4e547b balrog
#define N800_TSC_UNKNOWN_GPIO                119        /* out */
103 7e7c5e4c balrog
#define N8X0_TMP105_GPIO                125
104 7e7c5e4c balrog
105 7e7c5e4c balrog
/* Config */
106 c580d92b balrog
#define BT_UART                                0
107 7e7c5e4c balrog
#define XLDR_LL_UART                        1
108 7e7c5e4c balrog
109 1d4e547b balrog
/* Addresses on the I2C bus 0 */
110 1d4e547b balrog
#define N810_TLV320AIC33_ADDR                0x18        /* Audio CODEC */
111 1d4e547b balrog
#define N8X0_TCM825x_ADDR                0x29        /* Camera */
112 1d4e547b balrog
#define N810_LP5521_ADDR                0x32        /* LEDs */
113 1d4e547b balrog
#define N810_TSL2563_ADDR                0x3d        /* Light sensor */
114 1d4e547b balrog
#define N810_LM8323_ADDR                0x45        /* Keyboard */
115 1d4e547b balrog
/* Addresses on the I2C bus 1 */
116 1d4e547b balrog
#define N8X0_TMP105_ADDR                0x48        /* Temperature sensor */
117 1d4e547b balrog
#define N8X0_MENELAUS_ADDR                0x72        /* Power management */
118 7e7c5e4c balrog
119 7e7c5e4c balrog
/* Chipselects on GPMC NOR interface */
120 7e7c5e4c balrog
#define N8X0_ONENAND_CS                        0
121 7e7c5e4c balrog
#define N8X0_USB_ASYNC_CS                1
122 7e7c5e4c balrog
#define N8X0_USB_SYNC_CS                4
123 7e7c5e4c balrog
124 c580d92b balrog
#define N8X0_BD_ADDR                        0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
125 c580d92b balrog
126 7e7c5e4c balrog
static void n800_mmc_cs_cb(void *opaque, int line, int level)
127 7e7c5e4c balrog
{
128 7e7c5e4c balrog
    /* TODO: this seems to actually be connected to the menelaus, to
129 7e7c5e4c balrog
     * which also both MMC slots connect.  */
130 7e7c5e4c balrog
    omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
131 7e7c5e4c balrog
132 7e7c5e4c balrog
    printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
133 7e7c5e4c balrog
}
134 7e7c5e4c balrog
135 e927bb00 balrog
static void n8x0_gpio_setup(struct n800_s *s)
136 7e7c5e4c balrog
{
137 7e7c5e4c balrog
    qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
138 e927bb00 balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
139 7e7c5e4c balrog
140 7e7c5e4c balrog
    qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
141 7e7c5e4c balrog
}
142 7e7c5e4c balrog
143 c580d92b balrog
#define MAEMO_CAL_HEADER(...)                                \
144 c580d92b balrog
    'C',  'o',  'n',  'F',  0x02, 0x00, 0x04, 0x00,        \
145 c580d92b balrog
    __VA_ARGS__,                                        \
146 c580d92b balrog
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 c580d92b balrog
148 c580d92b balrog
static const uint8_t n8x0_cal_wlan_mac[] = {
149 c580d92b balrog
    MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c')
150 c580d92b balrog
    0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3,
151 c580d92b balrog
    0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00,
152 c580d92b balrog
    0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
153 c580d92b balrog
    0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
154 c580d92b balrog
    0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
155 c580d92b balrog
};
156 c580d92b balrog
157 c580d92b balrog
static const uint8_t n8x0_cal_bt_id[] = {
158 c580d92b balrog
    MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0)
159 c580d92b balrog
    0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96,
160 c580d92b balrog
    0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00,
161 c580d92b balrog
    N8X0_BD_ADDR,
162 c580d92b balrog
};
163 c580d92b balrog
164 7e7c5e4c balrog
static void n8x0_nand_setup(struct n800_s *s)
165 7e7c5e4c balrog
{
166 c580d92b balrog
    char *otp_region;
167 c580d92b balrog
168 7e7c5e4c balrog
    /* Either ec40xx or ec48xx are OK for the ID */
169 7e7c5e4c balrog
    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
170 7e7c5e4c balrog
                    onenand_base_unmap,
171 c580d92b balrog
                    (s->nand = onenand_init(0xec4800, 1,
172 c580d92b balrog
                                            omap2_gpio_in_get(s->cpu->gpif,
173 c580d92b balrog
                                                    N8X0_ONENAND_GPIO)[0])));
174 c580d92b balrog
    otp_region = onenand_raw_otp(s->nand);
175 c580d92b balrog
176 c580d92b balrog
    memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
177 c580d92b balrog
    memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));
178 c580d92b balrog
    /* XXX: in theory should also update the OOB for both pages */
179 7e7c5e4c balrog
}
180 7e7c5e4c balrog
181 e927bb00 balrog
static void n8x0_i2c_setup(struct n800_s *s)
182 7e7c5e4c balrog
{
183 7e7c5e4c balrog
    qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
184 7e7c5e4c balrog
185 7e7c5e4c balrog
    /* Attach the CPU on one end of our I2C bus.  */
186 7e7c5e4c balrog
    s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
187 7e7c5e4c balrog
188 7e7c5e4c balrog
    /* Attach a menelaus PM chip */
189 7e7c5e4c balrog
    i2c_set_slave_address(
190 7e7c5e4c balrog
                    twl92230_init(s->i2c,
191 7e7c5e4c balrog
                            s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]),
192 7e7c5e4c balrog
                    N8X0_MENELAUS_ADDR);
193 7e7c5e4c balrog
194 7e7c5e4c balrog
    /* Attach a TMP105 PM chip (A0 wired to ground) */
195 7e7c5e4c balrog
    i2c_set_slave_address(tmp105_init(s->i2c, tmp_irq), N8X0_TMP105_ADDR);
196 7e7c5e4c balrog
}
197 7e7c5e4c balrog
198 7e7c5e4c balrog
/* Touchscreen and keypad controller */
199 e927bb00 balrog
static struct mouse_transform_info_s n800_pointercal = {
200 e927bb00 balrog
    .x = 800,
201 e927bb00 balrog
    .y = 480,
202 e927bb00 balrog
    .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
203 e927bb00 balrog
};
204 e927bb00 balrog
205 e927bb00 balrog
static struct mouse_transform_info_s n810_pointercal = {
206 e927bb00 balrog
    .x = 800,
207 e927bb00 balrog
    .y = 480,
208 e927bb00 balrog
    .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
209 e927bb00 balrog
};
210 e927bb00 balrog
211 7e7c5e4c balrog
#define RETU_KEYCODE        61        /* F3 */
212 7e7c5e4c balrog
213 7e7c5e4c balrog
static void n800_key_event(void *opaque, int keycode)
214 7e7c5e4c balrog
{
215 7e7c5e4c balrog
    struct n800_s *s = (struct n800_s *) opaque;
216 7e7c5e4c balrog
    int code = s->keymap[keycode & 0x7f];
217 7e7c5e4c balrog
218 7e7c5e4c balrog
    if (code == -1) {
219 7e7c5e4c balrog
        if ((keycode & 0x7f) == RETU_KEYCODE)
220 7e7c5e4c balrog
            retu_key_event(s->retu, !(keycode & 0x80));
221 7e7c5e4c balrog
        return;
222 7e7c5e4c balrog
    }
223 7e7c5e4c balrog
224 e927bb00 balrog
    tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
225 7e7c5e4c balrog
}
226 7e7c5e4c balrog
227 7e7c5e4c balrog
static const int n800_keys[16] = {
228 7e7c5e4c balrog
    -1,
229 7e7c5e4c balrog
    72,        /* Up */
230 7e7c5e4c balrog
    63,        /* Home (F5) */
231 7e7c5e4c balrog
    -1,
232 7e7c5e4c balrog
    75,        /* Left */
233 7e7c5e4c balrog
    28,        /* Enter */
234 7e7c5e4c balrog
    77,        /* Right */
235 7e7c5e4c balrog
    -1,
236 1d4e547b balrog
     1,        /* Cycle (ESC) */
237 7e7c5e4c balrog
    80,        /* Down */
238 7e7c5e4c balrog
    62,        /* Menu (F4) */
239 7e7c5e4c balrog
    -1,
240 7e7c5e4c balrog
    66,        /* Zoom- (F8) */
241 1d4e547b balrog
    64,        /* FullScreen (F6) */
242 7e7c5e4c balrog
    65,        /* Zoom+ (F7) */
243 7e7c5e4c balrog
    -1,
244 7e7c5e4c balrog
};
245 7e7c5e4c balrog
246 e927bb00 balrog
static void n800_tsc_kbd_setup(struct n800_s *s)
247 7e7c5e4c balrog
{
248 7e7c5e4c balrog
    int i;
249 7e7c5e4c balrog
250 7e7c5e4c balrog
    /* XXX: are the three pins inverted inside the chip between the
251 7e7c5e4c balrog
     * tsc and the cpu (N4111)?  */
252 7e7c5e4c balrog
    qemu_irq penirq = 0;        /* NC */
253 7e7c5e4c balrog
    qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
254 7e7c5e4c balrog
    qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
255 7e7c5e4c balrog
256 e927bb00 balrog
    s->ts.chip = tsc2301_init(penirq, kbirq, dav, 0);
257 e927bb00 balrog
    s->ts.opaque = s->ts.chip->opaque;
258 e927bb00 balrog
    s->ts.txrx = tsc210x_txrx;
259 7e7c5e4c balrog
260 7e7c5e4c balrog
    for (i = 0; i < 0x80; i ++)
261 7e7c5e4c balrog
        s->keymap[i] = -1;
262 7e7c5e4c balrog
    for (i = 0; i < 0x10; i ++)
263 7e7c5e4c balrog
        if (n800_keys[i] >= 0)
264 7e7c5e4c balrog
            s->keymap[n800_keys[i]] = i;
265 7e7c5e4c balrog
266 7e7c5e4c balrog
    qemu_add_kbd_event_handler(n800_key_event, s);
267 7e7c5e4c balrog
268 e927bb00 balrog
    tsc210x_set_transform(s->ts.chip, &n800_pointercal);
269 e927bb00 balrog
}
270 e927bb00 balrog
271 e927bb00 balrog
static void n810_tsc_setup(struct n800_s *s)
272 e927bb00 balrog
{
273 e927bb00 balrog
    qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
274 e927bb00 balrog
275 e927bb00 balrog
    s->ts.opaque = tsc2005_init(pintdav);
276 e927bb00 balrog
    s->ts.txrx = tsc2005_txrx;
277 e927bb00 balrog
278 e927bb00 balrog
    tsc2005_set_transform(s->ts.opaque, &n810_pointercal);
279 7e7c5e4c balrog
}
280 7e7c5e4c balrog
281 1d4e547b balrog
/* N810 Keyboard controller */
282 1d4e547b balrog
static void n810_key_event(void *opaque, int keycode)
283 1d4e547b balrog
{
284 1d4e547b balrog
    struct n800_s *s = (struct n800_s *) opaque;
285 1d4e547b balrog
    int code = s->keymap[keycode & 0x7f];
286 1d4e547b balrog
287 1d4e547b balrog
    if (code == -1) {
288 1d4e547b balrog
        if ((keycode & 0x7f) == RETU_KEYCODE)
289 1d4e547b balrog
            retu_key_event(s->retu, !(keycode & 0x80));
290 1d4e547b balrog
        return;
291 1d4e547b balrog
    }
292 1d4e547b balrog
293 1d4e547b balrog
    lm832x_key_event(s->kbd, code, !(keycode & 0x80));
294 1d4e547b balrog
}
295 1d4e547b balrog
296 1d4e547b balrog
#define M        0
297 1d4e547b balrog
298 1d4e547b balrog
static int n810_keys[0x80] = {
299 1d4e547b balrog
    [0x01] = 16,        /* Q */
300 1d4e547b balrog
    [0x02] = 37,        /* K */
301 1d4e547b balrog
    [0x03] = 24,        /* O */
302 1d4e547b balrog
    [0x04] = 25,        /* P */
303 1d4e547b balrog
    [0x05] = 14,        /* Backspace */
304 1d4e547b balrog
    [0x06] = 30,        /* A */
305 1d4e547b balrog
    [0x07] = 31,        /* S */
306 1d4e547b balrog
    [0x08] = 32,        /* D */
307 1d4e547b balrog
    [0x09] = 33,        /* F */
308 1d4e547b balrog
    [0x0a] = 34,        /* G */
309 1d4e547b balrog
    [0x0b] = 35,        /* H */
310 1d4e547b balrog
    [0x0c] = 36,        /* J */
311 1d4e547b balrog
312 1d4e547b balrog
    [0x11] = 17,        /* W */
313 1d4e547b balrog
    [0x12] = 62,        /* Menu (F4) */
314 1d4e547b balrog
    [0x13] = 38,        /* L */
315 1d4e547b balrog
    [0x14] = 40,        /* ' (Apostrophe) */
316 1d4e547b balrog
    [0x16] = 44,        /* Z */
317 1d4e547b balrog
    [0x17] = 45,        /* X */
318 1d4e547b balrog
    [0x18] = 46,        /* C */
319 1d4e547b balrog
    [0x19] = 47,        /* V */
320 1d4e547b balrog
    [0x1a] = 48,        /* B */
321 1d4e547b balrog
    [0x1b] = 49,        /* N */
322 1d4e547b balrog
    [0x1c] = 42,        /* Shift (Left shift) */
323 1d4e547b balrog
    [0x1f] = 65,        /* Zoom+ (F7) */
324 1d4e547b balrog
325 1d4e547b balrog
    [0x21] = 18,        /* E */
326 1d4e547b balrog
    [0x22] = 39,        /* ; (Semicolon) */
327 1d4e547b balrog
    [0x23] = 12,        /* - (Minus) */
328 1d4e547b balrog
    [0x24] = 13,        /* = (Equal) */
329 1d4e547b balrog
    [0x2b] = 56,        /* Fn (Left Alt) */
330 1d4e547b balrog
    [0x2c] = 50,        /* M */
331 1d4e547b balrog
    [0x2f] = 66,        /* Zoom- (F8) */
332 1d4e547b balrog
333 1d4e547b balrog
    [0x31] = 19,        /* R */
334 1d4e547b balrog
    [0x32] = 29 | M,        /* Right Ctrl */
335 1d4e547b balrog
    [0x34] = 57,        /* Space */
336 1d4e547b balrog
    [0x35] = 51,        /* , (Comma) */
337 1d4e547b balrog
    [0x37] = 72 | M,        /* Up */
338 1d4e547b balrog
    [0x3c] = 82 | M,        /* Compose (Insert) */
339 1d4e547b balrog
    [0x3f] = 64,        /* FullScreen (F6) */
340 1d4e547b balrog
341 1d4e547b balrog
    [0x41] = 20,        /* T */
342 1d4e547b balrog
    [0x44] = 52,        /* . (Dot) */
343 1d4e547b balrog
    [0x46] = 77 | M,        /* Right */
344 1d4e547b balrog
    [0x4f] = 63,        /* Home (F5) */
345 1d4e547b balrog
    [0x51] = 21,        /* Y */
346 1d4e547b balrog
    [0x53] = 80 | M,        /* Down */
347 1d4e547b balrog
    [0x55] = 28,        /* Enter */
348 1d4e547b balrog
    [0x5f] =  1,        /* Cycle (ESC) */
349 1d4e547b balrog
350 1d4e547b balrog
    [0x61] = 22,        /* U */
351 1d4e547b balrog
    [0x64] = 75 | M,        /* Left */
352 1d4e547b balrog
353 1d4e547b balrog
    [0x71] = 23,        /* I */
354 1d4e547b balrog
#if 0
355 1d4e547b balrog
    [0x75] = 28 | M,        /* KP Enter (KP Enter) */
356 1d4e547b balrog
#else
357 1d4e547b balrog
    [0x75] = 15,        /* KP Enter (Tab) */
358 1d4e547b balrog
#endif
359 1d4e547b balrog
};
360 1d4e547b balrog
361 1d4e547b balrog
#undef M
362 1d4e547b balrog
363 1d4e547b balrog
static void n810_kbd_setup(struct n800_s *s)
364 1d4e547b balrog
{
365 1d4e547b balrog
    qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
366 1d4e547b balrog
    int i;
367 1d4e547b balrog
368 1d4e547b balrog
    for (i = 0; i < 0x80; i ++)
369 1d4e547b balrog
        s->keymap[i] = -1;
370 1d4e547b balrog
    for (i = 0; i < 0x80; i ++)
371 1d4e547b balrog
        if (n810_keys[i] > 0)
372 1d4e547b balrog
            s->keymap[n810_keys[i]] = i;
373 1d4e547b balrog
374 1d4e547b balrog
    qemu_add_kbd_event_handler(n810_key_event, s);
375 1d4e547b balrog
376 1d4e547b balrog
    /* Attach the LM8322 keyboard to the I2C bus,
377 1d4e547b balrog
     * should happen in n8x0_i2c_setup and s->kbd be initialised here.  */
378 1d4e547b balrog
    s->kbd = lm8323_init(s->i2c, kbd_irq);
379 1d4e547b balrog
    i2c_set_slave_address(s->kbd, N810_LM8323_ADDR);
380 1d4e547b balrog
}
381 1d4e547b balrog
382 7e7c5e4c balrog
/* LCD MIPI DBI-C controller (URAL) */
383 7e7c5e4c balrog
struct mipid_s {
384 7e7c5e4c balrog
    int resp[4];
385 7e7c5e4c balrog
    int param[4];
386 7e7c5e4c balrog
    int p;
387 7e7c5e4c balrog
    int pm;
388 7e7c5e4c balrog
    int cmd;
389 7e7c5e4c balrog
390 7e7c5e4c balrog
    int sleep;
391 7e7c5e4c balrog
    int booster;
392 7e7c5e4c balrog
    int te;
393 7e7c5e4c balrog
    int selfcheck;
394 7e7c5e4c balrog
    int partial;
395 7e7c5e4c balrog
    int normal;
396 7e7c5e4c balrog
    int vscr;
397 7e7c5e4c balrog
    int invert;
398 7e7c5e4c balrog
    int onoff;
399 7e7c5e4c balrog
    int gamma;
400 7e7c5e4c balrog
    uint32_t id;
401 7e7c5e4c balrog
};
402 7e7c5e4c balrog
403 7e7c5e4c balrog
static void mipid_reset(struct mipid_s *s)
404 7e7c5e4c balrog
{
405 7e7c5e4c balrog
    if (!s->sleep)
406 7e7c5e4c balrog
        fprintf(stderr, "%s: Display off\n", __FUNCTION__);
407 7e7c5e4c balrog
408 7e7c5e4c balrog
    s->pm = 0;
409 7e7c5e4c balrog
    s->cmd = 0;
410 7e7c5e4c balrog
411 7e7c5e4c balrog
    s->sleep = 1;
412 7e7c5e4c balrog
    s->booster = 0;
413 7e7c5e4c balrog
    s->selfcheck =
414 7e7c5e4c balrog
            (1 << 7) |        /* Register loading OK.  */
415 7e7c5e4c balrog
            (1 << 5) |        /* The chip is attached.  */
416 7e7c5e4c balrog
            (1 << 4);        /* Display glass still in one piece.  */
417 7e7c5e4c balrog
    s->te = 0;
418 7e7c5e4c balrog
    s->partial = 0;
419 7e7c5e4c balrog
    s->normal = 1;
420 7e7c5e4c balrog
    s->vscr = 0;
421 7e7c5e4c balrog
    s->invert = 0;
422 7e7c5e4c balrog
    s->onoff = 1;
423 7e7c5e4c balrog
    s->gamma = 0;
424 7e7c5e4c balrog
}
425 7e7c5e4c balrog
426 e927bb00 balrog
static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
427 7e7c5e4c balrog
{
428 7e7c5e4c balrog
    struct mipid_s *s = (struct mipid_s *) opaque;
429 7e7c5e4c balrog
    uint8_t ret;
430 7e7c5e4c balrog
431 e927bb00 balrog
    if (len > 9)
432 e927bb00 balrog
        cpu_abort(cpu_single_env, "%s: FIXME: bad SPI word width %i\n",
433 e927bb00 balrog
                        __FUNCTION__, len);
434 e927bb00 balrog
435 7e7c5e4c balrog
    if (s->p >= sizeof(s->resp) / sizeof(*s->resp))
436 7e7c5e4c balrog
        ret = 0;
437 7e7c5e4c balrog
    else
438 7e7c5e4c balrog
        ret = s->resp[s->p ++];
439 7e7c5e4c balrog
    if (s->pm --> 0)
440 7e7c5e4c balrog
        s->param[s->pm] = cmd;
441 7e7c5e4c balrog
    else
442 7e7c5e4c balrog
        s->cmd = cmd;
443 7e7c5e4c balrog
444 7e7c5e4c balrog
    switch (s->cmd) {
445 7e7c5e4c balrog
    case 0x00:        /* NOP */
446 7e7c5e4c balrog
        break;
447 7e7c5e4c balrog
448 7e7c5e4c balrog
    case 0x01:        /* SWRESET */
449 7e7c5e4c balrog
        mipid_reset(s);
450 7e7c5e4c balrog
        break;
451 7e7c5e4c balrog
452 7e7c5e4c balrog
    case 0x02:        /* BSTROFF */
453 7e7c5e4c balrog
        s->booster = 0;
454 7e7c5e4c balrog
        break;
455 7e7c5e4c balrog
    case 0x03:        /* BSTRON */
456 7e7c5e4c balrog
        s->booster = 1;
457 7e7c5e4c balrog
        break;
458 7e7c5e4c balrog
459 7e7c5e4c balrog
    case 0x04:        /* RDDID */
460 7e7c5e4c balrog
        s->p = 0;
461 7e7c5e4c balrog
        s->resp[0] = (s->id >> 16) & 0xff;
462 7e7c5e4c balrog
        s->resp[1] = (s->id >>  8) & 0xff;
463 7e7c5e4c balrog
        s->resp[2] = (s->id >>  0) & 0xff;
464 7e7c5e4c balrog
        break;
465 7e7c5e4c balrog
466 7e7c5e4c balrog
    case 0x06:        /* RD_RED */
467 7e7c5e4c balrog
    case 0x07:        /* RD_GREEN */
468 7e7c5e4c balrog
        /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
469 7e7c5e4c balrog
         * for the bootloader one needs to change this.  */
470 7e7c5e4c balrog
    case 0x08:        /* RD_BLUE */
471 7e7c5e4c balrog
        s->p = 0;
472 7e7c5e4c balrog
        /* TODO: return first pixel components */
473 7e7c5e4c balrog
        s->resp[0] = 0x01;
474 7e7c5e4c balrog
        break;
475 7e7c5e4c balrog
476 7e7c5e4c balrog
    case 0x09:        /* RDDST */
477 7e7c5e4c balrog
        s->p = 0;
478 7e7c5e4c balrog
        s->resp[0] = s->booster << 7;
479 7e7c5e4c balrog
        s->resp[1] = (5 << 4) | (s->partial << 2) |
480 7e7c5e4c balrog
                (s->sleep << 1) | s->normal;
481 7e7c5e4c balrog
        s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
482 7e7c5e4c balrog
                (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
483 7e7c5e4c balrog
        s->resp[3] = s->gamma << 6;
484 7e7c5e4c balrog
        break;
485 7e7c5e4c balrog
486 7e7c5e4c balrog
    case 0x0a:        /* RDDPM */
487 7e7c5e4c balrog
        s->p = 0;
488 7e7c5e4c balrog
        s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
489 7e7c5e4c balrog
                (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
490 7e7c5e4c balrog
        break;
491 7e7c5e4c balrog
    case 0x0b:        /* RDDMADCTR */
492 7e7c5e4c balrog
        s->p = 0;
493 7e7c5e4c balrog
        s->resp[0] = 0;
494 7e7c5e4c balrog
        break;
495 7e7c5e4c balrog
    case 0x0c:        /* RDDCOLMOD */
496 7e7c5e4c balrog
        s->p = 0;
497 7e7c5e4c balrog
        s->resp[0] = 5;        /* 65K colours */
498 7e7c5e4c balrog
        break;
499 7e7c5e4c balrog
    case 0x0d:        /* RDDIM */
500 7e7c5e4c balrog
        s->p = 0;
501 7e7c5e4c balrog
        s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
502 7e7c5e4c balrog
        break;
503 7e7c5e4c balrog
    case 0x0e:        /* RDDSM */
504 7e7c5e4c balrog
        s->p = 0;
505 7e7c5e4c balrog
        s->resp[0] = s->te << 7;
506 7e7c5e4c balrog
        break;
507 7e7c5e4c balrog
    case 0x0f:        /* RDDSDR */
508 7e7c5e4c balrog
        s->p = 0;
509 7e7c5e4c balrog
        s->resp[0] = s->selfcheck;
510 7e7c5e4c balrog
        break;
511 7e7c5e4c balrog
512 7e7c5e4c balrog
    case 0x10:        /* SLPIN */
513 7e7c5e4c balrog
        s->sleep = 1;
514 7e7c5e4c balrog
        break;
515 7e7c5e4c balrog
    case 0x11:        /* SLPOUT */
516 7e7c5e4c balrog
        s->sleep = 0;
517 7e7c5e4c balrog
        s->selfcheck ^= 1 << 6;        /* POFF self-diagnosis Ok */
518 7e7c5e4c balrog
        break;
519 7e7c5e4c balrog
520 7e7c5e4c balrog
    case 0x12:        /* PTLON */
521 7e7c5e4c balrog
        s->partial = 1;
522 7e7c5e4c balrog
        s->normal = 0;
523 7e7c5e4c balrog
        s->vscr = 0;
524 7e7c5e4c balrog
        break;
525 7e7c5e4c balrog
    case 0x13:        /* NORON */
526 7e7c5e4c balrog
        s->partial = 0;
527 7e7c5e4c balrog
        s->normal = 1;
528 7e7c5e4c balrog
        s->vscr = 0;
529 7e7c5e4c balrog
        break;
530 7e7c5e4c balrog
531 7e7c5e4c balrog
    case 0x20:        /* INVOFF */
532 7e7c5e4c balrog
        s->invert = 0;
533 7e7c5e4c balrog
        break;
534 7e7c5e4c balrog
    case 0x21:        /* INVON */
535 7e7c5e4c balrog
        s->invert = 1;
536 7e7c5e4c balrog
        break;
537 7e7c5e4c balrog
538 7e7c5e4c balrog
    case 0x22:        /* APOFF */
539 7e7c5e4c balrog
    case 0x23:        /* APON */
540 7e7c5e4c balrog
        goto bad_cmd;
541 7e7c5e4c balrog
542 7e7c5e4c balrog
    case 0x25:        /* WRCNTR */
543 7e7c5e4c balrog
        if (s->pm < 0)
544 7e7c5e4c balrog
            s->pm = 1;
545 7e7c5e4c balrog
        goto bad_cmd;
546 7e7c5e4c balrog
547 7e7c5e4c balrog
    case 0x26:        /* GAMSET */
548 7e7c5e4c balrog
        if (!s->pm)
549 7e7c5e4c balrog
            s->gamma = ffs(s->param[0] & 0xf) - 1;
550 7e7c5e4c balrog
        else if (s->pm < 0)
551 7e7c5e4c balrog
            s->pm = 1;
552 7e7c5e4c balrog
        break;
553 7e7c5e4c balrog
554 7e7c5e4c balrog
    case 0x28:        /* DISPOFF */
555 7e7c5e4c balrog
        s->onoff = 0;
556 7e7c5e4c balrog
        fprintf(stderr, "%s: Display off\n", __FUNCTION__);
557 7e7c5e4c balrog
        break;
558 7e7c5e4c balrog
    case 0x29:        /* DISPON */
559 7e7c5e4c balrog
        s->onoff = 1;
560 7e7c5e4c balrog
        fprintf(stderr, "%s: Display on\n", __FUNCTION__);
561 7e7c5e4c balrog
        break;
562 7e7c5e4c balrog
563 7e7c5e4c balrog
    case 0x2a:        /* CASET */
564 7e7c5e4c balrog
    case 0x2b:        /* RASET */
565 7e7c5e4c balrog
    case 0x2c:        /* RAMWR */
566 7e7c5e4c balrog
    case 0x2d:        /* RGBSET */
567 7e7c5e4c balrog
    case 0x2e:        /* RAMRD */
568 7e7c5e4c balrog
    case 0x30:        /* PTLAR */
569 7e7c5e4c balrog
    case 0x33:        /* SCRLAR */
570 7e7c5e4c balrog
        goto bad_cmd;
571 7e7c5e4c balrog
572 7e7c5e4c balrog
    case 0x34:        /* TEOFF */
573 7e7c5e4c balrog
        s->te = 0;
574 7e7c5e4c balrog
        break;
575 7e7c5e4c balrog
    case 0x35:        /* TEON */
576 7e7c5e4c balrog
        if (!s->pm)
577 7e7c5e4c balrog
            s->te = 1;
578 7e7c5e4c balrog
        else if (s->pm < 0)
579 7e7c5e4c balrog
            s->pm = 1;
580 7e7c5e4c balrog
        break;
581 7e7c5e4c balrog
582 7e7c5e4c balrog
    case 0x36:        /* MADCTR */
583 7e7c5e4c balrog
        goto bad_cmd;
584 7e7c5e4c balrog
585 7e7c5e4c balrog
    case 0x37:        /* VSCSAD */
586 7e7c5e4c balrog
        s->partial = 0;
587 7e7c5e4c balrog
        s->normal = 0;
588 7e7c5e4c balrog
        s->vscr = 1;
589 7e7c5e4c balrog
        break;
590 7e7c5e4c balrog
591 7e7c5e4c balrog
    case 0x38:        /* IDMOFF */
592 7e7c5e4c balrog
    case 0x39:        /* IDMON */
593 7e7c5e4c balrog
    case 0x3a:        /* COLMOD */
594 7e7c5e4c balrog
        goto bad_cmd;
595 7e7c5e4c balrog
596 7e7c5e4c balrog
    case 0xb0:        /* CLKINT / DISCTL */
597 7e7c5e4c balrog
    case 0xb1:        /* CLKEXT */
598 7e7c5e4c balrog
        if (s->pm < 0)
599 7e7c5e4c balrog
            s->pm = 2;
600 7e7c5e4c balrog
        break;
601 7e7c5e4c balrog
602 7e7c5e4c balrog
    case 0xb4:        /* FRMSEL */
603 7e7c5e4c balrog
        break;
604 7e7c5e4c balrog
605 7e7c5e4c balrog
    case 0xb5:        /* FRM8SEL */
606 7e7c5e4c balrog
    case 0xb6:        /* TMPRNG / INIESC */
607 7e7c5e4c balrog
    case 0xb7:        /* TMPHIS / NOP2 */
608 7e7c5e4c balrog
    case 0xb8:        /* TMPREAD / MADCTL */
609 7e7c5e4c balrog
    case 0xba:        /* DISTCTR */
610 7e7c5e4c balrog
    case 0xbb:        /* EPVOL */
611 7e7c5e4c balrog
        goto bad_cmd;
612 7e7c5e4c balrog
613 7e7c5e4c balrog
    case 0xbd:        /* Unknown */
614 7e7c5e4c balrog
        s->p = 0;
615 7e7c5e4c balrog
        s->resp[0] = 0;
616 7e7c5e4c balrog
        s->resp[1] = 1;
617 7e7c5e4c balrog
        break;
618 7e7c5e4c balrog
619 7e7c5e4c balrog
    case 0xc2:        /* IFMOD */
620 7e7c5e4c balrog
        if (s->pm < 0)
621 7e7c5e4c balrog
            s->pm = 2;
622 7e7c5e4c balrog
        break;
623 7e7c5e4c balrog
624 7e7c5e4c balrog
    case 0xc6:        /* PWRCTL */
625 7e7c5e4c balrog
    case 0xc7:        /* PPWRCTL */
626 7e7c5e4c balrog
    case 0xd0:        /* EPWROUT */
627 7e7c5e4c balrog
    case 0xd1:        /* EPWRIN */
628 7e7c5e4c balrog
    case 0xd4:        /* RDEV */
629 7e7c5e4c balrog
    case 0xd5:        /* RDRR */
630 7e7c5e4c balrog
        goto bad_cmd;
631 7e7c5e4c balrog
632 7e7c5e4c balrog
    case 0xda:        /* RDID1 */
633 7e7c5e4c balrog
        s->p = 0;
634 7e7c5e4c balrog
        s->resp[0] = (s->id >> 16) & 0xff;
635 7e7c5e4c balrog
        break;
636 7e7c5e4c balrog
    case 0xdb:        /* RDID2 */
637 7e7c5e4c balrog
        s->p = 0;
638 7e7c5e4c balrog
        s->resp[0] = (s->id >>  8) & 0xff;
639 7e7c5e4c balrog
        break;
640 7e7c5e4c balrog
    case 0xdc:        /* RDID3 */
641 7e7c5e4c balrog
        s->p = 0;
642 7e7c5e4c balrog
        s->resp[0] = (s->id >>  0) & 0xff;
643 7e7c5e4c balrog
        break;
644 7e7c5e4c balrog
645 7e7c5e4c balrog
    default:
646 7e7c5e4c balrog
    bad_cmd:
647 7e7c5e4c balrog
        fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd);
648 7e7c5e4c balrog
        break;
649 7e7c5e4c balrog
    }
650 7e7c5e4c balrog
651 7e7c5e4c balrog
    return ret;
652 7e7c5e4c balrog
}
653 7e7c5e4c balrog
654 7e7c5e4c balrog
static void *mipid_init(void)
655 7e7c5e4c balrog
{
656 7e7c5e4c balrog
    struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
657 7e7c5e4c balrog
658 7e7c5e4c balrog
    s->id = 0x838f03;
659 7e7c5e4c balrog
    mipid_reset(s);
660 7e7c5e4c balrog
661 7e7c5e4c balrog
    return s;
662 7e7c5e4c balrog
}
663 7e7c5e4c balrog
664 e927bb00 balrog
static void n8x0_spi_setup(struct n800_s *s)
665 7e7c5e4c balrog
{
666 e927bb00 balrog
    void *tsc = s->ts.opaque;
667 7e7c5e4c balrog
    void *mipid = mipid_init();
668 7e7c5e4c balrog
669 e927bb00 balrog
    omap_mcspi_attach(s->cpu->mcspi[0], s->ts.txrx, tsc, 0);
670 7e7c5e4c balrog
    omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1);
671 7e7c5e4c balrog
}
672 7e7c5e4c balrog
673 7e7c5e4c balrog
/* This task is normally performed by the bootloader.  If we're loading
674 7e7c5e4c balrog
 * a kernel directly, we need to enable the Blizzard ourselves.  */
675 7e7c5e4c balrog
static void n800_dss_init(struct rfbi_chip_s *chip)
676 7e7c5e4c balrog
{
677 7e7c5e4c balrog
    uint8_t *fb_blank;
678 7e7c5e4c balrog
679 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x2a);                /* LCD Width register */
680 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x64);
681 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x2c);                /* LCD HNDP register */
682 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x1e);
683 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x2e);                /* LCD Height 0 register */
684 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0xe0);
685 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x30);                /* LCD Height 1 register */
686 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x01);
687 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x32);                /* LCD VNDP register */
688 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x06);
689 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x68);                /* Display Mode register */
690 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 1);                /* Enable bit */
691 7e7c5e4c balrog
692 7e7c5e4c balrog
    chip->write(chip->opaque, 0, 0x6c);        
693 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Input X Start Position */
694 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Input X Start Position */
695 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Input Y Start Position */
696 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Input Y Start Position */
697 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x1f);                /* Input X End Position */
698 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x03);                /* Input X End Position */
699 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0xdf);                /* Input Y End Position */
700 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x01);                /* Input Y End Position */
701 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Output X Start Position */
702 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Output X Start Position */
703 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Output Y Start Position */
704 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x00);                /* Output Y Start Position */
705 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x1f);                /* Output X End Position */
706 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x03);                /* Output X End Position */
707 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0xdf);                /* Output Y End Position */
708 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x01);                /* Output Y End Position */
709 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x01);                /* Input Data Format */
710 7e7c5e4c balrog
    chip->write(chip->opaque, 1, 0x01);                /* Data Source Select */
711 7e7c5e4c balrog
712 7e7c5e4c balrog
    fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
713 7e7c5e4c balrog
    /* Display Memory Data Port */
714 7e7c5e4c balrog
    chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
715 7e7c5e4c balrog
    free(fb_blank);
716 7e7c5e4c balrog
}
717 7e7c5e4c balrog
718 e927bb00 balrog
static void n8x0_dss_setup(struct n800_s *s, DisplayState *ds)
719 7e7c5e4c balrog
{
720 7e7c5e4c balrog
    s->blizzard.opaque = s1d13745_init(0, ds);
721 7e7c5e4c balrog
    s->blizzard.block = s1d13745_write_block;
722 7e7c5e4c balrog
    s->blizzard.write = s1d13745_write;
723 7e7c5e4c balrog
    s->blizzard.read = s1d13745_read;
724 7e7c5e4c balrog
725 7e7c5e4c balrog
    omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard);
726 7e7c5e4c balrog
}
727 7e7c5e4c balrog
728 e927bb00 balrog
static void n8x0_cbus_setup(struct n800_s *s)
729 7e7c5e4c balrog
{
730 7e7c5e4c balrog
    qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
731 7e7c5e4c balrog
    qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
732 7e7c5e4c balrog
    qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
733 7e7c5e4c balrog
734 7e7c5e4c balrog
    struct cbus_s *cbus = cbus_init(dat_out);
735 7e7c5e4c balrog
736 7e7c5e4c balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
737 7e7c5e4c balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
738 7e7c5e4c balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
739 7e7c5e4c balrog
740 7e7c5e4c balrog
    cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
741 7e7c5e4c balrog
    cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
742 7e7c5e4c balrog
}
743 7e7c5e4c balrog
744 58a26b47 balrog
static void n8x0_uart_setup(struct n800_s *s)
745 58a26b47 balrog
{
746 58a26b47 balrog
    CharDriverState *radio = uart_hci_init(
747 58a26b47 balrog
                    omap2_gpio_in_get(s->cpu->gpif,
748 58a26b47 balrog
                            N8X0_BT_HOST_WKUP_GPIO)[0]);
749 58a26b47 balrog
750 58a26b47 balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO,
751 58a26b47 balrog
                    csrhci_pins_get(radio)[csrhci_pin_reset]);
752 58a26b47 balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO,
753 58a26b47 balrog
                    csrhci_pins_get(radio)[csrhci_pin_wakeup]);
754 58a26b47 balrog
755 58a26b47 balrog
    omap_uart_attach(s->cpu->uart[BT_UART], radio);
756 58a26b47 balrog
}
757 58a26b47 balrog
758 e927bb00 balrog
static void n8x0_usb_power_cb(void *opaque, int line, int level)
759 942ac052 balrog
{
760 942ac052 balrog
    struct n800_s *s = opaque;
761 942ac052 balrog
762 942ac052 balrog
    tusb6010_power(s->usb, level);
763 942ac052 balrog
}
764 942ac052 balrog
765 e927bb00 balrog
static void n8x0_usb_setup(struct n800_s *s)
766 942ac052 balrog
{
767 942ac052 balrog
    qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
768 e927bb00 balrog
    qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
769 942ac052 balrog
    struct tusb_s *tusb = tusb6010_init(tusb_irq);
770 942ac052 balrog
771 942ac052 balrog
    /* Using the NOR interface */
772 942ac052 balrog
    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
773 942ac052 balrog
                    tusb6010_async_io(tusb), 0, 0, tusb);
774 942ac052 balrog
    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
775 942ac052 balrog
                    tusb6010_sync_io(tusb), 0, 0, tusb);
776 942ac052 balrog
777 942ac052 balrog
    s->usb = tusb;
778 e927bb00 balrog
    omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
779 942ac052 balrog
}
780 942ac052 balrog
781 d238db7f balrog
/* Setup done before the main bootloader starts by some early setup code
782 d238db7f balrog
 * - used when we want to run the main bootloader in emulation.  This
783 d238db7f balrog
 * isn't documented.  */
784 d238db7f balrog
static uint32_t n800_pinout[104] = {
785 d238db7f balrog
    0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
786 d238db7f balrog
    0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
787 d238db7f balrog
    0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
788 d238db7f balrog
    0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
789 d238db7f balrog
    0x01241800, 0x18181818, 0x000000f0, 0x01300000,
790 d238db7f balrog
    0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
791 d238db7f balrog
    0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
792 d238db7f balrog
    0x007c0000, 0x00000000, 0x00000088, 0x00840000,
793 d238db7f balrog
    0x00000000, 0x00000094, 0x00980300, 0x0f180003,
794 d238db7f balrog
    0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
795 d238db7f balrog
    0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
796 d238db7f balrog
    0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
797 d238db7f balrog
    0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
798 d238db7f balrog
    0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
799 d238db7f balrog
    0x00000000, 0x00000038, 0x00340000, 0x00000000,
800 d238db7f balrog
    0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
801 d238db7f balrog
    0x005c0808, 0x08080808, 0x08080058, 0x00540808,
802 d238db7f balrog
    0x08080808, 0x0808006c, 0x00680808, 0x08080808,
803 d238db7f balrog
    0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
804 d238db7f balrog
    0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
805 d238db7f balrog
    0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
806 d238db7f balrog
    0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
807 d238db7f balrog
    0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
808 d238db7f balrog
    0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
809 d238db7f balrog
    0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
810 d238db7f balrog
    0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
811 d238db7f balrog
};
812 d238db7f balrog
813 d238db7f balrog
static void n800_setup_nolo_tags(void *sram_base)
814 d238db7f balrog
{
815 d238db7f balrog
    int i;
816 d238db7f balrog
    uint32_t *p = sram_base + 0x8000;
817 d238db7f balrog
    uint32_t *v = sram_base + 0xa000;
818 d238db7f balrog
819 d238db7f balrog
    memset(p, 0, 0x3000);
820 d238db7f balrog
821 d238db7f balrog
    strcpy((void *) (p + 0), "QEMU N800");
822 d238db7f balrog
823 d238db7f balrog
    strcpy((void *) (p + 8), "F5");
824 d238db7f balrog
825 d238db7f balrog
    stl_raw(p + 10, 0x04f70000);
826 d238db7f balrog
    strcpy((void *) (p + 9), "RX-34");
827 d238db7f balrog
828 d238db7f balrog
    /* RAM size in MB? */
829 d238db7f balrog
    stl_raw(p + 12, 0x80);
830 d238db7f balrog
831 d238db7f balrog
    /* Pointer to the list of tags */
832 d238db7f balrog
    stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
833 d238db7f balrog
834 d238db7f balrog
    /* The NOLO tags start here */
835 d238db7f balrog
    p = sram_base + 0x9000;
836 d238db7f balrog
#define ADD_TAG(tag, len)                                \
837 d238db7f balrog
    stw_raw((uint16_t *) p + 0, tag);                        \
838 d238db7f balrog
    stw_raw((uint16_t *) p + 1, len); p ++;                \
839 d238db7f balrog
    stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
840 d238db7f balrog
841 d238db7f balrog
    /* OMAP STI console? Pin out settings? */
842 d238db7f balrog
    ADD_TAG(0x6e01, 414);
843 d238db7f balrog
    for (i = 0; i < sizeof(n800_pinout) / 4; i ++)
844 d238db7f balrog
        stl_raw(v ++, n800_pinout[i]);
845 d238db7f balrog
846 d238db7f balrog
    /* Kernel memsize? */
847 d238db7f balrog
    ADD_TAG(0x6e05, 1);
848 d238db7f balrog
    stl_raw(v ++, 2);
849 d238db7f balrog
850 d238db7f balrog
    /* NOLO serial console */
851 d238db7f balrog
    ADD_TAG(0x6e02, 4);
852 d238db7f balrog
    stl_raw(v ++, XLDR_LL_UART);        /* UART number (1 - 3) */
853 d238db7f balrog
854 d238db7f balrog
#if 0
855 d238db7f balrog
    /* CBUS settings (Retu/AVilma) */
856 d238db7f balrog
    ADD_TAG(0x6e03, 6);
857 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 65);        /* CBUS GPIO0 */
858 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 66);        /* CBUS GPIO1 */
859 d238db7f balrog
    stw_raw((uint16_t *) v + 2, 64);        /* CBUS GPIO2 */
860 d238db7f balrog
    v += 2;
861 d238db7f balrog
#endif
862 d238db7f balrog
863 d238db7f balrog
    /* Nokia ASIC BB5 (Retu/Tahvo) */
864 d238db7f balrog
    ADD_TAG(0x6e0a, 4);
865 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 111);        /* "Retu" interrupt GPIO */
866 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 108);        /* "Tahvo" interrupt GPIO */
867 d238db7f balrog
    v ++;
868 d238db7f balrog
869 d238db7f balrog
    /* LCD console? */
870 d238db7f balrog
    ADD_TAG(0x6e04, 4);
871 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 30);        /* ??? */
872 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 24);        /* ??? */
873 d238db7f balrog
    v ++;
874 d238db7f balrog
875 d238db7f balrog
#if 0
876 d238db7f balrog
    /* LCD settings */
877 d238db7f balrog
    ADD_TAG(0x6e06, 2);
878 d238db7f balrog
    stw_raw((uint16_t *) (v ++), 15);        /* ??? */
879 d238db7f balrog
#endif
880 d238db7f balrog
881 d238db7f balrog
    /* I^2C (Menelaus) */
882 d238db7f balrog
    ADD_TAG(0x6e07, 4);
883 d238db7f balrog
    stl_raw(v ++, 0x00720000);                /* ??? */
884 d238db7f balrog
885 d238db7f balrog
    /* Unknown */
886 d238db7f balrog
    ADD_TAG(0x6e0b, 6);
887 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 94);        /* ??? */
888 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 23);        /* ??? */
889 d238db7f balrog
    stw_raw((uint16_t *) v + 2, 0);        /* ??? */
890 d238db7f balrog
    v += 2;
891 d238db7f balrog
892 d238db7f balrog
    /* OMAP gpio switch info */
893 d238db7f balrog
    ADD_TAG(0x6e0c, 80);
894 d238db7f balrog
    strcpy((void *) v, "bat_cover");        v += 3;
895 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 110);        /* GPIO num ??? */
896 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 1);        /* GPIO num ??? */
897 d238db7f balrog
    v += 2;
898 d238db7f balrog
    strcpy((void *) v, "cam_act");        v += 3;
899 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 95);        /* GPIO num ??? */
900 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 32);        /* GPIO num ??? */
901 d238db7f balrog
    v += 2;
902 d238db7f balrog
    strcpy((void *) v, "cam_turn");        v += 3;
903 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 12);        /* GPIO num ??? */
904 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 33);        /* GPIO num ??? */
905 d238db7f balrog
    v += 2;
906 d238db7f balrog
    strcpy((void *) v, "headphone");        v += 3;
907 d238db7f balrog
    stw_raw((uint16_t *) v + 0, 107);        /* GPIO num ??? */
908 d238db7f balrog
    stw_raw((uint16_t *) v + 1, 17);        /* GPIO num ??? */
909 d238db7f balrog
    v += 2;
910 d238db7f balrog
911 d238db7f balrog
    /* Bluetooth */
912 d238db7f balrog
    ADD_TAG(0x6e0e, 12);
913 d238db7f balrog
    stl_raw(v ++, 0x5c623d01);                /* ??? */
914 d238db7f balrog
    stl_raw(v ++, 0x00000201);                /* ??? */
915 d238db7f balrog
    stl_raw(v ++, 0x00000000);                /* ??? */
916 d238db7f balrog
917 d238db7f balrog
    /* CX3110x WLAN settings */
918 d238db7f balrog
    ADD_TAG(0x6e0f, 8);
919 d238db7f balrog
    stl_raw(v ++, 0x00610025);                /* ??? */
920 d238db7f balrog
    stl_raw(v ++, 0xffff0057);                /* ??? */
921 d238db7f balrog
922 d238db7f balrog
    /* MMC host settings */
923 d238db7f balrog
    ADD_TAG(0x6e10, 12);
924 d238db7f balrog
    stl_raw(v ++, 0xffff000f);                /* ??? */
925 d238db7f balrog
    stl_raw(v ++, 0xffffffff);                /* ??? */
926 d238db7f balrog
    stl_raw(v ++, 0x00000060);                /* ??? */
927 d238db7f balrog
928 d238db7f balrog
    /* OneNAND chip select */
929 d238db7f balrog
    ADD_TAG(0x6e11, 10);
930 d238db7f balrog
    stl_raw(v ++, 0x00000401);                /* ??? */
931 d238db7f balrog
    stl_raw(v ++, 0x0002003a);                /* ??? */
932 d238db7f balrog
    stl_raw(v ++, 0x00000002);                /* ??? */
933 d238db7f balrog
934 d238db7f balrog
    /* TEA5761 sensor settings */
935 d238db7f balrog
    ADD_TAG(0x6e12, 2);
936 d238db7f balrog
    stl_raw(v ++, 93);                        /* GPIO num ??? */
937 d238db7f balrog
938 d238db7f balrog
#if 0
939 d238db7f balrog
    /* Unknown tag */
940 d238db7f balrog
    ADD_TAG(6e09, 0);
941 d238db7f balrog

942 d238db7f balrog
    /* Kernel UART / console */
943 d238db7f balrog
    ADD_TAG(6e12, 0);
944 d238db7f balrog
#endif
945 d238db7f balrog
946 d238db7f balrog
    /* End of the list */
947 d238db7f balrog
    stl_raw(p ++, 0x00000000);
948 d238db7f balrog
    stl_raw(p ++, 0x00000000);
949 d238db7f balrog
}
950 d238db7f balrog
951 7e7c5e4c balrog
/* This task is normally performed by the bootloader.  If we're loading
952 7e7c5e4c balrog
 * a kernel directly, we need to set up GPMC mappings ourselves.  */
953 7e7c5e4c balrog
static void n800_gpmc_init(struct n800_s *s)
954 7e7c5e4c balrog
{
955 7e7c5e4c balrog
    uint32_t config7 =
956 7e7c5e4c balrog
            (0xf << 8) |        /* MASKADDRESS */
957 7e7c5e4c balrog
            (1 << 6) |                /* CSVALID */
958 7e7c5e4c balrog
            (4 << 0);                /* BASEADDRESS */
959 7e7c5e4c balrog
960 7e7c5e4c balrog
    cpu_physical_memory_write(0x6800a078,                /* GPMC_CONFIG7_0 */
961 7e7c5e4c balrog
                    (void *) &config7, sizeof(config7));
962 7e7c5e4c balrog
}
963 7e7c5e4c balrog
964 7e7c5e4c balrog
/* Setup sequence done by the bootloader */
965 e927bb00 balrog
static void n8x0_boot_init(void *opaque)
966 7e7c5e4c balrog
{
967 7e7c5e4c balrog
    struct n800_s *s = (struct n800_s *) opaque;
968 7e7c5e4c balrog
    uint32_t buf;
969 7e7c5e4c balrog
970 7e7c5e4c balrog
    /* PRCM setup */
971 7e7c5e4c balrog
#define omap_writel(addr, val)        \
972 7e7c5e4c balrog
    buf = (val);                        \
973 7e7c5e4c balrog
    cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
974 7e7c5e4c balrog
975 7e7c5e4c balrog
    omap_writel(0x48008060, 0x41);                /* PRCM_CLKSRC_CTRL */
976 7e7c5e4c balrog
    omap_writel(0x48008070, 1);                        /* PRCM_CLKOUT_CTRL */
977 7e7c5e4c balrog
    omap_writel(0x48008078, 0);                        /* PRCM_CLKEMUL_CTRL */
978 7e7c5e4c balrog
    omap_writel(0x48008090, 0);                        /* PRCM_VOLTSETUP */
979 7e7c5e4c balrog
    omap_writel(0x48008094, 0);                        /* PRCM_CLKSSETUP */
980 7e7c5e4c balrog
    omap_writel(0x48008098, 0);                        /* PRCM_POLCTRL */
981 7e7c5e4c balrog
    omap_writel(0x48008140, 2);                        /* CM_CLKSEL_MPU */
982 7e7c5e4c balrog
    omap_writel(0x48008148, 0);                        /* CM_CLKSTCTRL_MPU */
983 7e7c5e4c balrog
    omap_writel(0x48008158, 1);                        /* RM_RSTST_MPU */
984 7e7c5e4c balrog
    omap_writel(0x480081c8, 0x15);                /* PM_WKDEP_MPU */
985 7e7c5e4c balrog
    omap_writel(0x480081d4, 0x1d4);                /* PM_EVGENCTRL_MPU */
986 7e7c5e4c balrog
    omap_writel(0x480081d8, 0);                        /* PM_EVEGENONTIM_MPU */
987 7e7c5e4c balrog
    omap_writel(0x480081dc, 0);                        /* PM_EVEGENOFFTIM_MPU */
988 7e7c5e4c balrog
    omap_writel(0x480081e0, 0xc);                /* PM_PWSTCTRL_MPU */
989 7e7c5e4c balrog
    omap_writel(0x48008200, 0x047e7ff7);        /* CM_FCLKEN1_CORE */
990 7e7c5e4c balrog
    omap_writel(0x48008204, 0x00000004);        /* CM_FCLKEN2_CORE */
991 7e7c5e4c balrog
    omap_writel(0x48008210, 0x047e7ff1);        /* CM_ICLKEN1_CORE */
992 7e7c5e4c balrog
    omap_writel(0x48008214, 0x00000004);        /* CM_ICLKEN2_CORE */
993 7e7c5e4c balrog
    omap_writel(0x4800821c, 0x00000000);        /* CM_ICLKEN4_CORE */
994 7e7c5e4c balrog
    omap_writel(0x48008230, 0);                        /* CM_AUTOIDLE1_CORE */
995 7e7c5e4c balrog
    omap_writel(0x48008234, 0);                        /* CM_AUTOIDLE2_CORE */
996 7e7c5e4c balrog
    omap_writel(0x48008238, 7);                        /* CM_AUTOIDLE3_CORE */
997 7e7c5e4c balrog
    omap_writel(0x4800823c, 0);                        /* CM_AUTOIDLE4_CORE */
998 7e7c5e4c balrog
    omap_writel(0x48008240, 0x04360626);        /* CM_CLKSEL1_CORE */
999 7e7c5e4c balrog
    omap_writel(0x48008244, 0x00000014);        /* CM_CLKSEL2_CORE */
1000 7e7c5e4c balrog
    omap_writel(0x48008248, 0);                        /* CM_CLKSTCTRL_CORE */
1001 7e7c5e4c balrog
    omap_writel(0x48008300, 0x00000000);        /* CM_FCLKEN_GFX */
1002 7e7c5e4c balrog
    omap_writel(0x48008310, 0x00000000);        /* CM_ICLKEN_GFX */
1003 7e7c5e4c balrog
    omap_writel(0x48008340, 0x00000001);        /* CM_CLKSEL_GFX */
1004 7e7c5e4c balrog
    omap_writel(0x48008400, 0x00000004);        /* CM_FCLKEN_WKUP */
1005 7e7c5e4c balrog
    omap_writel(0x48008410, 0x00000004);        /* CM_ICLKEN_WKUP */
1006 7e7c5e4c balrog
    omap_writel(0x48008440, 0x00000000);        /* CM_CLKSEL_WKUP */
1007 7e7c5e4c balrog
    omap_writel(0x48008500, 0x000000cf);        /* CM_CLKEN_PLL */
1008 7e7c5e4c balrog
    omap_writel(0x48008530, 0x0000000c);        /* CM_AUTOIDLE_PLL */
1009 7e7c5e4c balrog
    omap_writel(0x48008540,                        /* CM_CLKSEL1_PLL */
1010 7e7c5e4c balrog
                    (0x78 << 12) | (6 << 8));
1011 7e7c5e4c balrog
    omap_writel(0x48008544, 2);                        /* CM_CLKSEL2_PLL */
1012 7e7c5e4c balrog
1013 7e7c5e4c balrog
    /* GPMC setup */
1014 7e7c5e4c balrog
    n800_gpmc_init(s);
1015 7e7c5e4c balrog
1016 7e7c5e4c balrog
    /* Video setup */
1017 7e7c5e4c balrog
    n800_dss_init(&s->blizzard);
1018 7e7c5e4c balrog
1019 7e7c5e4c balrog
    /* CPU setup */
1020 7e7c5e4c balrog
    s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
1021 7e7c5e4c balrog
    s->cpu->env->GE = 0x5;
1022 0941041e balrog
1023 0941041e balrog
    /* If the machine has a slided keyboard, open it */
1024 0941041e balrog
    if (s->kbd)
1025 0941041e balrog
        qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]);
1026 7e7c5e4c balrog
}
1027 7e7c5e4c balrog
1028 7e7c5e4c balrog
#define OMAP_TAG_NOKIA_BT        0x4e01
1029 7e7c5e4c balrog
#define OMAP_TAG_WLAN_CX3110X        0x4e02
1030 7e7c5e4c balrog
#define OMAP_TAG_CBUS                0x4e03
1031 7e7c5e4c balrog
#define OMAP_TAG_EM_ASIC_BB5        0x4e04
1032 7e7c5e4c balrog
1033 e927bb00 balrog
static struct omap_gpiosw_info_s {
1034 e927bb00 balrog
    const char *name;
1035 e927bb00 balrog
    int line;
1036 e927bb00 balrog
    int type;
1037 e927bb00 balrog
} n800_gpiosw_info[] = {
1038 e927bb00 balrog
    {
1039 e927bb00 balrog
        "bat_cover", N800_BAT_COVER_GPIO,
1040 e927bb00 balrog
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1041 e927bb00 balrog
    }, {
1042 e927bb00 balrog
        "cam_act", N800_CAM_ACT_GPIO,
1043 e927bb00 balrog
        OMAP_GPIOSW_TYPE_ACTIVITY,
1044 e927bb00 balrog
    }, {
1045 e927bb00 balrog
        "cam_turn", N800_CAM_TURN_GPIO,
1046 e927bb00 balrog
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
1047 e927bb00 balrog
    }, {
1048 e927bb00 balrog
        "headphone", N8X0_HEADPHONE_GPIO,
1049 e927bb00 balrog
        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1050 e927bb00 balrog
    },
1051 e927bb00 balrog
    { 0 }
1052 e927bb00 balrog
}, n810_gpiosw_info[] = {
1053 e927bb00 balrog
    {
1054 e927bb00 balrog
        "gps_reset", N810_GPS_RESET_GPIO,
1055 e927bb00 balrog
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1056 e927bb00 balrog
    }, {
1057 e927bb00 balrog
        "gps_wakeup", N810_GPS_WAKEUP_GPIO,
1058 e927bb00 balrog
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1059 e927bb00 balrog
    }, {
1060 e927bb00 balrog
        "headphone", N8X0_HEADPHONE_GPIO,
1061 e927bb00 balrog
        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1062 e927bb00 balrog
    }, {
1063 e927bb00 balrog
        "kb_lock", N810_KB_LOCK_GPIO,
1064 e927bb00 balrog
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1065 e927bb00 balrog
    }, {
1066 e927bb00 balrog
        "sleepx_led", N810_SLEEPX_LED_GPIO,
1067 e927bb00 balrog
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
1068 e927bb00 balrog
    }, {
1069 e927bb00 balrog
        "slide", N810_SLIDE_GPIO,
1070 e927bb00 balrog
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1071 e927bb00 balrog
    },
1072 e927bb00 balrog
    { 0 }
1073 e927bb00 balrog
};
1074 e927bb00 balrog
1075 e927bb00 balrog
static struct omap_partition_info_s {
1076 e927bb00 balrog
    uint32_t offset;
1077 e927bb00 balrog
    uint32_t size;
1078 e927bb00 balrog
    int mask;
1079 e927bb00 balrog
    const char *name;
1080 e927bb00 balrog
} n800_part_info[] = {
1081 e927bb00 balrog
    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1082 e927bb00 balrog
    { 0x00020000, 0x00060000, 0x0, "config" },
1083 e927bb00 balrog
    { 0x00080000, 0x00200000, 0x0, "kernel" },
1084 e927bb00 balrog
    { 0x00280000, 0x00200000, 0x3, "initfs" },
1085 e927bb00 balrog
    { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
1086 e927bb00 balrog
1087 e927bb00 balrog
    { 0, 0, 0, 0 }
1088 e927bb00 balrog
}, n810_part_info[] = {
1089 e927bb00 balrog
    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1090 e927bb00 balrog
    { 0x00020000, 0x00060000, 0x0, "config" },
1091 e927bb00 balrog
    { 0x00080000, 0x00220000, 0x0, "kernel" },
1092 e927bb00 balrog
    { 0x002a0000, 0x00400000, 0x0, "initfs" },
1093 e927bb00 balrog
    { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
1094 e927bb00 balrog
1095 e927bb00 balrog
    { 0, 0, 0, 0 }
1096 e927bb00 balrog
};
1097 e927bb00 balrog
1098 c580d92b balrog
static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
1099 c580d92b balrog
1100 e927bb00 balrog
static int n8x0_atag_setup(void *p, int model)
1101 7e7c5e4c balrog
{
1102 7e7c5e4c balrog
    uint8_t *b;
1103 7e7c5e4c balrog
    uint16_t *w;
1104 7e7c5e4c balrog
    uint32_t *l;
1105 e927bb00 balrog
    struct omap_gpiosw_info_s *gpiosw;
1106 e927bb00 balrog
    struct omap_partition_info_s *partition;
1107 e927bb00 balrog
    const char *tag;
1108 7e7c5e4c balrog
1109 7e7c5e4c balrog
    w = p;
1110 7e7c5e4c balrog
1111 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_UART);                /* u16 tag */
1112 7e7c5e4c balrog
    stw_raw(w ++, 4);                                /* u16 len */
1113 7e7c5e4c balrog
    stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
1114 7e7c5e4c balrog
    w ++;
1115 7e7c5e4c balrog
1116 e927bb00 balrog
#if 0
1117 e927bb00 balrog
    stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE);        /* u16 tag */
1118 7e7c5e4c balrog
    stw_raw(w ++, 4);                                /* u16 len */
1119 c580d92b balrog
    stw_raw(w ++, XLDR_LL_UART + 1);                /* u8 console_uart */
1120 e927bb00 balrog
    stw_raw(w ++, 115200);                        /* u32 console_speed */
1121 e927bb00 balrog
#endif
1122 e927bb00 balrog
1123 e927bb00 balrog
    stw_raw(w ++, OMAP_TAG_LCD);                /* u16 tag */
1124 e927bb00 balrog
    stw_raw(w ++, 36);                                /* u16 len */
1125 e927bb00 balrog
    strcpy((void *) w, "QEMU LCD panel");        /* char panel_name[16] */
1126 e927bb00 balrog
    w += 8;
1127 e927bb00 balrog
    strcpy((void *) w, "blizzard");                /* char ctrl_name[16] */
1128 e927bb00 balrog
    w += 8;
1129 e927bb00 balrog
    stw_raw(w ++, N810_BLIZZARD_RESET_GPIO);        /* TODO: n800 s16 nreset_gpio */
1130 e927bb00 balrog
    stw_raw(w ++, 24);                                /* u8 data_lines */
1131 7e7c5e4c balrog
1132 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_CBUS);                /* u16 tag */
1133 7e7c5e4c balrog
    stw_raw(w ++, 8);                                /* u16 len */
1134 7e7c5e4c balrog
    stw_raw(w ++, N8X0_CBUS_CLK_GPIO);                /* s16 clk_gpio */
1135 7e7c5e4c balrog
    stw_raw(w ++, N8X0_CBUS_DAT_GPIO);                /* s16 dat_gpio */
1136 7e7c5e4c balrog
    stw_raw(w ++, N8X0_CBUS_SEL_GPIO);                /* s16 sel_gpio */
1137 7e7c5e4c balrog
    w ++;
1138 7e7c5e4c balrog
1139 e927bb00 balrog
    stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5);        /* u16 tag */
1140 e927bb00 balrog
    stw_raw(w ++, 4);                                /* u16 len */
1141 e927bb00 balrog
    stw_raw(w ++, N8X0_RETU_GPIO);                /* s16 retu_irq_gpio */
1142 e927bb00 balrog
    stw_raw(w ++, N8X0_TAHVO_GPIO);                /* s16 tahvo_irq_gpio */
1143 e927bb00 balrog
1144 e927bb00 balrog
    gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
1145 e927bb00 balrog
    for (; gpiosw->name; gpiosw ++) {
1146 e927bb00 balrog
        stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);        /* u16 tag */
1147 e927bb00 balrog
        stw_raw(w ++, 20);                        /* u16 len */
1148 e927bb00 balrog
        strcpy((void *) w, gpiosw->name);        /* char name[12] */
1149 e927bb00 balrog
        w += 6;
1150 e927bb00 balrog
        stw_raw(w ++, gpiosw->line);                /* u16 gpio */
1151 e927bb00 balrog
        stw_raw(w ++, gpiosw->type);
1152 e927bb00 balrog
        stw_raw(w ++, 0);
1153 e927bb00 balrog
        stw_raw(w ++, 0);
1154 e927bb00 balrog
    }
1155 7e7c5e4c balrog
1156 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_NOKIA_BT);                /* u16 tag */
1157 7e7c5e4c balrog
    stw_raw(w ++, 12);                                /* u16 len */
1158 7e7c5e4c balrog
    b = (void *) w;
1159 7e7c5e4c balrog
    stb_raw(b ++, 0x01);                        /* u8 chip_type        (CSR) */
1160 e927bb00 balrog
    stb_raw(b ++, N8X0_BT_WKUP_GPIO);                /* u8 bt_wakeup_gpio */
1161 7e7c5e4c balrog
    stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO);        /* u8 host_wakeup_gpio */
1162 e927bb00 balrog
    stb_raw(b ++, N8X0_BT_RESET_GPIO);                /* u8 reset_gpio */
1163 c580d92b balrog
    stb_raw(b ++, BT_UART + 1);                        /* u8 bt_uart */
1164 c580d92b balrog
    memcpy(b, &n8x0_bd_addr, 6);                /* u8 bd_addr[6] */
1165 7e7c5e4c balrog
    b += 6;
1166 7e7c5e4c balrog
    stb_raw(b ++, 0x02);                        /* u8 bt_sysclk (38.4) */
1167 7e7c5e4c balrog
    w = (void *) b;
1168 7e7c5e4c balrog
1169 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_WLAN_CX3110X);        /* u16 tag */
1170 7e7c5e4c balrog
    stw_raw(w ++, 8);                                /* u16 len */
1171 7e7c5e4c balrog
    stw_raw(w ++, 0x25);                        /* u8 chip_type */
1172 e927bb00 balrog
    stw_raw(w ++, N8X0_WLAN_PWR_GPIO);                /* s16 power_gpio */
1173 e927bb00 balrog
    stw_raw(w ++, N8X0_WLAN_IRQ_GPIO);                /* s16 irq_gpio */
1174 7e7c5e4c balrog
    stw_raw(w ++, -1);                                /* s16 spi_cs_gpio */
1175 7e7c5e4c balrog
1176 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_MMC);                /* u16 tag */
1177 7e7c5e4c balrog
    stw_raw(w ++, 16);                                /* u16 len */
1178 e927bb00 balrog
    if (model == 810) {
1179 e927bb00 balrog
        stw_raw(w ++, 0x23f);                        /* unsigned flags */
1180 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 power_pin */
1181 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 switch_pin */
1182 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 wp_pin */
1183 e927bb00 balrog
        stw_raw(w ++, 0x240);                        /* unsigned flags */
1184 e927bb00 balrog
        stw_raw(w ++, 0xc000);                        /* s16 power_pin */
1185 e927bb00 balrog
        stw_raw(w ++, 0x0248);                        /* s16 switch_pin */
1186 e927bb00 balrog
        stw_raw(w ++, 0xc000);                        /* s16 wp_pin */
1187 e927bb00 balrog
    } else {
1188 e927bb00 balrog
        stw_raw(w ++, 0xf);                        /* unsigned flags */
1189 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 power_pin */
1190 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 switch_pin */
1191 e927bb00 balrog
        stw_raw(w ++, -1);                        /* s16 wp_pin */
1192 e927bb00 balrog
        stw_raw(w ++, 0);                        /* unsigned flags */
1193 e927bb00 balrog
        stw_raw(w ++, 0);                        /* s16 power_pin */
1194 e927bb00 balrog
        stw_raw(w ++, 0);                        /* s16 switch_pin */
1195 e927bb00 balrog
        stw_raw(w ++, 0);                        /* s16 wp_pin */
1196 e927bb00 balrog
    }
1197 7e7c5e4c balrog
1198 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_TEA5761);                /* u16 tag */
1199 7e7c5e4c balrog
    stw_raw(w ++, 4);                                /* u16 len */
1200 e927bb00 balrog
    stw_raw(w ++, N8X0_TEA5761_CS_GPIO);        /* u16 enable_gpio */
1201 7e7c5e4c balrog
    w ++;
1202 7e7c5e4c balrog
1203 e927bb00 balrog
    partition = (model == 810) ? n810_part_info : n800_part_info;
1204 e927bb00 balrog
    for (; partition->name; partition ++) {
1205 e927bb00 balrog
        stw_raw(w ++, OMAP_TAG_PARTITION);        /* u16 tag */
1206 e927bb00 balrog
        stw_raw(w ++, 28);                        /* u16 len */
1207 e927bb00 balrog
        strcpy((void *) w, partition->name);        /* char name[16] */
1208 e927bb00 balrog
        l = (void *) (w + 8);
1209 e927bb00 balrog
        stl_raw(l ++, partition->size);                /* unsigned int size */
1210 e927bb00 balrog
        stl_raw(l ++, partition->offset);        /* unsigned int offset */
1211 e927bb00 balrog
        stl_raw(l ++, partition->mask);                /* unsigned int mask_flags */
1212 e927bb00 balrog
        w = (void *) l;
1213 e927bb00 balrog
    }
1214 7e7c5e4c balrog
1215 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_BOOT_REASON);        /* u16 tag */
1216 7e7c5e4c balrog
    stw_raw(w ++, 12);                                /* u16 len */
1217 7e7c5e4c balrog
#if 0
1218 7e7c5e4c balrog
    strcpy((void *) w, "por");                        /* char reason_str[12] */
1219 7e7c5e4c balrog
    strcpy((void *) w, "charger");                /* char reason_str[12] */
1220 7e7c5e4c balrog
    strcpy((void *) w, "32wd_to");                /* char reason_str[12] */
1221 7e7c5e4c balrog
    strcpy((void *) w, "sw_rst");                /* char reason_str[12] */
1222 7e7c5e4c balrog
    strcpy((void *) w, "mbus");                        /* char reason_str[12] */
1223 7e7c5e4c balrog
    strcpy((void *) w, "unknown");                /* char reason_str[12] */
1224 7e7c5e4c balrog
    strcpy((void *) w, "swdg_to");                /* char reason_str[12] */
1225 7e7c5e4c balrog
    strcpy((void *) w, "sec_vio");                /* char reason_str[12] */
1226 7e7c5e4c balrog
    strcpy((void *) w, "pwr_key");                /* char reason_str[12] */
1227 7e7c5e4c balrog
    strcpy((void *) w, "rtc_alarm");                /* char reason_str[12] */
1228 7e7c5e4c balrog
#else
1229 7e7c5e4c balrog
    strcpy((void *) w, "pwr_key");                /* char reason_str[12] */
1230 7e7c5e4c balrog
#endif
1231 7e7c5e4c balrog
    w += 6;
1232 7e7c5e4c balrog
1233 e927bb00 balrog
    tag = (model == 810) ? "RX-44" : "RX-34";
1234 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1235 7e7c5e4c balrog
    stw_raw(w ++, 24);                                /* u16 len */
1236 7e7c5e4c balrog
    strcpy((void *) w, "product");                /* char component[12] */
1237 7e7c5e4c balrog
    w += 6;
1238 e927bb00 balrog
    strcpy((void *) w, tag);                        /* char version[12] */
1239 7e7c5e4c balrog
    w += 6;
1240 7e7c5e4c balrog
1241 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1242 7e7c5e4c balrog
    stw_raw(w ++, 24);                                /* u16 len */
1243 7e7c5e4c balrog
    strcpy((void *) w, "hw-build");                /* char component[12] */
1244 7e7c5e4c balrog
    w += 6;
1245 e927bb00 balrog
    strcpy((void *) w, "QEMU " QEMU_VERSION);        /* char version[12] */
1246 7e7c5e4c balrog
    w += 6;
1247 7e7c5e4c balrog
1248 e927bb00 balrog
    tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1249 7e7c5e4c balrog
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1250 7e7c5e4c balrog
    stw_raw(w ++, 24);                                /* u16 len */
1251 7e7c5e4c balrog
    strcpy((void *) w, "nolo");                        /* char component[12] */
1252 7e7c5e4c balrog
    w += 6;
1253 e927bb00 balrog
    strcpy((void *) w, tag);                        /* char version[12] */
1254 7e7c5e4c balrog
    w += 6;
1255 7e7c5e4c balrog
1256 7e7c5e4c balrog
    return (void *) w - p;
1257 7e7c5e4c balrog
}
1258 7e7c5e4c balrog
1259 e927bb00 balrog
static int n800_atag_setup(struct arm_boot_info *info, void *p)
1260 e927bb00 balrog
{
1261 e927bb00 balrog
    return n8x0_atag_setup(p, 800);
1262 e927bb00 balrog
}
1263 7e7c5e4c balrog
1264 e927bb00 balrog
static int n810_atag_setup(struct arm_boot_info *info, void *p)
1265 e927bb00 balrog
{
1266 e927bb00 balrog
    return n8x0_atag_setup(p, 810);
1267 e927bb00 balrog
}
1268 e927bb00 balrog
1269 e927bb00 balrog
static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
1270 e927bb00 balrog
                DisplayState *ds, const char *kernel_filename,
1271 e927bb00 balrog
                const char *kernel_cmdline, const char *initrd_filename,
1272 e927bb00 balrog
                const char *cpu_model, struct arm_boot_info *binfo, int model)
1273 7e7c5e4c balrog
{
1274 7e7c5e4c balrog
    struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
1275 e927bb00 balrog
    int sdram_size = binfo->ram_size;
1276 7e7c5e4c balrog
    int onenandram_size = 0x00010000;
1277 7e7c5e4c balrog
1278 7e7c5e4c balrog
    if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) {
1279 7e7c5e4c balrog
        fprintf(stderr, "This architecture uses %i bytes of memory\n",
1280 7e7c5e4c balrog
                        sdram_size + onenandram_size + OMAP242X_SRAM_SIZE);
1281 7e7c5e4c balrog
        exit(1);
1282 7e7c5e4c balrog
    }
1283 7e7c5e4c balrog
1284 7e7c5e4c balrog
    s->cpu = omap2420_mpu_init(sdram_size, NULL, cpu_model);
1285 7e7c5e4c balrog
1286 0941041e balrog
    /* Setup peripherals
1287 0941041e balrog
     *
1288 0941041e balrog
     * Believed external peripherals layout in the N810:
1289 0941041e balrog
     * (spi bus 1)
1290 0941041e balrog
     *   tsc2005
1291 0941041e balrog
     *   lcd_mipid
1292 0941041e balrog
     * (spi bus 2)
1293 0941041e balrog
     *   Conexant cx3110x (WLAN)
1294 0941041e balrog
     *   optional: pc2400m (WiMAX)
1295 0941041e balrog
     * (i2c bus 0)
1296 0941041e balrog
     *   TLV320AIC33 (audio codec)
1297 0941041e balrog
     *   TCM825x (camera by Toshiba)
1298 0941041e balrog
     *   lp5521 (clever LEDs)
1299 0941041e balrog
     *   tsl2563 (light sensor, hwmon, model 7, rev. 0)
1300 0941041e balrog
     *   lm8323 (keypad, manf 00, rev 04)
1301 0941041e balrog
     * (i2c bus 1)
1302 0941041e balrog
     *   tmp105 (temperature sensor, hwmon)
1303 0941041e balrog
     *   menelaus (pm)
1304 d238db7f balrog
     * (somewhere on i2c - maybe N800-only)
1305 d238db7f balrog
     *   tea5761 (FM tuner)
1306 d238db7f balrog
     * (serial 0)
1307 d238db7f balrog
     *   GPS
1308 d238db7f balrog
     * (some serial port)
1309 d238db7f balrog
     *   csr41814 (Bluetooth)
1310 0941041e balrog
     */
1311 e927bb00 balrog
    n8x0_gpio_setup(s);
1312 7e7c5e4c balrog
    n8x0_nand_setup(s);
1313 e927bb00 balrog
    n8x0_i2c_setup(s);
1314 e927bb00 balrog
    if (model == 800)
1315 e927bb00 balrog
        n800_tsc_kbd_setup(s);
1316 1d4e547b balrog
    else if (model == 810) {
1317 e927bb00 balrog
        n810_tsc_setup(s);
1318 1d4e547b balrog
        n810_kbd_setup(s);
1319 1d4e547b balrog
    }
1320 e927bb00 balrog
    n8x0_spi_setup(s);
1321 e927bb00 balrog
    n8x0_dss_setup(s, ds);
1322 e927bb00 balrog
    n8x0_cbus_setup(s);
1323 58a26b47 balrog
    n8x0_uart_setup(s);
1324 942ac052 balrog
    if (usb_enabled)
1325 e927bb00 balrog
        n8x0_usb_setup(s);
1326 7e7c5e4c balrog
1327 7e7c5e4c balrog
    /* Setup initial (reset) machine state */
1328 7e7c5e4c balrog
1329 7e7c5e4c balrog
    /* Start at the OneNAND bootloader.  */
1330 7e7c5e4c balrog
    s->cpu->env->regs[15] = 0;
1331 7e7c5e4c balrog
1332 7e7c5e4c balrog
    if (kernel_filename) {
1333 7e7c5e4c balrog
        /* Or at the linux loader.  */
1334 e927bb00 balrog
        binfo->kernel_filename = kernel_filename;
1335 e927bb00 balrog
        binfo->kernel_cmdline = kernel_cmdline;
1336 e927bb00 balrog
        binfo->initrd_filename = initrd_filename;
1337 e927bb00 balrog
        arm_load_kernel(s->cpu->env, binfo);
1338 7e7c5e4c balrog
1339 e927bb00 balrog
        qemu_register_reset(n8x0_boot_init, s);
1340 e927bb00 balrog
        n8x0_boot_init(s);
1341 7e7c5e4c balrog
    }
1342 7e7c5e4c balrog
1343 d238db7f balrog
    if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) {
1344 d238db7f balrog
        /* No, wait, better start at the ROM.  */
1345 d238db7f balrog
        s->cpu->env->regs[15] = OMAP2_Q2_BASE + 0x400000;
1346 d238db7f balrog
1347 d238db7f balrog
        /* This is intended for loading the `secondary.bin' program from
1348 d238db7f balrog
         * Nokia images (the NOLO bootloader).  The entry point seems
1349 d238db7f balrog
         * to be at OMAP2_Q2_BASE + 0x400000.
1350 d238db7f balrog
         *
1351 d238db7f balrog
         * The `2nd.bin' files contain some kind of earlier boot code and
1352 d238db7f balrog
         * for them the entry point needs to be set to OMAP2_SRAM_BASE.
1353 d238db7f balrog
         *
1354 d238db7f balrog
         * The code above is for loading the `zImage' file from Nokia
1355 d238db7f balrog
         * images.  */
1356 d238db7f balrog
        printf("%i bytes of image loaded\n", load_image(option_rom[0],
1357 d238db7f balrog
                                phys_ram_base + 0x400000));
1358 d238db7f balrog
1359 d238db7f balrog
        n800_setup_nolo_tags(phys_ram_base + sdram_size);
1360 d238db7f balrog
    }
1361 c60e08d9 pbrook
    /* FIXME: We shouldn't really be doing this here.  The LCD controller
1362 c60e08d9 pbrook
       will set the size once configured, so this just sets an initial
1363 c60e08d9 pbrook
       size until the guest activates the display.  */
1364 7e7c5e4c balrog
    dpy_resize(ds, 800, 480);
1365 7e7c5e4c balrog
}
1366 7e7c5e4c balrog
1367 e927bb00 balrog
static struct arm_boot_info n800_binfo = {
1368 e927bb00 balrog
    .loader_start = OMAP2_Q2_BASE,
1369 e927bb00 balrog
    /* Actually two chips of 0x4000000 bytes each */
1370 e927bb00 balrog
    .ram_size = 0x08000000,
1371 e927bb00 balrog
    .board_id = 0x4f7,
1372 e927bb00 balrog
    .atag_board = n800_atag_setup,
1373 e927bb00 balrog
};
1374 e927bb00 balrog
1375 e927bb00 balrog
static struct arm_boot_info n810_binfo = {
1376 e927bb00 balrog
    .loader_start = OMAP2_Q2_BASE,
1377 e927bb00 balrog
    /* Actually two chips of 0x4000000 bytes each */
1378 e927bb00 balrog
    .ram_size = 0x08000000,
1379 e927bb00 balrog
    /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1380 e927bb00 balrog
     * used by some older versions of the bootloader and 5555 is used
1381 e927bb00 balrog
     * instead (including versions that shipped with many devices).  */
1382 e927bb00 balrog
    .board_id = 0x60c,
1383 e927bb00 balrog
    .atag_board = n810_atag_setup,
1384 e927bb00 balrog
};
1385 e927bb00 balrog
1386 e927bb00 balrog
static void n800_init(ram_addr_t ram_size, int vga_ram_size,
1387 e927bb00 balrog
                const char *boot_device, DisplayState *ds,
1388 e927bb00 balrog
                const char *kernel_filename, const char *kernel_cmdline,
1389 e927bb00 balrog
                const char *initrd_filename, const char *cpu_model)
1390 e927bb00 balrog
{
1391 e927bb00 balrog
    return n8x0_init(ram_size, boot_device, ds,
1392 e927bb00 balrog
                    kernel_filename, kernel_cmdline, initrd_filename,
1393 e927bb00 balrog
                    cpu_model, &n800_binfo, 800);
1394 e927bb00 balrog
}
1395 e927bb00 balrog
1396 e927bb00 balrog
static void n810_init(ram_addr_t ram_size, int vga_ram_size,
1397 e927bb00 balrog
                const char *boot_device, DisplayState *ds,
1398 e927bb00 balrog
                const char *kernel_filename, const char *kernel_cmdline,
1399 e927bb00 balrog
                const char *initrd_filename, const char *cpu_model)
1400 e927bb00 balrog
{
1401 e927bb00 balrog
    return n8x0_init(ram_size, boot_device, ds,
1402 e927bb00 balrog
                    kernel_filename, kernel_cmdline, initrd_filename,
1403 e927bb00 balrog
                    cpu_model, &n810_binfo, 810);
1404 e927bb00 balrog
}
1405 e927bb00 balrog
1406 7e7c5e4c balrog
QEMUMachine n800_machine = {
1407 4b32e168 aliguori
    .name = "n800",
1408 4b32e168 aliguori
    .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
1409 4b32e168 aliguori
    .init = n800_init,
1410 3d878caa balrog
    .ram_require = (0x08000000 + 0x00010000 + OMAP242X_SRAM_SIZE) |
1411 3d878caa balrog
            RAMSIZE_FIXED,
1412 7e7c5e4c balrog
};
1413 e927bb00 balrog
1414 e927bb00 balrog
QEMUMachine n810_machine = {
1415 4b32e168 aliguori
    .name = "n810",
1416 4b32e168 aliguori
    .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
1417 4b32e168 aliguori
    .init = n810_init,
1418 3d878caa balrog
    .ram_require = (0x08000000 + 0x00010000 + OMAP242X_SRAM_SIZE) |
1419 3d878caa balrog
            RAMSIZE_FIXED,
1420 e927bb00 balrog
};