blob: 01bce3784b0acb89404c778a9e6ec20cfe0a13d7 [file] [log] [blame]
Li Yang98658532006-10-03 23:10:46 -05001/*
2 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
3 *
4 * Authors: Shlomi Gridish <gridish@freescale.com>
5 * Li Yang <leoli@freescale.com>
6 * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
7 *
8 * Description:
9 * General Purpose functions for the global management of the
10 * QUICC Engine (QE).
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/errno.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/string.h>
Anton Vorontsov09a3fba2008-11-11 18:31:39 +030022#include <linux/spinlock.h>
Li Yang98658532006-10-03 23:10:46 -050023#include <linux/mm.h>
24#include <linux/interrupt.h>
25#include <linux/bootmem.h>
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/ioport.h>
Timur Tabibc556ba2008-01-08 10:30:58 -060029#include <linux/crc32.h>
Li Yang98658532006-10-03 23:10:46 -050030#include <asm/irq.h>
31#include <asm/page.h>
32#include <asm/pgtable.h>
33#include <asm/immap_qe.h>
34#include <asm/qe.h>
35#include <asm/prom.h>
36#include <asm/rheap.h>
37
38static void qe_snums_init(void);
Li Yang98658532006-10-03 23:10:46 -050039static int qe_sdma_init(void);
40
41static DEFINE_SPINLOCK(qe_lock);
Anton Vorontsov09a3fba2008-11-11 18:31:39 +030042DEFINE_SPINLOCK(cmxgcr_lock);
43EXPORT_SYMBOL(cmxgcr_lock);
Li Yang98658532006-10-03 23:10:46 -050044
45/* QE snum state */
46enum qe_snum_state {
47 QE_SNUM_STATE_USED,
48 QE_SNUM_STATE_FREE
49};
50
51/* QE snum */
52struct qe_snum {
53 u8 num;
54 enum qe_snum_state state;
55};
56
57/* We allocate this here because it is used almost exclusively for
58 * the communication processor devices.
59 */
Anton Vorontsov0b51b022008-03-11 20:24:13 +030060struct qe_immap __iomem *qe_immr;
Li Yang98658532006-10-03 23:10:46 -050061EXPORT_SYMBOL(qe_immr);
62
63static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
64
65static phys_addr_t qebase = -1;
66
67phys_addr_t get_qe_base(void)
68{
69 struct device_node *qe;
Andy Fleming7e1cc9c2008-05-07 13:19:44 -050070 int size;
Anton Vorontsovd8985fd2008-02-04 16:46:17 +030071 const u32 *prop;
Li Yang98658532006-10-03 23:10:46 -050072
73 if (qebase != -1)
74 return qebase;
75
Anton Vorontsova2dd70a2008-01-24 18:39:59 +030076 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
77 if (!qe) {
78 qe = of_find_node_by_type(NULL, "qe");
79 if (!qe)
80 return qebase;
81 }
82
83 prop = of_get_property(qe, "reg", &size);
Anton Vorontsovd8985fd2008-02-04 16:46:17 +030084 if (prop && size >= sizeof(*prop))
85 qebase = of_translate_address(qe, prop);
Anton Vorontsova2dd70a2008-01-24 18:39:59 +030086 of_node_put(qe);
Li Yang98658532006-10-03 23:10:46 -050087
88 return qebase;
89}
90
91EXPORT_SYMBOL(get_qe_base);
92
Anton Vorontsov5848f162008-06-11 16:32:48 +040093void __init qe_reset(void)
Li Yang98658532006-10-03 23:10:46 -050094{
95 if (qe_immr == NULL)
96 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
97
98 qe_snums_init();
99
100 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
101 QE_CR_PROTOCOL_UNSPECIFIED, 0);
102
103 /* Reclaim the MURAM memory for our use. */
104 qe_muram_init();
105
106 if (qe_sdma_init())
107 panic("sdma init failed!");
108}
109
110int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
111{
112 unsigned long flags;
113 u8 mcn_shift = 0, dev_shift = 0;
114
115 spin_lock_irqsave(&qe_lock, flags);
116 if (cmd == QE_RESET) {
117 out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
118 } else {
119 if (cmd == QE_ASSIGN_PAGE) {
120 /* Here device is the SNUM, not sub-block */
121 dev_shift = QE_CR_SNUM_SHIFT;
122 } else if (cmd == QE_ASSIGN_RISC) {
123 /* Here device is the SNUM, and mcnProtocol is
124 * e_QeCmdRiscAssignment value */
125 dev_shift = QE_CR_SNUM_SHIFT;
126 mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
127 } else {
128 if (device == QE_CR_SUBBLOCK_USB)
129 mcn_shift = QE_CR_MCN_USB_SHIFT;
130 else
131 mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
132 }
133
Timur Tabi302439d2006-10-31 17:53:42 +0800134 out_be32(&qe_immr->cp.cecdr, cmd_input);
Li Yang98658532006-10-03 23:10:46 -0500135 out_be32(&qe_immr->cp.cecr,
136 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
137 mcn_protocol << mcn_shift));
138 }
139
140 /* wait for the QE_CR_FLG to clear */
141 while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
142 cpu_relax();
143 spin_unlock_irqrestore(&qe_lock, flags);
144
145 return 0;
146}
147EXPORT_SYMBOL(qe_issue_cmd);
148
149/* Set a baud rate generator. This needs lots of work. There are
150 * 16 BRGs, which can be connected to the QE channels or output
151 * as clocks. The BRGs are in two different block of internal
152 * memory mapped space.
Timur Tabi6b0b5942007-10-03 11:34:59 -0500153 * The BRG clock is the QE clock divided by 2.
Li Yang98658532006-10-03 23:10:46 -0500154 * It was set up long ago during the initial boot phase and is
155 * is given to us.
156 * Baud rate clocks are zero-based in the driver code (as that maps
157 * to port numbers). Documentation uses 1-based numbering.
158 */
159static unsigned int brg_clk = 0;
160
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300161unsigned int qe_get_brg_clk(void)
Li Yang98658532006-10-03 23:10:46 -0500162{
163 struct device_node *qe;
Andy Fleming7e1cc9c2008-05-07 13:19:44 -0500164 int size;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300165 const u32 *prop;
166
Li Yang98658532006-10-03 23:10:46 -0500167 if (brg_clk)
168 return brg_clk;
169
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300170 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
171 if (!qe) {
172 qe = of_find_node_by_type(NULL, "qe");
173 if (!qe)
174 return brg_clk;
175 }
176
177 prop = of_get_property(qe, "brg-frequency", &size);
Anton Vorontsovd8985fd2008-02-04 16:46:17 +0300178 if (prop && size == sizeof(*prop))
179 brg_clk = *prop;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300180
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300181 of_node_put(qe);
182
Li Yang98658532006-10-03 23:10:46 -0500183 return brg_clk;
184}
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300185EXPORT_SYMBOL(qe_get_brg_clk);
Li Yang98658532006-10-03 23:10:46 -0500186
Timur Tabi6b0b5942007-10-03 11:34:59 -0500187/* Program the BRG to the given sampling rate and multiplier
188 *
Timur Tabi7264ec42007-11-29 17:26:30 -0600189 * @brg: the BRG, QE_BRG1 - QE_BRG16
Timur Tabi6b0b5942007-10-03 11:34:59 -0500190 * @rate: the desired sampling rate
191 * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
192 * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
193 * then 'multiplier' should be 8.
Li Yang98658532006-10-03 23:10:46 -0500194 */
Timur Tabi7264ec42007-11-29 17:26:30 -0600195int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
Li Yang98658532006-10-03 23:10:46 -0500196{
Li Yang98658532006-10-03 23:10:46 -0500197 u32 divisor, tempval;
Timur Tabi6b0b5942007-10-03 11:34:59 -0500198 u32 div16 = 0;
Li Yang98658532006-10-03 23:10:46 -0500199
Timur Tabi7264ec42007-11-29 17:26:30 -0600200 if ((brg < QE_BRG1) || (brg > QE_BRG16))
201 return -EINVAL;
202
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300203 divisor = qe_get_brg_clk() / (rate * multiplier);
Li Yang98658532006-10-03 23:10:46 -0500204
Li Yang98658532006-10-03 23:10:46 -0500205 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
Timur Tabi6b0b5942007-10-03 11:34:59 -0500206 div16 = QE_BRGC_DIV16;
Li Yang98658532006-10-03 23:10:46 -0500207 divisor /= 16;
208 }
209
Timur Tabi6b0b5942007-10-03 11:34:59 -0500210 /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
211 that the BRG divisor must be even if you're not using divide-by-16
212 mode. */
213 if (!div16 && (divisor & 1))
214 divisor++;
Li Yang98658532006-10-03 23:10:46 -0500215
Timur Tabi6b0b5942007-10-03 11:34:59 -0500216 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
217 QE_BRGC_ENABLE | div16;
218
Timur Tabi7264ec42007-11-29 17:26:30 -0600219 out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
220
221 return 0;
Li Yang98658532006-10-03 23:10:46 -0500222}
Timur Tabi7264ec42007-11-29 17:26:30 -0600223EXPORT_SYMBOL(qe_setbrg);
Li Yang98658532006-10-03 23:10:46 -0500224
Timur Tabi174b0da2007-12-03 15:17:58 -0600225/* Convert a string to a QE clock source enum
226 *
227 * This function takes a string, typically from a property in the device
228 * tree, and returns the corresponding "enum qe_clock" value.
229*/
230enum qe_clock qe_clock_source(const char *source)
231{
232 unsigned int i;
233
234 if (strcasecmp(source, "none") == 0)
235 return QE_CLK_NONE;
236
237 if (strncasecmp(source, "brg", 3) == 0) {
238 i = simple_strtoul(source + 3, NULL, 10);
239 if ((i >= 1) && (i <= 16))
240 return (QE_BRG1 - 1) + i;
241 else
242 return QE_CLK_DUMMY;
243 }
244
245 if (strncasecmp(source, "clk", 3) == 0) {
246 i = simple_strtoul(source + 3, NULL, 10);
247 if ((i >= 1) && (i <= 24))
248 return (QE_CLK1 - 1) + i;
249 else
250 return QE_CLK_DUMMY;
251 }
252
253 return QE_CLK_DUMMY;
254}
255EXPORT_SYMBOL(qe_clock_source);
256
Li Yang98658532006-10-03 23:10:46 -0500257/* Initialize SNUMs (thread serial numbers) according to
258 * QE Module Control chapter, SNUM table
259 */
260static void qe_snums_init(void)
261{
262 int i;
263 static const u8 snum_init[] = {
264 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
265 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
266 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
267 0xD8, 0xD9, 0xE8, 0xE9,
268 };
269
270 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
271 snums[i].num = snum_init[i];
272 snums[i].state = QE_SNUM_STATE_FREE;
273 }
274}
275
276int qe_get_snum(void)
277{
278 unsigned long flags;
279 int snum = -EBUSY;
280 int i;
281
282 spin_lock_irqsave(&qe_lock, flags);
283 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
284 if (snums[i].state == QE_SNUM_STATE_FREE) {
285 snums[i].state = QE_SNUM_STATE_USED;
286 snum = snums[i].num;
287 break;
288 }
289 }
290 spin_unlock_irqrestore(&qe_lock, flags);
291
292 return snum;
293}
294EXPORT_SYMBOL(qe_get_snum);
295
296void qe_put_snum(u8 snum)
297{
298 int i;
299
300 for (i = 0; i < QE_NUM_OF_SNUM; i++) {
301 if (snums[i].num == snum) {
302 snums[i].state = QE_SNUM_STATE_FREE;
303 break;
304 }
305 }
306}
307EXPORT_SYMBOL(qe_put_snum);
308
309static int qe_sdma_init(void)
310{
Andy Fleming7e1cc9c2008-05-07 13:19:44 -0500311 struct sdma __iomem *sdma = &qe_immr->sdma;
Timur Tabi4c356302007-05-08 14:46:36 -0500312 unsigned long sdma_buf_offset;
Li Yang98658532006-10-03 23:10:46 -0500313
314 if (!sdma)
315 return -ENODEV;
316
317 /* allocate 2 internal temporary buffers (512 bytes size each) for
318 * the SDMA */
Chuck Meade7f013bc2007-03-27 10:46:10 -0400319 sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
Timur Tabi4c356302007-05-08 14:46:36 -0500320 if (IS_ERR_VALUE(sdma_buf_offset))
Li Yang98658532006-10-03 23:10:46 -0500321 return -ENOMEM;
322
Timur Tabi4c356302007-05-08 14:46:36 -0500323 out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
Chuck Meade7f013bc2007-03-27 10:46:10 -0400324 out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
325 (0x1 << QE_SDMR_CEN_SHIFT)));
Li Yang98658532006-10-03 23:10:46 -0500326
327 return 0;
328}
329
Timur Tabibc556ba2008-01-08 10:30:58 -0600330/* The maximum number of RISCs we support */
331#define MAX_QE_RISC 2
332
333/* Firmware information stored here for qe_get_firmware_info() */
334static struct qe_firmware_info qe_firmware_info;
335
336/*
337 * Set to 1 if QE firmware has been uploaded, and therefore
338 * qe_firmware_info contains valid data.
339 */
340static int qe_firmware_uploaded;
341
342/*
343 * Upload a QE microcode
344 *
345 * This function is a worker function for qe_upload_firmware(). It does
346 * the actual uploading of the microcode.
347 */
348static void qe_upload_microcode(const void *base,
349 const struct qe_microcode *ucode)
350{
351 const __be32 *code = base + be32_to_cpu(ucode->code_offset);
352 unsigned int i;
353
354 if (ucode->major || ucode->minor || ucode->revision)
355 printk(KERN_INFO "qe-firmware: "
356 "uploading microcode '%s' version %u.%u.%u\n",
357 ucode->id, ucode->major, ucode->minor, ucode->revision);
358 else
359 printk(KERN_INFO "qe-firmware: "
360 "uploading microcode '%s'\n", ucode->id);
361
362 /* Use auto-increment */
363 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
364 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
365
366 for (i = 0; i < be32_to_cpu(ucode->count); i++)
367 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
368}
369
370/*
371 * Upload a microcode to the I-RAM at a specific address.
372 *
373 * See Documentation/powerpc/qe-firmware.txt for information on QE microcode
374 * uploading.
375 *
376 * Currently, only version 1 is supported, so the 'version' field must be
377 * set to 1.
378 *
379 * The SOC model and revision are not validated, they are only displayed for
380 * informational purposes.
381 *
382 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
383 * all of the microcode structures, minus the CRC.
384 *
385 * 'length' is the size that the structure says it is, including the CRC.
386 */
387int qe_upload_firmware(const struct qe_firmware *firmware)
388{
389 unsigned int i;
390 unsigned int j;
391 u32 crc;
392 size_t calc_size = sizeof(struct qe_firmware);
393 size_t length;
394 const struct qe_header *hdr;
395
396 if (!firmware) {
397 printk(KERN_ERR "qe-firmware: invalid pointer\n");
398 return -EINVAL;
399 }
400
401 hdr = &firmware->header;
402 length = be32_to_cpu(hdr->length);
403
404 /* Check the magic */
405 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
406 (hdr->magic[2] != 'F')) {
407 printk(KERN_ERR "qe-firmware: not a microcode\n");
408 return -EPERM;
409 }
410
411 /* Check the version */
412 if (hdr->version != 1) {
413 printk(KERN_ERR "qe-firmware: unsupported version\n");
414 return -EPERM;
415 }
416
417 /* Validate some of the fields */
Timur Tabi6f913162008-03-03 11:11:30 -0600418 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
Timur Tabibc556ba2008-01-08 10:30:58 -0600419 printk(KERN_ERR "qe-firmware: invalid data\n");
420 return -EINVAL;
421 }
422
423 /* Validate the length and check if there's a CRC */
424 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
425
426 for (i = 0; i < firmware->count; i++)
427 /*
428 * For situations where the second RISC uses the same microcode
429 * as the first, the 'code_offset' and 'count' fields will be
430 * zero, so it's okay to add those.
431 */
432 calc_size += sizeof(__be32) *
433 be32_to_cpu(firmware->microcode[i].count);
434
435 /* Validate the length */
436 if (length != calc_size + sizeof(__be32)) {
437 printk(KERN_ERR "qe-firmware: invalid length\n");
438 return -EPERM;
439 }
440
441 /* Validate the CRC */
442 crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
443 if (crc != crc32(0, firmware, calc_size)) {
444 printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
445 return -EIO;
446 }
447
448 /*
449 * If the microcode calls for it, split the I-RAM.
450 */
451 if (!firmware->split)
452 setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
453
454 if (firmware->soc.model)
455 printk(KERN_INFO
456 "qe-firmware: firmware '%s' for %u V%u.%u\n",
457 firmware->id, be16_to_cpu(firmware->soc.model),
458 firmware->soc.major, firmware->soc.minor);
459 else
460 printk(KERN_INFO "qe-firmware: firmware '%s'\n",
461 firmware->id);
462
463 /*
464 * The QE only supports one microcode per RISC, so clear out all the
465 * saved microcode information and put in the new.
466 */
467 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
468 strcpy(qe_firmware_info.id, firmware->id);
469 qe_firmware_info.extended_modes = firmware->extended_modes;
470 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
471 sizeof(firmware->vtraps));
472
473 /* Loop through each microcode. */
474 for (i = 0; i < firmware->count; i++) {
475 const struct qe_microcode *ucode = &firmware->microcode[i];
476
477 /* Upload a microcode if it's present */
478 if (ucode->code_offset)
479 qe_upload_microcode(firmware, ucode);
480
481 /* Program the traps for this processor */
482 for (j = 0; j < 16; j++) {
483 u32 trap = be32_to_cpu(ucode->traps[j]);
484
485 if (trap)
486 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
487 }
488
489 /* Enable traps */
490 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
491 }
492
493 qe_firmware_uploaded = 1;
494
495 return 0;
496}
497EXPORT_SYMBOL(qe_upload_firmware);
498
499/*
500 * Get info on the currently-loaded firmware
501 *
502 * This function also checks the device tree to see if the boot loader has
503 * uploaded a firmware already.
504 */
505struct qe_firmware_info *qe_get_firmware_info(void)
506{
507 static int initialized;
508 struct property *prop;
509 struct device_node *qe;
510 struct device_node *fw = NULL;
511 const char *sprop;
512 unsigned int i;
513
514 /*
515 * If we haven't checked yet, and a driver hasn't uploaded a firmware
516 * yet, then check the device tree for information.
517 */
Ionut Nicu86f4e5d2008-03-07 19:27:59 +0200518 if (qe_firmware_uploaded)
519 return &qe_firmware_info;
520
521 if (initialized)
Timur Tabibc556ba2008-01-08 10:30:58 -0600522 return NULL;
523
524 initialized = 1;
525
526 /*
527 * Newer device trees have an "fsl,qe" compatible property for the QE
528 * node, but we still need to support older device trees.
529 */
530 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
531 if (!qe) {
532 qe = of_find_node_by_type(NULL, "qe");
533 if (!qe)
534 return NULL;
535 }
536
537 /* Find the 'firmware' child node */
538 for_each_child_of_node(qe, fw) {
539 if (strcmp(fw->name, "firmware") == 0)
540 break;
541 }
542
543 of_node_put(qe);
544
545 /* Did we find the 'firmware' node? */
546 if (!fw)
547 return NULL;
548
549 qe_firmware_uploaded = 1;
550
551 /* Copy the data into qe_firmware_info*/
552 sprop = of_get_property(fw, "id", NULL);
553 if (sprop)
554 strncpy(qe_firmware_info.id, sprop,
555 sizeof(qe_firmware_info.id) - 1);
556
557 prop = of_find_property(fw, "extended-modes", NULL);
558 if (prop && (prop->length == sizeof(u64))) {
559 const u64 *iprop = prop->value;
560
561 qe_firmware_info.extended_modes = *iprop;
562 }
563
564 prop = of_find_property(fw, "virtual-traps", NULL);
565 if (prop && (prop->length == 32)) {
566 const u32 *iprop = prop->value;
567
568 for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
569 qe_firmware_info.vtraps[i] = iprop[i];
570 }
571
572 of_node_put(fw);
573
574 return &qe_firmware_info;
575}
576EXPORT_SYMBOL(qe_get_firmware_info);
577