include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / wireless / wl12xx / wl1271_boot.c
CommitLineData
f5fc0f86
LC
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/gpio.h>
5a0e3ad6 25#include <linux/slab.h>
f5fc0f86
LC
26
27#include "wl1271_acx.h"
28#include "wl1271_reg.h"
29#include "wl1271_boot.h"
30#include "wl1271_spi.h"
7b048c52 31#include "wl1271_io.h"
f5fc0f86
LC
32#include "wl1271_event.h"
33
34static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
35 [PART_DOWN] = {
36 .mem = {
37 .start = 0x00000000,
38 .size = 0x000177c0
39 },
40 .reg = {
41 .start = REGISTERS_BASE,
42 .size = 0x00008800
43 },
451de97a
JO
44 .mem2 = {
45 .start = 0x00000000,
46 .size = 0x00000000
47 },
48 .mem3 = {
49 .start = 0x00000000,
50 .size = 0x00000000
51 },
f5fc0f86
LC
52 },
53
54 [PART_WORK] = {
55 .mem = {
56 .start = 0x00040000,
57 .size = 0x00014fc0
58 },
59 .reg = {
60 .start = REGISTERS_BASE,
451de97a
JO
61 .size = 0x0000a000
62 },
63 .mem2 = {
64 .start = 0x003004f8,
65 .size = 0x00000004
66 },
67 .mem3 = {
68 .start = 0x00040404,
69 .size = 0x00000000
f5fc0f86
LC
70 },
71 },
72
73 [PART_DRPW] = {
74 .mem = {
75 .start = 0x00040000,
76 .size = 0x00014fc0
77 },
78 .reg = {
79 .start = DRPW_BASE,
80 .size = 0x00006000
451de97a
JO
81 },
82 .mem2 = {
83 .start = 0x00000000,
84 .size = 0x00000000
85 },
86 .mem3 = {
87 .start = 0x00000000,
88 .size = 0x00000000
f5fc0f86
LC
89 }
90 }
91};
92
93static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
94{
95 u32 cpu_ctrl;
96
97 /* 10.5.0 run the firmware (I) */
7b048c52 98 cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
f5fc0f86
LC
99
100 /* 10.5.1 run the firmware (II) */
101 cpu_ctrl |= flag;
7b048c52 102 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
f5fc0f86
LC
103}
104
105static void wl1271_boot_fw_version(struct wl1271 *wl)
106{
107 struct wl1271_static_data static_data;
108
7b048c52
TP
109 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
110 false);
f5fc0f86
LC
111
112 strncpy(wl->chip.fw_ver, static_data.fw_version,
113 sizeof(wl->chip.fw_ver));
114
115 /* make sure the string is NULL-terminated */
116 wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
117}
118
119static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
120 size_t fw_data_len, u32 dest)
121{
451de97a 122 struct wl1271_partition_set partition;
f5fc0f86 123 int addr, chunk_num, partition_limit;
1fba4974 124 u8 *p, *chunk;
f5fc0f86
LC
125
126 /* whal_FwCtrl_LoadFwImageSm() */
127
128 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
129
73d0a13c
LC
130 wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
131 fw_data_len, CHUNK_SIZE);
f5fc0f86 132
f5fc0f86
LC
133 if ((fw_data_len % 4) != 0) {
134 wl1271_error("firmware length not multiple of four");
135 return -EIO;
136 }
137
1fba4974 138 chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
ed317788 139 if (!chunk) {
1fba4974
JO
140 wl1271_error("allocation for firmware upload chunk failed");
141 return -ENOMEM;
142 }
143
451de97a
JO
144 memcpy(&partition, &part_table[PART_DOWN], sizeof(partition));
145 partition.mem.start = dest;
146 wl1271_set_partition(wl, &partition);
f5fc0f86
LC
147
148 /* 10.1 set partition limit and chunk num */
149 chunk_num = 0;
150 partition_limit = part_table[PART_DOWN].mem.size;
151
152 while (chunk_num < fw_data_len / CHUNK_SIZE) {
153 /* 10.2 update partition, if needed */
154 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
155 if (addr > partition_limit) {
156 addr = dest + chunk_num * CHUNK_SIZE;
157 partition_limit = chunk_num * CHUNK_SIZE +
158 part_table[PART_DOWN].mem.size;
451de97a
JO
159 partition.mem.start = addr;
160 wl1271_set_partition(wl, &partition);
f5fc0f86
LC
161 }
162
163 /* 10.3 upload the chunk */
164 addr = dest + chunk_num * CHUNK_SIZE;
165 p = buf + chunk_num * CHUNK_SIZE;
1fba4974 166 memcpy(chunk, p, CHUNK_SIZE);
f5fc0f86
LC
167 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
168 p, addr);
7b048c52 169 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
f5fc0f86
LC
170
171 chunk_num++;
172 }
173
174 /* 10.4 upload the last chunk */
175 addr = dest + chunk_num * CHUNK_SIZE;
176 p = buf + chunk_num * CHUNK_SIZE;
1fba4974 177 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
73d0a13c 178 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
f5fc0f86 179 fw_data_len % CHUNK_SIZE, p, addr);
7b048c52 180 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
f5fc0f86 181
1fba4974 182 kfree(chunk);
f5fc0f86
LC
183 return 0;
184}
185
186static int wl1271_boot_upload_firmware(struct wl1271 *wl)
187{
188 u32 chunks, addr, len;
ed317788 189 int ret = 0;
f5fc0f86
LC
190 u8 *fw;
191
192 fw = wl->fw;
d0f63b20 193 chunks = be32_to_cpup((__be32 *) fw);
f5fc0f86
LC
194 fw += sizeof(u32);
195
196 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
197
198 while (chunks--) {
d0f63b20 199 addr = be32_to_cpup((__be32 *) fw);
f5fc0f86 200 fw += sizeof(u32);
d0f63b20 201 len = be32_to_cpup((__be32 *) fw);
f5fc0f86
LC
202 fw += sizeof(u32);
203
204 if (len > 300000) {
205 wl1271_info("firmware chunk too long: %u", len);
206 return -EINVAL;
207 }
208 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
209 chunks, addr, len);
ed317788
JO
210 ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
211 if (ret != 0)
212 break;
f5fc0f86
LC
213 fw += len;
214 }
215
ed317788 216 return ret;
f5fc0f86
LC
217}
218
219static int wl1271_boot_upload_nvs(struct wl1271 *wl)
220{
221 size_t nvs_len, burst_len;
222 int i;
223 u32 dest_addr, val;
152ee6e0 224 u8 *nvs_ptr, *nvs_aligned;
f5fc0f86 225
152ee6e0 226 if (wl->nvs == NULL)
f5fc0f86
LC
227 return -ENODEV;
228
8cf5e8e5 229 /* only the first part of the NVS needs to be uploaded */
152ee6e0
JO
230 nvs_len = sizeof(wl->nvs->nvs);
231 nvs_ptr = (u8 *)wl->nvs->nvs;
f5fc0f86 232
f5fc0f86
LC
233 /*
234 * Layout before the actual NVS tables:
235 * 1 byte : burst length.
236 * 2 bytes: destination address.
237 * n bytes: data to burst copy.
238 *
239 * This is ended by a 0 length, then the NVS tables.
240 */
241
242 /* FIXME: Do we need to check here whether the LSB is 1? */
243 while (nvs_ptr[0]) {
244 burst_len = nvs_ptr[0];
245 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
246
247 /* FIXME: Due to our new wl1271_translate_reg_addr function,
248 we need to add the REGISTER_BASE to the destination */
249 dest_addr += REGISTERS_BASE;
250
251 /* We move our pointer to the data */
252 nvs_ptr += 3;
253
254 for (i = 0; i < burst_len; i++) {
255 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
256 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
257
258 wl1271_debug(DEBUG_BOOT,
259 "nvs burst write 0x%x: 0x%x",
260 dest_addr, val);
7b048c52 261 wl1271_write32(wl, dest_addr, val);
f5fc0f86
LC
262
263 nvs_ptr += 4;
264 dest_addr += 4;
265 }
266 }
267
268 /*
269 * We've reached the first zero length, the first NVS table
270 * is 7 bytes further.
271 */
272 nvs_ptr += 7;
152ee6e0 273 nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
f5fc0f86
LC
274 nvs_len = ALIGN(nvs_len, 4);
275
276 /* FIXME: The driver sets the partition here, but this is not needed,
277 since it sets to the same one as currently in use */
278 /* Now we must set the partition correctly */
451de97a 279 wl1271_set_partition(wl, &part_table[PART_WORK]);
f5fc0f86
LC
280
281 /* Copy the NVS tables to a new block to ensure alignment */
6f8434a7
LC
282 /* FIXME: We jump 3 more bytes before uploading the NVS. It seems
283 that our NVS files have three extra zeros here. I'm not sure whether
284 the problem is in our NVS generation or we should really jumpt these
285 3 bytes here */
286 nvs_ptr += 3;
287
288 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if
289 (!nvs_aligned) return -ENOMEM;
f5fc0f86
LC
290
291 /* And finally we upload the NVS tables */
292 /* FIXME: In wl1271, we upload everything at once.
293 No endianness handling needed here?! The ref driver doesn't do
294 anything about it at this point */
7b048c52 295 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
f5fc0f86
LC
296
297 kfree(nvs_aligned);
298 return 0;
299}
300
301static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
302{
303 enable_irq(wl->irq);
7b048c52
TP
304 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
305 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
306 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
f5fc0f86
LC
307}
308
309static int wl1271_boot_soft_reset(struct wl1271 *wl)
310{
311 unsigned long timeout;
312 u32 boot_data;
313
314 /* perform soft reset */
7b048c52 315 wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
f5fc0f86
LC
316
317 /* SOFT_RESET is self clearing */
318 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
319 while (1) {
7b048c52 320 boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
f5fc0f86
LC
321 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
322 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
323 break;
324
325 if (time_after(jiffies, timeout)) {
326 /* 1.2 check pWhalBus->uSelfClearTime if the
327 * timeout was reached */
328 wl1271_error("soft reset timeout");
329 return -1;
330 }
331
332 udelay(SOFT_RESET_STALL_TIME);
333 }
334
335 /* disable Rx/Tx */
7b048c52 336 wl1271_write32(wl, ENABLE, 0x0);
f5fc0f86
LC
337
338 /* disable auto calibration on start*/
7b048c52 339 wl1271_write32(wl, SPARE_A2, 0xffff);
f5fc0f86
LC
340
341 return 0;
342}
343
344static int wl1271_boot_run_firmware(struct wl1271 *wl)
345{
346 int loop, ret;
347 u32 chip_id, interrupt;
348
349 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
350
7b048c52 351 chip_id = wl1271_read32(wl, CHIP_ID_B);
f5fc0f86
LC
352
353 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
354
355 if (chip_id != wl->chip.id) {
356 wl1271_error("chip id doesn't match after firmware boot");
357 return -EIO;
358 }
359
360 /* wait for init to complete */
361 loop = 0;
362 while (loop++ < INIT_LOOP) {
363 udelay(INIT_LOOP_DELAY);
7b048c52 364 interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
f5fc0f86
LC
365
366 if (interrupt == 0xffffffff) {
367 wl1271_error("error reading hardware complete "
368 "init indication");
369 return -EIO;
370 }
371 /* check that ACX_INTR_INIT_COMPLETE is enabled */
372 else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
7b048c52
TP
373 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
374 WL1271_ACX_INTR_INIT_COMPLETE);
f5fc0f86
LC
375 break;
376 }
377 }
378
e7d17cf4 379 if (loop > INIT_LOOP) {
f5fc0f86
LC
380 wl1271_error("timeout waiting for the hardware to "
381 "complete initialization");
382 return -EIO;
383 }
384
385 /* get hardware config command mail box */
7b048c52 386 wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
f5fc0f86
LC
387
388 /* get hardware config event mail box */
7b048c52 389 wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
f5fc0f86
LC
390
391 /* set the working partition to its "running" mode offset */
451de97a 392 wl1271_set_partition(wl, &part_table[PART_WORK]);
f5fc0f86
LC
393
394 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
395 wl->cmd_box_addr, wl->event_box_addr);
396
397 wl1271_boot_fw_version(wl);
398
399 /*
400 * in case of full asynchronous mode the firmware event must be
401 * ready to receive event from the command mailbox
402 */
403
be823e5b
JO
404 /* unmask required mbox events */
405 wl->event_mask = BSS_LOSE_EVENT_ID |
19ad0715
JO
406 SCAN_COMPLETE_EVENT_ID |
407 PS_REPORT_EVENT_ID;
f5fc0f86
LC
408
409 ret = wl1271_event_unmask(wl);
410 if (ret < 0) {
411 wl1271_error("EVENT mask setting failed");
412 return ret;
413 }
414
415 wl1271_event_mbox_config(wl);
416
417 /* firmware startup completed */
418 return 0;
419}
420
421static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
422{
e8768eeb 423 u32 polarity;
f5fc0f86 424
e8768eeb 425 polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
f5fc0f86
LC
426
427 /* We use HIGH polarity, so unset the LOW bit */
428 polarity &= ~POLARITY_LOW;
e8768eeb 429 wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
f5fc0f86
LC
430
431 return 0;
432}
433
434int wl1271_boot(struct wl1271 *wl)
435{
436 int ret = 0;
437 u32 tmp, clk, pause;
438
284134eb
JO
439 if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
440 /* ref clk: 19.2/38.4/38.4-XTAL */
f5fc0f86
LC
441 clk = 0x3;
442 else if (REF_CLOCK == 1 || REF_CLOCK == 3)
443 /* ref clk: 26/52 */
444 clk = 0x5;
445
284134eb
JO
446 if (REF_CLOCK != 0) {
447 u16 val;
448 /* Set clock type */
449 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
450 val &= FREF_CLK_TYPE_BITS;
451 val |= CLK_REQ_PRCM;
452 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
453 } else {
454 u16 val;
455 /* Set clock polarity */
456 val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
457 val &= FREF_CLK_POLARITY_BITS;
458 val |= CLK_REQ_OUTN_SEL;
459 wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
460 }
461
7b048c52 462 wl1271_write32(wl, PLL_PARAMETERS, clk);
f5fc0f86 463
7b048c52 464 pause = wl1271_read32(wl, PLL_PARAMETERS);
f5fc0f86
LC
465
466 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
467
468 pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
469 * WU_COUNTER_PAUSE_VAL instead of
470 * 0x3ff (magic number ). How does
471 * this work?! */
472 pause |= WU_COUNTER_PAUSE_VAL;
7b048c52 473 wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
f5fc0f86
LC
474
475 /* Continue the ELP wake up sequence */
7b048c52 476 wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
f5fc0f86
LC
477 udelay(500);
478
451de97a 479 wl1271_set_partition(wl, &part_table[PART_DRPW]);
f5fc0f86
LC
480
481 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
482 to be used by DRPw FW. The RTRIM value will be added by the FW
483 before taking DRPw out of reset */
484
485 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
7b048c52 486 clk = wl1271_read32(wl, DRPW_SCRATCH_START);
f5fc0f86
LC
487
488 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
489
490 /* 2 */
491 clk |= (REF_CLOCK << 1) << 4;
7b048c52 492 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
f5fc0f86 493
451de97a 494 wl1271_set_partition(wl, &part_table[PART_WORK]);
f5fc0f86
LC
495
496 /* Disable interrupts */
7b048c52 497 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
f5fc0f86
LC
498
499 ret = wl1271_boot_soft_reset(wl);
500 if (ret < 0)
501 goto out;
502
503 /* 2. start processing NVS file */
504 ret = wl1271_boot_upload_nvs(wl);
505 if (ret < 0)
506 goto out;
507
508 /* write firmware's last address (ie. it's length) to
509 * ACX_EEPROMLESS_IND_REG */
510 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
511
7b048c52 512 wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
f5fc0f86 513
7b048c52 514 tmp = wl1271_read32(wl, CHIP_ID_B);
f5fc0f86
LC
515
516 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
517
518 /* 6. read the EEPROM parameters */
7b048c52 519 tmp = wl1271_read32(wl, SCR_PAD2);
f5fc0f86
LC
520
521 ret = wl1271_boot_write_irq_polarity(wl);
522 if (ret < 0)
523 goto out;
524
525 /* FIXME: Need to check whether this is really what we want */
7b048c52
TP
526 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
527 WL1271_ACX_ALL_EVENTS_VECTOR);
f5fc0f86
LC
528
529 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
530 * to upload_fw) */
531
532 ret = wl1271_boot_upload_firmware(wl);
533 if (ret < 0)
534 goto out;
535
536 /* 10.5 start firmware */
537 ret = wl1271_boot_run_firmware(wl);
538 if (ret < 0)
539 goto out;
540
eb5b28d0
JO
541 /* Enable firmware interrupts now */
542 wl1271_boot_enable_interrupts(wl);
543
f5fc0f86
LC
544 /* set the wl1271 default filters */
545 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
546 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
547
548 wl1271_event_mbox_config(wl);
549
550out:
551 return ret;
552}