Statistics
| Branch: | Revision:

root / hw / nseries.c @ cff17894

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

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