1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>
22#include <linux/spinlock.h>
23#include <linux/mm.h>
24#include <linux/interrupt.h>
25#include <linux/module.h>
26#include <linux/delay.h>
27#include <linux/ioport.h>
28#include <linux/crc32.h>
29#include <linux/mod_devicetable.h>
30#include <linux/of_platform.h>
31#include <asm/irq.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34#include <soc/fsl/qe/immap_qe.h>
35#include <soc/fsl/qe/qe.h>
36#include <asm/prom.h>
37#include <asm/rheap.h>
38
39static void qe_snums_init(void);
40static int qe_sdma_init(void);
41
42static DEFINE_SPINLOCK(qe_lock);
43DEFINE_SPINLOCK(cmxgcr_lock);
44EXPORT_SYMBOL(cmxgcr_lock);
45
46
47enum qe_snum_state {
48 QE_SNUM_STATE_USED,
49 QE_SNUM_STATE_FREE
50};
51
52
53struct qe_snum {
54 u8 num;
55 enum qe_snum_state state;
56};
57
58
59
60
61struct qe_immap __iomem *qe_immr;
62EXPORT_SYMBOL(qe_immr);
63
64static struct qe_snum snums[QE_NUM_OF_SNUM];
65static unsigned int qe_num_of_snum;
66
67static phys_addr_t qebase = -1;
68
69phys_addr_t get_qe_base(void)
70{
71 struct device_node *qe;
72 int size;
73 const u32 *prop;
74
75 if (qebase != -1)
76 return qebase;
77
78 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
79 if (!qe) {
80 qe = of_find_node_by_type(NULL, "qe");
81 if (!qe)
82 return qebase;
83 }
84
85 prop = of_get_property(qe, "reg", &size);
86 if (prop && size >= sizeof(*prop))
87 qebase = of_translate_address(qe, prop);
88 of_node_put(qe);
89
90 return qebase;
91}
92
93EXPORT_SYMBOL(get_qe_base);
94
95void qe_reset(void)
96{
97 if (qe_immr == NULL)
98 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
99
100 qe_snums_init();
101
102 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
103 QE_CR_PROTOCOL_UNSPECIFIED, 0);
104
105
106 qe_muram_init();
107
108 if (qe_sdma_init())
109 panic("sdma init failed!");
110}
111
112int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
113{
114 unsigned long flags;
115 u8 mcn_shift = 0, dev_shift = 0;
116 u32 ret;
117
118 spin_lock_irqsave(&qe_lock, flags);
119 if (cmd == QE_RESET) {
120 out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
121 } else {
122 if (cmd == QE_ASSIGN_PAGE) {
123
124 dev_shift = QE_CR_SNUM_SHIFT;
125 } else if (cmd == QE_ASSIGN_RISC) {
126
127
128 dev_shift = QE_CR_SNUM_SHIFT;
129 mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
130 } else {
131 if (device == QE_CR_SUBBLOCK_USB)
132 mcn_shift = QE_CR_MCN_USB_SHIFT;
133 else
134 mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
135 }
136
137 out_be32(&qe_immr->cp.cecdr, cmd_input);
138 out_be32(&qe_immr->cp.cecr,
139 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
140 mcn_protocol << mcn_shift));
141 }
142
143
144 ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
145 100, 0);
146
147
148 spin_unlock_irqrestore(&qe_lock, flags);
149
150 return ret == 1;
151}
152EXPORT_SYMBOL(qe_issue_cmd);
153
154
155
156
157
158
159
160
161
162
163
164static unsigned int brg_clk = 0;
165
166unsigned int qe_get_brg_clk(void)
167{
168 struct device_node *qe;
169 int size;
170 const u32 *prop;
171
172 if (brg_clk)
173 return brg_clk;
174
175 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
176 if (!qe) {
177 qe = of_find_node_by_type(NULL, "qe");
178 if (!qe)
179 return brg_clk;
180 }
181
182 prop = of_get_property(qe, "brg-frequency", &size);
183 if (prop && size == sizeof(*prop))
184 brg_clk = *prop;
185
186 of_node_put(qe);
187
188 return brg_clk;
189}
190EXPORT_SYMBOL(qe_get_brg_clk);
191
192
193
194
195
196
197
198
199
200int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
201{
202 u32 divisor, tempval;
203 u32 div16 = 0;
204
205 if ((brg < QE_BRG1) || (brg > QE_BRG16))
206 return -EINVAL;
207
208 divisor = qe_get_brg_clk() / (rate * multiplier);
209
210 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
211 div16 = QE_BRGC_DIV16;
212 divisor /= 16;
213 }
214
215
216
217
218 if (!div16 && (divisor & 1) && (divisor > 3))
219 divisor++;
220
221 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
222 QE_BRGC_ENABLE | div16;
223
224 out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
225
226 return 0;
227}
228EXPORT_SYMBOL(qe_setbrg);
229
230
231
232
233
234
235enum qe_clock qe_clock_source(const char *source)
236{
237 unsigned int i;
238
239 if (strcasecmp(source, "none") == 0)
240 return QE_CLK_NONE;
241
242 if (strncasecmp(source, "brg", 3) == 0) {
243 i = simple_strtoul(source + 3, NULL, 10);
244 if ((i >= 1) && (i <= 16))
245 return (QE_BRG1 - 1) + i;
246 else
247 return QE_CLK_DUMMY;
248 }
249
250 if (strncasecmp(source, "clk", 3) == 0) {
251 i = simple_strtoul(source + 3, NULL, 10);
252 if ((i >= 1) && (i <= 24))
253 return (QE_CLK1 - 1) + i;
254 else
255 return QE_CLK_DUMMY;
256 }
257
258 return QE_CLK_DUMMY;
259}
260EXPORT_SYMBOL(qe_clock_source);
261
262
263
264
265static void qe_snums_init(void)
266{
267 int i;
268 static const u8 snum_init_76[] = {
269 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
270 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
271 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
272 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
273 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
274 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
275 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
276 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
277 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
278 0xF4, 0xF5, 0xFC, 0xFD,
279 };
280 static const u8 snum_init_46[] = {
281 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
282 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
283 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
284 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
285 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
286 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
287 };
288 static const u8 *snum_init;
289
290 qe_num_of_snum = qe_get_num_of_snums();
291
292 if (qe_num_of_snum == 76)
293 snum_init = snum_init_76;
294 else
295 snum_init = snum_init_46;
296
297 for (i = 0; i < qe_num_of_snum; i++) {
298 snums[i].num = snum_init[i];
299 snums[i].state = QE_SNUM_STATE_FREE;
300 }
301}
302
303int qe_get_snum(void)
304{
305 unsigned long flags;
306 int snum = -EBUSY;
307 int i;
308
309 spin_lock_irqsave(&qe_lock, flags);
310 for (i = 0; i < qe_num_of_snum; i++) {
311 if (snums[i].state == QE_SNUM_STATE_FREE) {
312 snums[i].state = QE_SNUM_STATE_USED;
313 snum = snums[i].num;
314 break;
315 }
316 }
317 spin_unlock_irqrestore(&qe_lock, flags);
318
319 return snum;
320}
321EXPORT_SYMBOL(qe_get_snum);
322
323void qe_put_snum(u8 snum)
324{
325 int i;
326
327 for (i = 0; i < qe_num_of_snum; i++) {
328 if (snums[i].num == snum) {
329 snums[i].state = QE_SNUM_STATE_FREE;
330 break;
331 }
332 }
333}
334EXPORT_SYMBOL(qe_put_snum);
335
336static int qe_sdma_init(void)
337{
338 struct sdma __iomem *sdma = &qe_immr->sdma;
339 static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
340
341 if (!sdma)
342 return -ENODEV;
343
344
345
346 if (IS_ERR_VALUE(sdma_buf_offset)) {
347 sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
348 if (IS_ERR_VALUE(sdma_buf_offset))
349 return -ENOMEM;
350 }
351
352 out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
353 out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
354 (0x1 << QE_SDMR_CEN_SHIFT)));
355
356 return 0;
357}
358
359
360#define MAX_QE_RISC 4
361
362
363static struct qe_firmware_info qe_firmware_info;
364
365
366
367
368
369static int qe_firmware_uploaded;
370
371
372
373
374
375
376
377static void qe_upload_microcode(const void *base,
378 const struct qe_microcode *ucode)
379{
380 const __be32 *code = base + be32_to_cpu(ucode->code_offset);
381 unsigned int i;
382
383 if (ucode->major || ucode->minor || ucode->revision)
384 printk(KERN_INFO "qe-firmware: "
385 "uploading microcode '%s' version %u.%u.%u\n",
386 ucode->id, ucode->major, ucode->minor, ucode->revision);
387 else
388 printk(KERN_INFO "qe-firmware: "
389 "uploading microcode '%s'\n", ucode->id);
390
391
392 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
393 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
394
395 for (i = 0; i < be32_to_cpu(ucode->count); i++)
396 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
397
398
399 out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
400}
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419int qe_upload_firmware(const struct qe_firmware *firmware)
420{
421 unsigned int i;
422 unsigned int j;
423 u32 crc;
424 size_t calc_size = sizeof(struct qe_firmware);
425 size_t length;
426 const struct qe_header *hdr;
427
428 if (!firmware) {
429 printk(KERN_ERR "qe-firmware: invalid pointer\n");
430 return -EINVAL;
431 }
432
433 hdr = &firmware->header;
434 length = be32_to_cpu(hdr->length);
435
436
437 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
438 (hdr->magic[2] != 'F')) {
439 printk(KERN_ERR "qe-firmware: not a microcode\n");
440 return -EPERM;
441 }
442
443
444 if (hdr->version != 1) {
445 printk(KERN_ERR "qe-firmware: unsupported version\n");
446 return -EPERM;
447 }
448
449
450 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
451 printk(KERN_ERR "qe-firmware: invalid data\n");
452 return -EINVAL;
453 }
454
455
456 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
457
458 for (i = 0; i < firmware->count; i++)
459
460
461
462
463
464 calc_size += sizeof(__be32) *
465 be32_to_cpu(firmware->microcode[i].count);
466
467
468 if (length != calc_size + sizeof(__be32)) {
469 printk(KERN_ERR "qe-firmware: invalid length\n");
470 return -EPERM;
471 }
472
473
474 crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
475 if (crc != crc32(0, firmware, calc_size)) {
476 printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
477 return -EIO;
478 }
479
480
481
482
483 if (!firmware->split)
484 setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
485
486 if (firmware->soc.model)
487 printk(KERN_INFO
488 "qe-firmware: firmware '%s' for %u V%u.%u\n",
489 firmware->id, be16_to_cpu(firmware->soc.model),
490 firmware->soc.major, firmware->soc.minor);
491 else
492 printk(KERN_INFO "qe-firmware: firmware '%s'\n",
493 firmware->id);
494
495
496
497
498
499 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
500 strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
501 qe_firmware_info.extended_modes = firmware->extended_modes;
502 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
503 sizeof(firmware->vtraps));
504
505
506 for (i = 0; i < firmware->count; i++) {
507 const struct qe_microcode *ucode = &firmware->microcode[i];
508
509
510 if (ucode->code_offset)
511 qe_upload_microcode(firmware, ucode);
512
513
514 for (j = 0; j < 16; j++) {
515 u32 trap = be32_to_cpu(ucode->traps[j]);
516
517 if (trap)
518 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
519 }
520
521
522 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
523 }
524
525 qe_firmware_uploaded = 1;
526
527 return 0;
528}
529EXPORT_SYMBOL(qe_upload_firmware);
530
531
532
533
534
535
536
537struct qe_firmware_info *qe_get_firmware_info(void)
538{
539 static int initialized;
540 struct property *prop;
541 struct device_node *qe;
542 struct device_node *fw = NULL;
543 const char *sprop;
544 unsigned int i;
545
546
547
548
549
550 if (qe_firmware_uploaded)
551 return &qe_firmware_info;
552
553 if (initialized)
554 return NULL;
555
556 initialized = 1;
557
558
559
560
561
562 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
563 if (!qe) {
564 qe = of_find_node_by_type(NULL, "qe");
565 if (!qe)
566 return NULL;
567 }
568
569
570 for_each_child_of_node(qe, fw) {
571 if (strcmp(fw->name, "firmware") == 0)
572 break;
573 }
574
575 of_node_put(qe);
576
577
578 if (!fw)
579 return NULL;
580
581 qe_firmware_uploaded = 1;
582
583
584 sprop = of_get_property(fw, "id", NULL);
585 if (sprop)
586 strlcpy(qe_firmware_info.id, sprop,
587 sizeof(qe_firmware_info.id));
588
589 prop = of_find_property(fw, "extended-modes", NULL);
590 if (prop && (prop->length == sizeof(u64))) {
591 const u64 *iprop = prop->value;
592
593 qe_firmware_info.extended_modes = *iprop;
594 }
595
596 prop = of_find_property(fw, "virtual-traps", NULL);
597 if (prop && (prop->length == 32)) {
598 const u32 *iprop = prop->value;
599
600 for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
601 qe_firmware_info.vtraps[i] = iprop[i];
602 }
603
604 of_node_put(fw);
605
606 return &qe_firmware_info;
607}
608EXPORT_SYMBOL(qe_get_firmware_info);
609
610unsigned int qe_get_num_of_risc(void)
611{
612 struct device_node *qe;
613 int size;
614 unsigned int num_of_risc = 0;
615 const u32 *prop;
616
617 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
618 if (!qe) {
619
620
621
622
623 qe = of_find_node_by_type(NULL, "qe");
624 if (!qe)
625 return num_of_risc;
626 }
627
628 prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
629 if (prop && size == sizeof(*prop))
630 num_of_risc = *prop;
631
632 of_node_put(qe);
633
634 return num_of_risc;
635}
636EXPORT_SYMBOL(qe_get_num_of_risc);
637
638unsigned int qe_get_num_of_snums(void)
639{
640 struct device_node *qe;
641 int size;
642 unsigned int num_of_snums;
643 const u32 *prop;
644
645 num_of_snums = 28;
646 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
647 if (!qe) {
648
649
650
651
652 qe = of_find_node_by_type(NULL, "qe");
653 if (!qe)
654 return num_of_snums;
655 }
656
657 prop = of_get_property(qe, "fsl,qe-num-snums", &size);
658 if (prop && size == sizeof(*prop)) {
659 num_of_snums = *prop;
660 if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
661
662 pr_err("QE: number of snum is invalid\n");
663 of_node_put(qe);
664 return -EINVAL;
665 }
666 }
667
668 of_node_put(qe);
669
670 return num_of_snums;
671}
672EXPORT_SYMBOL(qe_get_num_of_snums);
673
674static int __init qe_init(void)
675{
676 struct device_node *np;
677
678 np = of_find_compatible_node(NULL, NULL, "fsl,qe");
679 if (!np)
680 return -ENODEV;
681 qe_reset();
682 of_node_put(np);
683 return 0;
684}
685subsys_initcall(qe_init);
686
687#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
688static int qe_resume(struct platform_device *ofdev)
689{
690 if (!qe_alive_during_sleep())
691 qe_reset();
692 return 0;
693}
694
695static int qe_probe(struct platform_device *ofdev)
696{
697 return 0;
698}
699
700static const struct of_device_id qe_ids[] = {
701 { .compatible = "fsl,qe", },
702 { },
703};
704
705static struct platform_driver qe_driver = {
706 .driver = {
707 .name = "fsl-qe",
708 .of_match_table = qe_ids,
709 },
710 .probe = qe_probe,
711 .resume = qe_resume,
712};
713
714static int __init qe_drv_init(void)
715{
716 return platform_driver_register(&qe_driver);
717}
718device_initcall(qe_drv_init);
719#endif
720