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