Statistics
| Branch: | Revision:

root / hw / nseries.c @ 681f8c29

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

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