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