]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/qe/qe.c
Merge branch 'u-boot-microblaze/zynq' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / qe / qe.c
1 /*
2  * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
3  *
4  * Dave Liu <daveliu@freescale.com>
5  * based on source code of Shlomi Gridish
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include "common.h"
11 #include <command.h>
12 #include "asm/errno.h"
13 #include "asm/io.h"
14 #include "asm/immap_qe.h"
15 #include "qe.h"
16
17 #define MPC85xx_DEVDISR_QE_DISABLE      0x1
18
19 qe_map_t                *qe_immr = NULL;
20 static qe_snum_t        snums[QE_NUM_OF_SNUM];
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
25 {
26         u32 cecr;
27
28         if (cmd == QE_RESET) {
29                 out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG));
30         } else {
31                 out_be32(&qe_immr->cp.cecdr, cmd_data);
32                 out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
33                          ((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd));
34         }
35         /* Wait for the QE_CR_FLG to clear */
36         do {
37                 cecr = in_be32(&qe_immr->cp.cecr);
38         } while (cecr & QE_CR_FLG);
39
40         return;
41 }
42
43 uint qe_muram_alloc(uint size, uint align)
44 {
45         uint    retloc;
46         uint    align_mask, off;
47         uint    savebase;
48
49         align_mask = align - 1;
50         savebase = gd->arch.mp_alloc_base;
51
52         off = gd->arch.mp_alloc_base & align_mask;
53         if (off != 0)
54                 gd->arch.mp_alloc_base += (align - off);
55
56         if ((off = size & align_mask) != 0)
57                 size += (align - off);
58
59         if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) {
60                 gd->arch.mp_alloc_base = savebase;
61                 printf("%s: ran out of ram.\n",  __FUNCTION__);
62         }
63
64         retloc = gd->arch.mp_alloc_base;
65         gd->arch.mp_alloc_base += size;
66
67         memset((void *)&qe_immr->muram[retloc], 0, size);
68
69         __asm__ __volatile__("sync");
70
71         return retloc;
72 }
73
74 void *qe_muram_addr(uint offset)
75 {
76         return (void *)&qe_immr->muram[offset];
77 }
78
79 static void qe_sdma_init(void)
80 {
81         volatile sdma_t *p;
82         uint            sdma_buffer_base;
83
84         p = (volatile sdma_t *)&qe_immr->sdma;
85
86         /* All of DMA transaction in bus 1 */
87         out_be32(&p->sdaqr, 0);
88         out_be32(&p->sdaqmr, 0);
89
90         /* Allocate 2KB temporary buffer for sdma */
91         sdma_buffer_base = qe_muram_alloc(2048, 4096);
92         out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
93
94         /* Clear sdma status */
95         out_be32(&p->sdsr, 0x03000000);
96
97         /* Enable global mode on bus 1, and 2KB buffer size */
98         out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
99 }
100
101 /* This table is a list of the serial numbers of the Threads, taken from the
102  * "SNUM Table" chart in the QE Reference Manual. The order is not important,
103  * we just need to know what the SNUMs are for the threads.
104  */
105 static u8 thread_snum[] = {
106 /* Evthreads 16-29 are not supported in MPC8309 */
107 #if !defined(CONFIG_MPC8309)
108         0x04, 0x05, 0x0c, 0x0d,
109         0x14, 0x15, 0x1c, 0x1d,
110         0x24, 0x25, 0x2c, 0x2d,
111         0x34, 0x35,
112 #endif
113         0x88, 0x89, 0x98, 0x99,
114         0xa8, 0xa9, 0xb8, 0xb9,
115         0xc8, 0xc9, 0xd8, 0xd9,
116         0xe8, 0xe9, 0x08, 0x09,
117         0x18, 0x19, 0x28, 0x29,
118         0x38, 0x39, 0x48, 0x49,
119         0x58, 0x59, 0x68, 0x69,
120         0x78, 0x79, 0x80, 0x81
121 };
122
123 static void qe_snums_init(void)
124 {
125         int     i;
126
127         for (i = 0; i < QE_NUM_OF_SNUM; i++) {
128                 snums[i].state = QE_SNUM_STATE_FREE;
129                 snums[i].num   = thread_snum[i];
130         }
131 }
132
133 int qe_get_snum(void)
134 {
135         int     snum = -EBUSY;
136         int     i;
137
138         for (i = 0; i < QE_NUM_OF_SNUM; i++) {
139                 if (snums[i].state == QE_SNUM_STATE_FREE) {
140                         snums[i].state = QE_SNUM_STATE_USED;
141                         snum = snums[i].num;
142                         break;
143                 }
144         }
145
146         return snum;
147 }
148
149 void qe_put_snum(u8 snum)
150 {
151         int     i;
152
153         for (i = 0; i < QE_NUM_OF_SNUM; i++) {
154                 if (snums[i].num == snum) {
155                         snums[i].state = QE_SNUM_STATE_FREE;
156                         break;
157                 }
158         }
159 }
160
161 void qe_init(uint qe_base)
162 {
163         /* Init the QE IMMR base */
164         qe_immr = (qe_map_t *)qe_base;
165
166 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
167         /*
168          * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
169          */
170         qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
171
172         /* enable the microcode in IRAM */
173         out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
174 #endif
175
176         gd->arch.mp_alloc_base = QE_DATAONLY_BASE;
177         gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE;
178
179         qe_sdma_init();
180         qe_snums_init();
181 }
182
183 void qe_reset(void)
184 {
185         qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
186                          (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
187 }
188
189 void qe_assign_page(uint snum, uint para_ram_base)
190 {
191         u32     cecr;
192
193         out_be32(&qe_immr->cp.cecdr, para_ram_base);
194         out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
195                                          | QE_CR_FLG | QE_ASSIGN_PAGE);
196
197         /* Wait for the QE_CR_FLG to clear */
198         do {
199                 cecr = in_be32(&qe_immr->cp.cecr);
200         } while (cecr & QE_CR_FLG );
201
202         return;
203 }
204
205 /*
206  * brg: 0~15 as BRG1~BRG16
207    rate: baud rate
208  * BRG input clock comes from the BRGCLK (internal clock generated from
209    the QE clock, it is one-half of the QE clock), If need the clock source
210    from CLKn pin, we have te change the function.
211  */
212
213 #define BRG_CLK         (gd->arch.brg_clk)
214
215 int qe_set_brg(uint brg, uint rate)
216 {
217         volatile uint   *bp;
218         u32             divisor;
219         int             div16 = 0;
220
221         if (brg >= QE_NUM_OF_BRGS)
222                 return -EINVAL;
223         bp = (uint *)&qe_immr->brg.brgc1;
224         bp += brg;
225
226         divisor = (BRG_CLK / rate);
227         if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
228                 div16 = 1;
229                 divisor /= 16;
230         }
231
232         *bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
233         __asm__ __volatile__("sync");
234
235         if (div16) {
236                 *bp |= QE_BRGC_DIV16;
237                 __asm__ __volatile__("sync");
238         }
239
240         return 0;
241 }
242
243 /* Set ethernet MII clock master
244 */
245 int qe_set_mii_clk_src(int ucc_num)
246 {
247         u32     cmxgcr;
248
249         /* check if the UCC number is in range. */
250         if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
251                 printf("%s: ucc num not in ranges\n", __FUNCTION__);
252                 return -EINVAL;
253         }
254
255         cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
256         cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
257         cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
258         out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
259
260         return 0;
261 }
262
263 /* Firmware information stored here for qe_get_firmware_info() */
264 static struct qe_firmware_info qe_firmware_info;
265
266 /*
267  * Set to 1 if QE firmware has been uploaded, and therefore
268  * qe_firmware_info contains valid data.
269  */
270 static int qe_firmware_uploaded;
271
272 /*
273  * Upload a QE microcode
274  *
275  * This function is a worker function for qe_upload_firmware().  It does
276  * the actual uploading of the microcode.
277  */
278 static void qe_upload_microcode(const void *base,
279         const struct qe_microcode *ucode)
280 {
281         const u32 *code = base + be32_to_cpu(ucode->code_offset);
282         unsigned int i;
283
284         if (ucode->major || ucode->minor || ucode->revision)
285                 printf("QE: uploading microcode '%s' version %u.%u.%u\n",
286                         ucode->id, ucode->major, ucode->minor, ucode->revision);
287         else
288                 printf("QE: uploading microcode '%s'\n", ucode->id);
289
290         /* Use auto-increment */
291         out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
292                 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
293
294         for (i = 0; i < be32_to_cpu(ucode->count); i++)
295                 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
296 }
297
298 /*
299  * Upload a microcode to the I-RAM at a specific address.
300  *
301  * See docs/README.qe_firmware for information on QE microcode uploading.
302  *
303  * Currently, only version 1 is supported, so the 'version' field must be
304  * set to 1.
305  *
306  * The SOC model and revision are not validated, they are only displayed for
307  * informational purposes.
308  *
309  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
310  * all of the microcode structures, minus the CRC.
311  *
312  * 'length' is the size that the structure says it is, including the CRC.
313  */
314 int qe_upload_firmware(const struct qe_firmware *firmware)
315 {
316         unsigned int i;
317         unsigned int j;
318         u32 crc;
319         size_t calc_size = sizeof(struct qe_firmware);
320         size_t length;
321         const struct qe_header *hdr;
322 #ifdef CONFIG_DEEP_SLEEP
323         ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
324 #endif
325         if (!firmware) {
326                 printf("Invalid address\n");
327                 return -EINVAL;
328         }
329
330         hdr = &firmware->header;
331         length = be32_to_cpu(hdr->length);
332
333         /* Check the magic */
334         if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
335             (hdr->magic[2] != 'F')) {
336                 printf("Not a microcode\n");
337 #ifdef CONFIG_DEEP_SLEEP
338                 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
339 #endif
340                 return -EPERM;
341         }
342
343         /* Check the version */
344         if (hdr->version != 1) {
345                 printf("Unsupported version\n");
346                 return -EPERM;
347         }
348
349         /* Validate some of the fields */
350         if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
351                 printf("Invalid data\n");
352                 return -EINVAL;
353         }
354
355         /* Validate the length and check if there's a CRC */
356         calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
357
358         for (i = 0; i < firmware->count; i++)
359                 /*
360                  * For situations where the second RISC uses the same microcode
361                  * as the first, the 'code_offset' and 'count' fields will be
362                  * zero, so it's okay to add those.
363                  */
364                 calc_size += sizeof(u32) *
365                         be32_to_cpu(firmware->microcode[i].count);
366
367         /* Validate the length */
368         if (length != calc_size + sizeof(u32)) {
369                 printf("Invalid length\n");
370                 return -EPERM;
371         }
372
373         /*
374          * Validate the CRC.  We would normally call crc32_no_comp(), but that
375          * function isn't available unless you turn on JFFS support.
376          */
377         crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
378         if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
379                 printf("Firmware CRC is invalid\n");
380                 return -EIO;
381         }
382
383         /*
384          * If the microcode calls for it, split the I-RAM.
385          */
386         if (!firmware->split) {
387                 out_be16(&qe_immr->cp.cercr,
388                         in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
389         }
390
391         if (firmware->soc.model)
392                 printf("Firmware '%s' for %u V%u.%u\n",
393                         firmware->id, be16_to_cpu(firmware->soc.model),
394                         firmware->soc.major, firmware->soc.minor);
395         else
396                 printf("Firmware '%s'\n", firmware->id);
397
398         /*
399          * The QE only supports one microcode per RISC, so clear out all the
400          * saved microcode information and put in the new.
401          */
402         memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
403         strcpy(qe_firmware_info.id, (char *)firmware->id);
404         qe_firmware_info.extended_modes = firmware->extended_modes;
405         memcpy(qe_firmware_info.vtraps, firmware->vtraps,
406                 sizeof(firmware->vtraps));
407         qe_firmware_uploaded = 1;
408
409         /* Loop through each microcode. */
410         for (i = 0; i < firmware->count; i++) {
411                 const struct qe_microcode *ucode = &firmware->microcode[i];
412
413                 /* Upload a microcode if it's present */
414                 if (ucode->code_offset)
415                         qe_upload_microcode(firmware, ucode);
416
417                 /* Program the traps for this processor */
418                 for (j = 0; j < 16; j++) {
419                         u32 trap = be32_to_cpu(ucode->traps[j]);
420
421                         if (trap)
422                                 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
423                 }
424
425                 /* Enable traps */
426                 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
427         }
428
429         return 0;
430 }
431
432 struct qe_firmware_info *qe_get_firmware_info(void)
433 {
434         return qe_firmware_uploaded ? &qe_firmware_info : NULL;
435 }
436
437 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
438 {
439         ulong addr;
440
441         if (argc < 3)
442                 return cmd_usage(cmdtp);
443
444         if (strcmp(argv[1], "fw") == 0) {
445                 addr = simple_strtoul(argv[2], NULL, 16);
446
447                 if (!addr) {
448                         printf("Invalid address\n");
449                         return -EINVAL;
450                 }
451
452                 /*
453                  * If a length was supplied, compare that with the 'length'
454                  * field.
455                  */
456
457                 if (argc > 3) {
458                         ulong length = simple_strtoul(argv[3], NULL, 16);
459                         struct qe_firmware *firmware = (void *) addr;
460
461                         if (length != be32_to_cpu(firmware->header.length)) {
462                                 printf("Length mismatch\n");
463                                 return -EINVAL;
464                         }
465                 }
466
467                 return qe_upload_firmware((const struct qe_firmware *) addr);
468         }
469
470         return cmd_usage(cmdtp);
471 }
472
473 U_BOOT_CMD(
474         qe, 4, 0, qe_cmd,
475         "QUICC Engine commands",
476         "fw <addr> [<length>] - Upload firmware binary at address <addr> to "
477                 "the QE,\n"
478         "\twith optional length <length> verification."
479 );