Merge branch 'serge-next-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh...
[cascardo/linux.git] / drivers / net / wireless / cw1200 / fwio.c
1 /*
2  * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
3  *
4  * Copyright (c) 2010, ST-Ericsson
5  * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6  *
7  * Based on:
8  * ST-Ericsson UMAC CW1200 driver which is
9  * Copyright (c) 2010, ST-Ericsson
10  * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16
17 #include <linux/vmalloc.h>
18 #include <linux/sched.h>
19 #include <linux/firmware.h>
20
21 #include "cw1200.h"
22 #include "fwio.h"
23 #include "hwio.h"
24 #include "hwbus.h"
25 #include "bh.h"
26
27 static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
28 {
29         int hw_type = -1;
30         u32 silicon_type = (config_reg_val >> 24) & 0x7;
31         u32 silicon_vers = (config_reg_val >> 31) & 0x1;
32
33         switch (silicon_type) {
34         case 0x00:
35                 *major_revision = 1;
36                 hw_type = HIF_9000_SILICON_VERSATILE;
37                 break;
38         case 0x01:
39         case 0x02: /* CW1x00 */
40         case 0x04: /* CW1x60 */
41                 *major_revision = silicon_type;
42                 if (silicon_vers)
43                         hw_type = HIF_8601_VERSATILE;
44                 else
45                         hw_type = HIF_8601_SILICON;
46                 break;
47         default:
48                 break;
49         }
50
51         return hw_type;
52 }
53
54 static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
55 {
56         int ret, block, num_blocks;
57         unsigned i;
58         u32 val32;
59         u32 put = 0, get = 0;
60         u8 *buf = NULL;
61         const char *fw_path;
62         const struct firmware *firmware = NULL;
63
64         /* Macroses are local. */
65 #define APB_WRITE(reg, val) \
66         do { \
67                 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
68                 if (ret < 0) \
69                         goto error; \
70         } while (0)
71 #define APB_READ(reg, val) \
72         do { \
73                 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
74                 if (ret < 0) \
75                         goto error; \
76         } while (0)
77 #define REG_WRITE(reg, val) \
78         do { \
79                 ret = cw1200_reg_write_32(priv, (reg), (val)); \
80                 if (ret < 0) \
81                         goto error; \
82         } while (0)
83 #define REG_READ(reg, val) \
84         do { \
85                 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
86                 if (ret < 0) \
87                         goto error; \
88         } while (0)
89
90         switch (priv->hw_revision) {
91         case CW1200_HW_REV_CUT10:
92                 fw_path = FIRMWARE_CUT10;
93                 if (!priv->sdd_path)
94                         priv->sdd_path = SDD_FILE_10;
95                 break;
96         case CW1200_HW_REV_CUT11:
97                 fw_path = FIRMWARE_CUT11;
98                 if (!priv->sdd_path)
99                         priv->sdd_path = SDD_FILE_11;
100                 break;
101         case CW1200_HW_REV_CUT20:
102                 fw_path = FIRMWARE_CUT20;
103                 if (!priv->sdd_path)
104                         priv->sdd_path = SDD_FILE_20;
105                 break;
106         case CW1200_HW_REV_CUT22:
107                 fw_path = FIRMWARE_CUT22;
108                 if (!priv->sdd_path)
109                         priv->sdd_path = SDD_FILE_22;
110                 break;
111         case CW1X60_HW_REV:
112                 fw_path = FIRMWARE_CW1X60;
113                 if (!priv->sdd_path)
114                         priv->sdd_path = SDD_FILE_CW1X60;
115                 break;
116         default:
117                 pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
118                 return -EINVAL;
119         }
120
121         /* Initialize common registers */
122         APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
123         APB_WRITE(DOWNLOAD_PUT_REG, 0);
124         APB_WRITE(DOWNLOAD_GET_REG, 0);
125         APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
126         APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
127
128         /* Write the NOP Instruction */
129         REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
130         REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
131
132         /* Release CPU from RESET */
133         REG_READ(ST90TDS_CONFIG_REG_ID, val32);
134         val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
135         REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
136
137         /* Enable Clock */
138         val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
139         REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
140
141         /* Load a firmware file */
142         ret = request_firmware(&firmware, fw_path, priv->pdev);
143         if (ret) {
144                 pr_err("Can't load firmware file %s.\n", fw_path);
145                 goto error;
146         }
147
148         buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
149         if (!buf) {
150                 pr_err("Can't allocate firmware load buffer.\n");
151                 ret = -ENOMEM;
152                 goto error;
153         }
154
155         /* Check if the bootloader is ready */
156         for (i = 0; i < 100; i += 1 + i / 2) {
157                 APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
158                 if (val32 == DOWNLOAD_I_AM_HERE)
159                         break;
160                 mdelay(i);
161         } /* End of for loop */
162
163         if (val32 != DOWNLOAD_I_AM_HERE) {
164                 pr_err("Bootloader is not ready.\n");
165                 ret = -ETIMEDOUT;
166                 goto error;
167         }
168
169         /* Calculcate number of download blocks */
170         num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
171
172         /* Updating the length in Download Ctrl Area */
173         val32 = firmware->size; /* Explicit cast from size_t to u32 */
174         APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32);
175
176         /* Firmware downloading loop */
177         for (block = 0; block < num_blocks; block++) {
178                 size_t tx_size;
179                 size_t block_size;
180
181                 /* check the download status */
182                 APB_READ(DOWNLOAD_STATUS_REG, val32);
183                 if (val32 != DOWNLOAD_PENDING) {
184                         pr_err("Bootloader reported error %d.\n", val32);
185                         ret = -EIO;
186                         goto error;
187                 }
188
189                 /* loop until put - get <= 24K */
190                 for (i = 0; i < 100; i++) {
191                         APB_READ(DOWNLOAD_GET_REG, get);
192                         if ((put - get) <=
193                             (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
194                                 break;
195                         mdelay(i);
196                 }
197
198                 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
199                         pr_err("Timeout waiting for FIFO.\n");
200                         ret = -ETIMEDOUT;
201                         goto error;
202                 }
203
204                 /* calculate the block size */
205                 tx_size = block_size = min_t(size_t, firmware->size - put,
206                                         DOWNLOAD_BLOCK_SIZE);
207
208                 memcpy(buf, &firmware->data[put], block_size);
209                 if (block_size < DOWNLOAD_BLOCK_SIZE) {
210                         memset(&buf[block_size], 0,
211                                DOWNLOAD_BLOCK_SIZE - block_size);
212                         tx_size = DOWNLOAD_BLOCK_SIZE;
213                 }
214
215                 /* send the block to sram */
216                 ret = cw1200_apb_write(priv,
217                         CW1200_APB(DOWNLOAD_FIFO_OFFSET +
218                                    (put & (DOWNLOAD_FIFO_SIZE - 1))),
219                         buf, tx_size);
220                 if (ret < 0) {
221                         pr_err("Can't write firmware block @ %d!\n",
222                                put & (DOWNLOAD_FIFO_SIZE - 1));
223                         goto error;
224                 }
225
226                 /* update the put register */
227                 put += block_size;
228                 APB_WRITE(DOWNLOAD_PUT_REG, put);
229         } /* End of firmware download loop */
230
231         /* Wait for the download completion */
232         for (i = 0; i < 300; i += 1 + i / 2) {
233                 APB_READ(DOWNLOAD_STATUS_REG, val32);
234                 if (val32 != DOWNLOAD_PENDING)
235                         break;
236                 mdelay(i);
237         }
238         if (val32 != DOWNLOAD_SUCCESS) {
239                 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
240                 ret = -ETIMEDOUT;
241                 goto error;
242         } else {
243                 pr_info("Firmware download completed.\n");
244                 ret = 0;
245         }
246
247 error:
248         kfree(buf);
249         if (firmware)
250                 release_firmware(firmware);
251         return ret;
252
253 #undef APB_WRITE
254 #undef APB_READ
255 #undef REG_WRITE
256 #undef REG_READ
257 }
258
259
260 static int config_reg_read(struct cw1200_common *priv, u32 *val)
261 {
262         switch (priv->hw_type) {
263         case HIF_9000_SILICON_VERSATILE: {
264                 u16 val16;
265                 int ret = cw1200_reg_read_16(priv,
266                                              ST90TDS_CONFIG_REG_ID,
267                                              &val16);
268                 if (ret < 0)
269                         return ret;
270                 *val = val16;
271                 return 0;
272         }
273         case HIF_8601_VERSATILE:
274         case HIF_8601_SILICON:
275         default:
276                 cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
277                 break;
278         }
279         return 0;
280 }
281
282 static int config_reg_write(struct cw1200_common *priv, u32 val)
283 {
284         switch (priv->hw_type) {
285         case HIF_9000_SILICON_VERSATILE:
286                 return cw1200_reg_write_16(priv,
287                                            ST90TDS_CONFIG_REG_ID,
288                                            (u16)val);
289         case HIF_8601_VERSATILE:
290         case HIF_8601_SILICON:
291         default:
292                 return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
293                 break;
294         }
295         return 0;
296 }
297
298 int cw1200_load_firmware(struct cw1200_common *priv)
299 {
300         int ret;
301         int i;
302         u32 val32;
303         u16 val16;
304         int major_revision = -1;
305
306         /* Read CONFIG Register */
307         ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
308         if (ret < 0) {
309                 pr_err("Can't read config register.\n");
310                 goto out;
311         }
312
313         if (val32 == 0 || val32 == 0xffffffff) {
314                 pr_err("Bad config register value (0x%08x)\n", val32);
315                 ret = -EIO;
316                 goto out;
317         }
318
319         priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
320         if (priv->hw_type < 0) {
321                 pr_err("Can't deduce hardware type.\n");
322                 ret = -ENOTSUPP;
323                 goto out;
324         }
325
326         /* Set DPLL Reg value, and read back to confirm writes work */
327         ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
328                                   cw1200_dpll_from_clk(priv->hw_refclk));
329         if (ret < 0) {
330                 pr_err("Can't write DPLL register.\n");
331                 goto out;
332         }
333
334         msleep(20);
335
336         ret = cw1200_reg_read_32(priv,
337                 ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
338         if (ret < 0) {
339                 pr_err("Can't read DPLL register.\n");
340                 goto out;
341         }
342
343         if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
344                 pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
345                        cw1200_dpll_from_clk(priv->hw_refclk), val32);
346                 ret = -EIO;
347                 goto out;
348         }
349
350         /* Set wakeup bit in device */
351         ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
352         if (ret < 0) {
353                 pr_err("set_wakeup: can't read control register.\n");
354                 goto out;
355         }
356
357         ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
358                 val16 | ST90TDS_CONT_WUP_BIT);
359         if (ret < 0) {
360                 pr_err("set_wakeup: can't write control register.\n");
361                 goto out;
362         }
363
364         /* Wait for wakeup */
365         for (i = 0; i < 300; i += (1 + i / 2)) {
366                 ret = cw1200_reg_read_16(priv,
367                         ST90TDS_CONTROL_REG_ID, &val16);
368                 if (ret < 0) {
369                         pr_err("wait_for_wakeup: can't read control register.\n");
370                         goto out;
371                 }
372
373                 if (val16 & ST90TDS_CONT_RDY_BIT)
374                         break;
375
376                 msleep(i);
377         }
378
379         if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
380                 pr_err("wait_for_wakeup: device is not responding.\n");
381                 ret = -ETIMEDOUT;
382                 goto out;
383         }
384
385         switch (major_revision) {
386         case 1:
387                 /* CW1200 Hardware detection logic : Check for CUT1.1 */
388                 ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
389                 if (ret) {
390                         pr_err("HW detection: can't read CUT ID.\n");
391                         goto out;
392                 }
393
394                 switch (val32) {
395                 case CW1200_CUT_11_ID_STR:
396                         pr_info("CW1x00 Cut 1.1 silicon detected.\n");
397                         priv->hw_revision = CW1200_HW_REV_CUT11;
398                         break;
399                 default:
400                         pr_info("CW1x00 Cut 1.0 silicon detected.\n");
401                         priv->hw_revision = CW1200_HW_REV_CUT10;
402                         break;
403                 }
404
405                 /* According to ST-E, CUT<2.0 has busted BA TID0-3.
406                    Just disable it entirely...
407                 */
408                 priv->ba_rx_tid_mask = 0;
409                 priv->ba_tx_tid_mask = 0;
410                 break;
411         case 2: {
412                 u32 ar1, ar2, ar3;
413                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
414                 if (ret) {
415                         pr_err("(1) HW detection: can't read CUT ID\n");
416                         goto out;
417                 }
418                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
419                 if (ret) {
420                         pr_err("(2) HW detection: can't read CUT ID.\n");
421                         goto out;
422                 }
423
424                 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
425                 if (ret) {
426                         pr_err("(3) HW detection: can't read CUT ID.\n");
427                         goto out;
428                 }
429
430                 if (ar1 == CW1200_CUT_22_ID_STR1 &&
431                     ar2 == CW1200_CUT_22_ID_STR2 &&
432                     ar3 == CW1200_CUT_22_ID_STR3) {
433                         pr_info("CW1x00 Cut 2.2 silicon detected.\n");
434                         priv->hw_revision = CW1200_HW_REV_CUT22;
435                 } else {
436                         pr_info("CW1x00 Cut 2.0 silicon detected.\n");
437                         priv->hw_revision = CW1200_HW_REV_CUT20;
438                 }
439                 break;
440         }
441         case 4:
442                 pr_info("CW1x60 silicon detected.\n");
443                 priv->hw_revision = CW1X60_HW_REV;
444                 break;
445         default:
446                 pr_err("Unsupported silicon major revision %d.\n",
447                        major_revision);
448                 ret = -ENOTSUPP;
449                 goto out;
450         }
451
452         /* Checking for access mode */
453         ret = config_reg_read(priv, &val32);
454         if (ret < 0) {
455                 pr_err("Can't read config register.\n");
456                 goto out;
457         }
458
459         if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
460                 pr_err("Device is already in QUEUE mode!\n");
461                         ret = -EINVAL;
462                         goto out;
463         }
464
465         switch (priv->hw_type)  {
466         case HIF_8601_SILICON:
467                 if (priv->hw_revision == CW1X60_HW_REV) {
468                         pr_err("Can't handle CW1160/1260 firmware load yet.\n");
469                         ret = -ENOTSUPP;
470                         goto out;
471                 }
472                 ret = cw1200_load_firmware_cw1200(priv);
473                 break;
474         default:
475                 pr_err("Can't perform firmware load for hw type %d.\n",
476                        priv->hw_type);
477                 ret = -ENOTSUPP;
478                 goto out;
479         }
480         if (ret < 0) {
481                 pr_err("Firmware load error.\n");
482                 goto out;
483         }
484
485         /* Enable interrupt signalling */
486         priv->hwbus_ops->lock(priv->hwbus_priv);
487         ret = __cw1200_irq_enable(priv, 1);
488         priv->hwbus_ops->unlock(priv->hwbus_priv);
489         if (ret < 0)
490                 goto unsubscribe;
491
492         /* Configure device for MESSSAGE MODE */
493         ret = config_reg_read(priv, &val32);
494         if (ret < 0) {
495                 pr_err("Can't read config register.\n");
496                 goto unsubscribe;
497         }
498         ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
499         if (ret < 0) {
500                 pr_err("Can't write config register.\n");
501                 goto unsubscribe;
502         }
503
504         /* Unless we read the CONFIG Register we are
505          * not able to get an interrupt
506          */
507         mdelay(10);
508         config_reg_read(priv, &val32);
509
510 out:
511         return ret;
512
513 unsubscribe:
514         /* Disable interrupt signalling */
515         priv->hwbus_ops->lock(priv->hwbus_priv);
516         ret = __cw1200_irq_enable(priv, 0);
517         priv->hwbus_ops->unlock(priv->hwbus_priv);
518         return ret;
519 }