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