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