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