Statistics
| Branch: | Revision:

root / hw / nseries.c @ d9c32310

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

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