Statistics
| Branch: | Revision:

root / hw / nseries.c @ 7830cf78

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

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