9be0aeab63c34d50f7947c163233a4790ab8a892
1 /******************************************************************************
2 * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *****************************************************************************/
14 /**************************************************************************************
15 * FILE NAME: pciedemo.c
16 *
17 * DESCRIPTION: A sample code to load DSP boot image from a Linux machine into DSP.
18 *
19 * Revision History:
20 * - 1.0: Initial version (6678 little endian PCIE boot POST demo)
21 * - 1.1: Add a new PCIE boot demo for HelloWorld
22 * - 1.2: support 6670 boot
23 * - 1.3: support big endian boot for 6670/6678; support 32-bit/64-bit Linux;
24 * support EDMA; support interrupt between host and DSP;
25 * added PCIE over EDMA throughput measurement
26 * - 1.4: Add a DSP local reset demo; fix pushData() to handle cases when
27 * sections within different memory regions in a header file
28 ***************************************************************************************/
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/kernel.h>
33 #include <linux/pci.h>
34 #include <linux/delay.h>
35 #include <linux/fs.h>
36 #include <linux/init.h>
37 #include <linux/ioport.h>
38 #include <linux/interrupt.h>
39 #include <asm/uaccess.h>
40 #include <asm/dma-mapping.h>
41 #include <linux/time.h>
43 MODULE_LICENSE("GPL v2");
45 /* Must select the endianess */
46 #define BIG_ENDIAN 0
48 /* Must select which demo to run */
49 #define HELLO_WORLD_DEMO 1
50 #define POST_DEMO 0
51 #define EDMA_INTC_DEMO 0
52 #define LOCAL_RESET 0
54 /* Must select a platform */
55 #define EVMC6678L 1
56 #define EVMC6670L 0
58 #if BIG_ENDIAN
59 #define myIoread32 ioread32be
60 #define myIowrite32 iowrite32be
61 #else
62 #define myIoread32 ioread32
63 #define myIowrite32 iowrite32
64 #endif
66 #if EVMC6678L
67 #define MAGIC_ADDR 0x0087FFFC
68 #endif
70 #if EVMC6670L
71 #define MAGIC_ADDR 0x008FFFFC
72 #endif
74 /* Include header array */
75 #if HELLO_WORLD_DEMO
77 #if EVMC6678L
78 #include "pcieDdrInit_6678.h" /* DDR init */
79 #include "pcieBootCode_6678.h" /* "Hello world" boot example */
80 #endif
82 #if EVMC6670L
83 #include "pcieDdrInit_6670.h" /* DDR init */
84 #include "pcieBootCode_6670.h" /* "Hello world" boot example */
85 #endif
87 #endif
89 #if POST_DEMO
91 #if EVMC6678L
92 #include "post_6678.h" /* POST boot example */
93 #endif
95 #if EVMC6670L
96 #include "post_6670.h" /* POST boot example */
97 #endif
99 #endif
101 #if EDMA_INTC_DEMO
103 #if EVMC6678L
104 #include "pcieInterrupt_6678.h" /* EDMA-Interrupt boot example */
105 #endif
107 #if EVMC6670L
108 #include "pcieInterrupt_6670.h" /* EDMA-Interrupt boot example */
109 #endif
111 #endif
113 #if LOCAL_RESET
115 #if EVMC6678L
116 #include "pcieLocalReset_6678.h"
117 #endif
119 #if EVMC6670L
120 #include "pcieLocalReset_6670.h"
121 #endif
123 #endif
125 /* PCIE registers */
126 #define PCIE_BASE_ADDRESS 0x21800000
127 #define OB_SIZE 0x30
128 #define PRIORITY 0x3C
129 #define EP_IRQ_CLR 0x68
130 #define EP_IRQ_STATUS 0x6C
131 #define LEGACY_A_IRQ_STATUS_RAW 0x180
132 #define LEGACY_A_IRQ_ENABLE_SET 0x188
133 #define LEGACY_A_IRQ_ENABLE_CLR 0x18C
134 #define OB_OFFSET_INDEX(n) (0x200 + (8 * (n)))
135 #define OB_OFFSET_HI(n) (0x204 + (8 * (n)))
136 #define IB_BAR(n) (0x300 + (0x10 * (n)))
137 #define IB_START_LO(n) (0x304 + (0x10 * (n)))
138 #define IB_START_HI(n) (0x308 + (0x10 * (n)))
139 #define IB_OFFSET(n) (0x30C + (0x10 * (n)))
141 #define PCIE_TI_VENDOR 0x104C
142 #define PCIE_TI_DEVICE 0xB005
144 /* PSC registers */
145 #define PSC_BASE_ADDRESS 0x02350000
146 #define PTCMD 0x120
147 #define PTSTAT 0x128
148 #define PDSTAT(n) (0x200 + (4 * (n)))
149 #define PDCTL(n) (0x300 + (4 * (n)))
150 #define MDSTAT(n) (0x800 + (4 * (n)))
151 #define MDCTL(n) (0xA00 + (4 * (n)))
153 /* EDMA registers */
154 #define EDMA_TPCC0_BASE_ADDRESS 0x02700000
155 #define DMAQNUM0 0x0240
156 #define ESR 0x1010
157 #define EESR 0x1030
158 #define IESR 0x1060
159 #define IPR 0x1068
160 #define ICR 0x1070
161 #define PARAM_0_OPT 0x4000
162 #define PARAM_0_SRC 0x4004
163 #define PARAM_0_A_B_CNT 0x4008
164 #define PARAM_0_DST 0x400C
165 #define PARAM_0_SRC_DST_BIDX 0x4010
166 #define PARAM_0_LINK_BCNTRLD 0x4014
167 #define PARAM_0_SRC_DST_CIDX 0x4018
168 #define PARAM_0_CCNT 0x401C
170 /* Chip level registers */
171 #define CHIP_LEVEL_BASE_ADDRESS 0x02620000
172 #define KICK0 0x38
173 #define KICK1 0x3C
174 #define KICK0_UNLOCK 0x83E70B13
175 #define KICK1_UNLOCK 0x95A4F1E0
176 #define KICK_LOCK 0x0
177 #define DSP_BOOT_ADDR(n) (0x040 + (4 * (n)))
178 #define IPCGR(n) (0x240 + (4 * (n)))
181 #define LL2_START 0x00800000
182 #define MSMC_START 0x0C000000 /* Shared L2 */
183 #define DDR_START 0x80000000
184 #define PCIE_DATA 0x60000000
186 /* Block size in bytes when r/w data between GPP and DSP via DSP CPU */
187 #define BLOCK_TRANSFER_SIZE 0x100
189 /* Data size in bytes when r/w data bewteen GPP and DSP via EDMA:
190 GPP----PCIE link----PCIE data space----EDMA----DSP device memory (L2, DDR, ...) */
191 #define DMA_TRANSFER_SIZE 0x400000 /* 4MB */
193 /* Payload size in bytes over PCIE link. PCIe module supports
194 outbound payload size of 128 bytes and inbound payload size of 256 bytes */
195 #define PCIE_TRANSFER_SIZE 0x80
197 /* For 1MB outbound translation window size */
198 #define PCIE_ADLEN_1MB 0x00100000
199 #define PCIE_1MB_BITMASK 0xFFF00000
201 #define PSC_SWRSTDISABLE 0x0
202 #define PSC_ENABLE 0x3
204 #define LOC_RST_ASSERT 0x0
205 #define LOC_RST_DEASSERT 0x1
207 /* Power domains definitions */
208 #define PD0 0 // Power Domain-0
209 #define PD1 1 // Power Domain-1
210 #define PD2 2 // Power Domain-2
211 #define PD3 3 // Power Domain-3
212 #define PD4 4 // Power Domain-4
213 #define PD5 5 // Power Domain-5
214 #define PD6 6 // Power Domain-6
215 #define PD7 7 // Power Domain-7
216 #define PD8 8 // Power Domain-8
217 #define PD9 9 // Power Domain-9
218 #define PD10 10 // Power Domain-10
219 #define PD11 11 // Power Domain-11
220 #define PD12 12 // Power Domain-12
221 #define PD13 13 // Power Domain-13
222 #define PD14 14 // Power Domain-14
223 #define PD15 15 // Power Domain-15
224 #define PD16 16 // Power Domain-16
225 #define PD17 17 // Power Domain-17
227 #if EVMC6670L
228 /* Modules on power domain 0 */
229 #define LPSC_TCP3E 3
230 #define LPSC_VCP2A 4
232 /* Modules on power domain 1 */
233 #define LPSC_DEBUG 5
234 #define LPSC_TETB 6
236 /* Modules on power domain 2 */
237 #define LPSC_PA 7
238 #define LPSC_SGMII 8
239 #define LPSC_SA 9
241 /* Modules on power domain 3 */
242 #define LPSC_PCIE 10
244 /* Modules on power domain 4 */
245 #define LPSC_SRIO 11
247 /* Modules on power domain 5 */
248 #define LPSC_HYPER 12
250 /* Modules on power domain 6 */
251 #define LPSC_RESERV 13
253 /* Modules on power domain 7 */
254 #define LPSC_MSMCRAM 14
256 /* Modules on power domain 8 */
257 #define LPSC_RACA_RACB 15
258 #define LPSC_TAC 16
260 /* Modules on power domain 9 */
261 #define LPSC_FFTCA_FFTCB 17
263 /* Modules on power domain 10 */
264 #define LPSC_AIF2 18
266 /* Modules on power domain 11 */
267 #define LPSC_TCP3DA 19
269 /* Modules on power domain 12 */
270 #define LPSC_VCP2B 20
271 #define LPSC_VCP2C 21
272 #define LPSC_VCP2D 22
274 /* Modules on power domain 13 */
275 #define LPSC_C0_TIM0 23
277 /* Modules on power domain 14 */
278 #define LPSC_C1_TIM1 24
279 #define LPSC_C1_RSA 25
281 /* Modules on power domain 15 */
282 #define LPSC_C2_TIM2 26
283 #define LPSC_C2_RSA 27
285 /* Modules on power domain 16 */
286 #define LPSC_C3_TIM3 28
288 /* Modules on power domain 17 */
289 #define LPSC_TCP3dB 29
291 #endif
293 #if EVMC6678L
294 /* Modules on power domain 0 */
295 #define LPSC_EMIF16_SPI 3
296 #define LPSC_TSIP 4
298 /* Modules on power domain 1 */
299 #define LPSC_DEBUG 5
300 #define LPSC_TETB_TRC 6
302 /* Modules on power domain 2 */
303 #define LPSC_PA 7
304 #define LPSC_SGMII 8
305 #define LPSC_SA 9
307 /* Modules on power domain 3 */
308 #define LPSC_PCIE 10
310 /* Modules on power domain 4 */
311 #define LPSC_SRIO 11
313 /* Modules on power domain 5 */
314 #define LPSC_HYPER 12
316 /* Modules on power domain 6 */
317 #define LPSC_RESERV 13
319 /* Modules on power domain 7 */
320 #define LPSC_MSMCRAM 14
322 /* Modules on power domain 8 */
323 #define LPSC_C0_TIM0 15
325 /* Modules on power domain 9 */
326 #define LPSC_C1_TIM1 16
328 /* Modules on power domain 10 */
329 #define LPSC_C2_TIM2 17
331 /* Modules on power domain 11 */
332 #define LPSC_C3_TIM3 18
334 /* Modules on power domain 12 */
335 #define LPSC_C4_TIM4 19
337 /* Modules on power domain 13 */
338 #define LPSC_C5_TIM5 20
340 /* Modules on power domain 14 */
341 #define LPSC_C6_TIM6 21
343 /* Modules on power domain 15 */
344 #define LPSC_C7_TIM7 22
346 #endif
348 /*
349 reg: PCIE application registers
350 mem: Local L2
351 msmc: Shared L2 memory
352 ddr: DDR3
353 */
355 uint8_t *wDataVirt, *rDataVirt; /* Virtue address for CPU */
356 dma_addr_t wData, rData; /* Physical PCIE bus address */
359 /***********************************************
360 * uncomment following line on very old kernels:
361 * typedef unsigned long resource_size_t;
362 **********************************************/
363 resource_size_t regBase = 0;
364 resource_size_t memBase = 0;
365 resource_size_t msmcBase = 0;
366 resource_size_t ddrBase = 0;
368 uint32_t *regVirt = NULL;
369 uint32_t *memVirt = NULL;
370 uint32_t *msmcVirt = NULL;
371 uint32_t *ddrVirt = NULL;
373 resource_size_t memLen = 0;
374 resource_size_t regLen = 0;
375 resource_size_t msmcLen = 0;
376 resource_size_t ddrLen = 0;
378 uint32_t *ptrReg = 0;
379 int32_t irqNo;
380 uint32_t dummy;
381 struct pci_dev *PCIE_DEV = NULL;
383 struct timeval test_time1;
384 struct timeval test_time2;
385 struct timeval test_time3;
386 struct timeval test_time4;
388 /* ============================================================================
389 * @func PCI_FindPciDevices
390 *
391 * @desc This function locates 6670/6678 PCIE cards on system.
392 *
393 * @modif None.
394 * ============================================================================
395 */
396 void PCI_FindPciDevices(void)
397 {
398 struct pci_dev *dev = NULL;
400 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
401 {
402 if ((dev->vendor == PCIE_TI_VENDOR) && (dev->device == PCIE_TI_DEVICE)) {
403 printk("Found TI device\n");
404 irqNo = dev->irq;
405 PCIE_DEV = dev;
406 printk("TI device: vendor=0x%04x, dev=0x%04x, irq=0x%08x\n", dev->vendor, dev->device, dev->irq);
407 break;
408 }
409 }
410 }
412 /* ============================================================================
413 * @func PCI_readBAR
414 *
415 * @desc This function reads config.
416 *
417 * @modif None.
418 * ============================================================================
419 */
420 void PCI_readBAR(void)
421 {
422 resource_size_t barStart[4];
423 resource_size_t barLen[4];
424 resource_size_t barFlags[4];
426 barStart [0] = pci_resource_start (PCIE_DEV, 0); /* BAR0 4K for PCIE application registers */
427 barLen [0] = pci_resource_len (PCIE_DEV, 0);
428 barFlags [0] = pci_resource_flags (PCIE_DEV, 0);
429 barStart [1] = pci_resource_start (PCIE_DEV, 1); /* BAR1 512K/1024K for 6678/6670 Local L2 */
430 barLen [1] = pci_resource_len (PCIE_DEV, 1);
431 barFlags [1] = pci_resource_flags (PCIE_DEV, 1);
432 barStart [2] = pci_resource_start (PCIE_DEV, 2); /* BAR2 4M/2M for 6678/6670 Shared L2 */
433 barLen [2] = pci_resource_len (PCIE_DEV, 2);
434 barFlags [2] = pci_resource_flags (PCIE_DEV, 2);
435 barStart [3] = pci_resource_start (PCIE_DEV, 3); /* BAR3 16M for DDR3 */
436 barLen [3] = pci_resource_len (PCIE_DEV, 3);
437 barFlags [3] = pci_resource_flags (PCIE_DEV, 3);
439 /* ---------------------------------------------------------------------
440 * Map the REG memory region
441 * ---------------------------------------------------------------------
442 */
443 if (barFlags[0] & IORESOURCE_MEM) {
444 regBase = barStart[0];
445 /* Map the memory region. */
446 request_mem_region(regBase, barLen[0], "DSPLINK");
447 }
448 else {
449 /* Map the memory region. */
450 request_region(regBase, barLen[0], "DSPLINK");
451 }
453 if (regBase > 0) {
454 regVirt = ioremap(barStart[0], barLen[0]);
455 }
457 /* ---------------------------------------------------------------------
458 * Map the LL2RAM memory region
459 * ---------------------------------------------------------------------
460 */
461 if (barFlags[1] & IORESOURCE_MEM) {
462 memBase = barStart[1];
463 /* Map the memory region. */
464 request_mem_region(memBase, barLen[1], "DSPLINK");
465 }
466 else {
467 /* Map the memory region. */
468 request_region(memBase, barLen[1], "DSPLINK");
469 }
471 if (memBase > 0) {
472 memVirt = ioremap(barStart[1], barLen[1]);
473 }
475 /* ---------------------------------------------------------------------
476 * Map the MSMC memory region
477 * ---------------------------------------------------------------------
478 */
479 if (barFlags[2] & IORESOURCE_MEM) {
480 msmcBase = barStart[2];
481 /* Map the memory region. */
482 request_mem_region(msmcBase, barLen[2], "DSPLINK");
483 }
484 else {
485 /* Map the memory region. */
486 request_region(msmcBase, barLen[2], "DSPLINK");
487 }
489 if (msmcBase > 0) {
490 msmcVirt = ioremap(barStart[2], barLen[2]);
491 }
493 /* ---------------------------------------------------------------------
494 * Map the DDR memory region
495 * ---------------------------------------------------------------------
496 */
497 if (barFlags[3] & IORESOURCE_MEM) {
498 ddrBase = barStart[3];
499 /* Map the memory region. */
500 request_mem_region(ddrBase, barLen[3], "DSPLINK");
501 }
502 else {
503 /* Map the memory region. */
504 request_region(ddrBase, barLen[3], "DSPLINK");
505 }
507 if (ddrBase > 0) {
508 ddrVirt = ioremap(barStart[3], barLen[3]);
509 }
511 regLen = barLen[0];
512 memLen = barLen[1];
513 msmcLen = barLen[2];
514 ddrLen = barLen[3];
516 }
518 /* =============================================================================
519 * @func PCI_setMaster
520 *
521 * @desc This function makes the given device to be master.
522 *
523 * @modif None.
524 * ============================================================================
525 */
526 void PCI_setMaster(void)
527 {
528 int32_t retVal;
529 uint16_t cmdVal;
530 struct pci_dev *dev;
532 dev = PCIE_DEV;
534 /* set the DMA mask */
535 if (pci_set_dma_mask(dev, 0xfffffff0ULL)) {
536 }
538 /* set the desired PCI dev to be master, this internally sets the latency timer */
539 pci_set_master(dev);
540 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
542 /* Add support memory write invalidate */
543 retVal = pci_set_mwi(dev);
545 pci_read_config_word(dev, PCI_COMMAND, (u16 *)&cmdVal);
546 /* and set the master bit in command register. */
547 cmdVal |= PCI_COMMAND_MEMORY
548 | PCI_COMMAND_MASTER
549 | PCI_COMMAND_SERR;
550 /* and clear the interrupt disable bit in command register. */
551 cmdVal &= ~PCI_COMMAND_INTX_DISABLE;
552 pci_write_config_word(dev, PCI_COMMAND, cmdVal);
553 }
555 /* =============================================================================
556 * @func HAL_CheckPciInterrupt
557 *
558 * @desc This function check whether interrupt is generated by C667x or not.
559 *
560 * @modif None.
561 * ============================================================================
562 */
563 bool HAL_CheckPciInterrupt(void)
564 {
565 uint32_t *pReg = (uint32_t *)regVirt;
566 return ioread32(pReg + EP_IRQ_STATUS/4);
567 }
569 /** ============================================================================
570 * @func HAL_PciClearDspInterrupt
571 *
572 * @desc Clear pending interrupt from DSP to Host.
573 *
574 * @modif None.
575 * ============================================================================
576 */
577 void HAL_PciClearDspInterrupt(void)
578 {
579 uint32_t *pReg = (uint32_t *)regVirt;
580 iowrite32(1, pReg+EP_IRQ_CLR/4);
581 }
583 /** ============================================================================
584 * @func HAL_PciEnableDspInterrupt
585 *
586 * @desc Allow the DSP to generate interrupts to the Host.
587 *
588 * @modif None.
589 * ============================================================================
590 */
591 void HAL_PciEnableDspInterrupt(void)
592 {
593 uint32_t *pReg = (uint32_t *)regVirt;
594 iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_SET/4);
595 }
597 /** ============================================================================
598 * @func HAL_PciDisableDspInterrupt
599 *
600 * @desc Disable the DSP to generate interrupts to the Host.
601 *
602 * @modif None.
603 * ============================================================================
604 */
605 void HAL_PciDisableDspInterrupt(void)
606 {
607 uint32_t *pReg = (uint32_t *)regVirt;
608 iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_CLR/4);
609 }
612 /* ============================================================================
613 * @func HAL_readDMA
614 *
615 * @desc Move DMAs contents from DSP memory to GPP Memory. For DSP this is
616 * outbound write.
617 * flag: 0: Move data inside DSP; 1: Move data between GPP and DSP
618 *
619 * @modif None.
620 * ============================================================================
621 */
622 void HAL_readDMA(uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag)
623 {
624 uint32_t *pReg, tmp, pageBase, i, tSize;
626 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
628 /* Move data between GPP and DSP, need to program PCIE OB registers */
629 if (flag) {
630 iowrite32(0x0, pReg + OB_SIZE/4); /* 1MB outbound translation size */
632 if (size <= PCIE_ADLEN_1MB) {
633 pageBase = dstAddr & PCIE_1MB_BITMASK;
634 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(0)/4);
635 iowrite32(0x0, pReg + OB_OFFSET_HI(0)/4);
636 }
637 else {
638 for (tmp = size, i = 0; tmp > 0; tmp -= PCIE_ADLEN_1MB, i++) {
639 pageBase = (dstAddr + (PCIE_ADLEN_1MB * i)) & PCIE_1MB_BITMASK;
640 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(i)/4);
641 iowrite32(0x0, pReg + OB_OFFSET_HI(i)/4);
642 }
643 }
644 }
646 /* Temporarily re-map IB region 3 from DDR memory to EDMA registers */
647 iowrite32(EDMA_TPCC0_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
649 pReg = (uint32_t*)ddrVirt; /* Now it points to the start of EDMA_TPCC0_BASE_ADDRESS */
651 while (true) {
652 /* Use TC0 for DBS = 128 bytes */
653 myIowrite32(0x0, pReg + DMAQNUM0/4);
655 /* Set the interrupt enable for 1st Channel (IER). */
656 myIowrite32(0x1, pReg + IESR/4);
658 /* Clear any pending interrupt (IPR). */
659 myIowrite32(0x1, pReg + ICR/4);
661 /* Populate the Param entry. */
662 myIowrite32(0x00100004, pReg + PARAM_0_OPT/4); /* Enable SYNCDIM and TCINTEN, TCC = 0 */
664 if (flag == 1) {
665 /* Calculate the DSP PCI address for the PC address */
666 tmp = PCIE_DATA + (dstAddr & ~PCIE_1MB_BITMASK);
667 myIowrite32(tmp, pReg + PARAM_0_DST/4);
668 } else {
669 myIowrite32(dstAddr, pReg + PARAM_0_DST/4);
670 }
672 /* Calculate the A & B count */
673 if (size > PCIE_TRANSFER_SIZE) {
674 tmp = size/PCIE_TRANSFER_SIZE;
675 tSize = tmp*PCIE_TRANSFER_SIZE;
676 size -= (tmp*PCIE_TRANSFER_SIZE);
677 tmp <<= 16;
678 tmp |= PCIE_TRANSFER_SIZE;
679 }
680 else {
681 tmp = 0x10000|size;
682 tSize = size;
683 size = 0;
684 }
686 myIowrite32(tmp, pReg + PARAM_0_A_B_CNT/4);
687 myIowrite32(srcAddr, pReg + PARAM_0_SRC/4);
689 myIowrite32(((PCIE_TRANSFER_SIZE<<16)|PCIE_TRANSFER_SIZE), pReg + PARAM_0_SRC_DST_BIDX/4);
690 myIowrite32(0xFFFF, pReg + PARAM_0_LINK_BCNTRLD/4);
691 myIowrite32(0x0, pReg + PARAM_0_SRC_DST_CIDX/4);
693 /* C Count is set to 1 since mostly size will not be more than 1.75GB */
694 myIowrite32(0x1, pReg + PARAM_0_CCNT/4);
696 /* Set the Event Enable Set Register. */
697 myIowrite32(0x1, pReg + EESR/4);
699 /* Set the event set register. */
700 myIowrite32(0x1, pReg + ESR/4);
702 /* wait for current DMA to finish. */
703 while (true) {
704 /* check in steps of 10 usec. */
705 udelay(10);
706 tmp = myIoread32(pReg + IPR/4);
707 if ((tmp & 0x1) == 1) {
708 break;
709 }
710 }
712 if (size != 0) {
713 srcAddr += tSize;
714 dstAddr += tSize;
715 } else {
716 break;
717 }
718 }
720 /* Clear any pending interrupt. */
721 myIowrite32(1, pReg + ICR/4);
723 /* Restore pointer */
724 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
725 iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
726 }
728 /* ============================================================================
729 * @func HAL_writeDMA
730 *
731 * @desc Move DMAs contents from GPP memory to DSP Memory. For DSP this is
732 * outbound read.
733 * flag: 0: Move data inside DSP; 1: Move data between GPP and DSP
734 *
735 * @modif None.
736 * ============================================================================
737 */
738 void HAL_writeDMA(uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag)
739 {
740 uint32_t *pReg, tmp, pageBase, i, tSize;
742 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
744 /* Move data between GPP and DSP, need to program PCIE OB registers */
745 if (flag) {
746 iowrite32(0x0, pReg + OB_SIZE/4); /* 1MB outbound translation size */
748 if (size <= PCIE_ADLEN_1MB) {
749 pageBase = srcAddr & PCIE_1MB_BITMASK;
750 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(0)/4);
751 iowrite32(0x0, pReg + OB_OFFSET_HI(0)/4);
752 }
753 else {
754 for (tmp = size, i = 0; tmp > 0; tmp -= PCIE_ADLEN_1MB, i++) {
755 pageBase = (srcAddr + (PCIE_ADLEN_1MB * i)) & PCIE_1MB_BITMASK;
756 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(i)/4);
757 iowrite32(0x0, pReg + OB_OFFSET_HI(i)/4);
758 }
759 }
760 }
762 /* Temporarily re-map IB region 3 from DDR memory to EDMA registers */
763 iowrite32(EDMA_TPCC0_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
765 pReg = (uint32_t*)ddrVirt; /* Now it points to the start of EDMA_TPCC0_BASE_ADDRESS */
767 while (true) {
768 /* Use TC0 for DBS = 128 bytes */
769 myIowrite32(0x0, pReg + DMAQNUM0/4);
771 /* Set the interrupt enable for 1st Channel (IER). */
772 myIowrite32(0x1, pReg + IESR/4);
774 /* Clear any pending interrupt (IPR). */
775 myIowrite32(0x1, pReg + ICR/4);
777 /* Populate the Param entry. */
778 myIowrite32(0x00100004, pReg + PARAM_0_OPT/4); /* Enable SYNCDIM and TCINTEN, TCC = 0 */
780 if (flag == 1) {
781 /* Calculate the DSP PCI address for the PC address */
782 tmp = PCIE_DATA + (srcAddr & ~PCIE_1MB_BITMASK);
783 myIowrite32(tmp, pReg + PARAM_0_SRC/4);
784 } else {
785 myIowrite32(srcAddr, pReg + PARAM_0_SRC/4);
786 }
788 /* Calculate the A & B count */
789 if (size > PCIE_TRANSFER_SIZE) {
790 tmp = size/PCIE_TRANSFER_SIZE;
791 tSize = tmp*PCIE_TRANSFER_SIZE;
792 size -= (tmp*PCIE_TRANSFER_SIZE);
793 tmp <<= 16;
794 tmp |= PCIE_TRANSFER_SIZE;
795 }
796 else {
797 tmp = 0x10000|size;
798 tSize = size;
799 size = 0;
800 }
802 myIowrite32(tmp, pReg + PARAM_0_A_B_CNT/4);
803 myIowrite32(dstAddr, pReg + PARAM_0_DST/4);
805 myIowrite32(((PCIE_TRANSFER_SIZE<<16)|PCIE_TRANSFER_SIZE), pReg + PARAM_0_SRC_DST_BIDX/4);
806 myIowrite32(0xFFFF, pReg + PARAM_0_LINK_BCNTRLD/4);
807 myIowrite32(0x0, pReg + PARAM_0_SRC_DST_CIDX/4);
809 /* C Count is set to 1 since mostly size will not be more than 1.75GB */
810 myIowrite32(0x1, pReg + PARAM_0_CCNT/4);
812 /* Set the Event Enable Set Register. */
813 myIowrite32(0x1, pReg + EESR/4);
815 /* Set the event set register. */
816 myIowrite32(0x1, pReg + ESR/4);
818 /* wait for current DMA to finish. */
819 while (true) {
820 /* check in steps of 10 usec. */
821 udelay(10);
822 tmp = myIoread32(pReg + IPR/4);
823 if ((tmp & 0x1) == 1) {
824 break;
825 }
826 }
828 if (size != 0) {
829 srcAddr += tSize;
830 dstAddr += tSize;
831 } else {
832 break;
833 }
834 }
836 /* Clear any pending interrupt. */
837 myIowrite32(1, pReg + ICR/4);
839 /* Restore pointer */
840 pReg = (uint32_t *)regVirt; //Point to PCIE application registers
841 iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
842 }
844 /** ============================================================================
845 * @func ISR_handler
846 *
847 * @desc ISR.
848 *
849 * @modif None.
850 * ============================================================================
851 */
852 static irqreturn_t ISR_handler(int irq, void *arg)
853 {
854 uint32_t i, dma_failure_flag = 0, counter = 0;
855 uint32_t status = HAL_CheckPciInterrupt();
857 if (status == 1) {
858 printk("Interrupt %d received from DSP\n", irq);
859 printk("Read DMA from DSP ...\n");
860 do_gettimeofday(&test_time3);
861 HAL_readDMA(DDR_START, rData, DMA_TRANSFER_SIZE, 1); /* Move from DSP to GPP */
862 do_gettimeofday(&test_time4);
864 for (i = 0; i < DMA_TRANSFER_SIZE; i++) {
865 if ((~(rDataVirt[i])&0xFF) != wDataVirt[i]) {
866 dma_failure_flag = 1;
867 counter++;
868 }
869 }
871 if (dma_failure_flag)
872 printk("DMA test failed with %d locations !\n", counter);
873 else
874 printk("DMA test passed!\n");
876 HAL_PciClearDspInterrupt();
877 return IRQ_HANDLED;
878 }
879 return IRQ_NONE;
880 }
882 /* ============================================================================
883 * @func byteto32bits
884 *
885 * @desc Convert 4 bytes to 32 bits long word
886 *
887 * @modif None.
888 * ============================================================================
889 */
890 uint32_t byteTo32bits(uint8_t *pDspCode)
891 {
892 uint32_t i, temp;
894 temp = *pDspCode++;
895 for(i = 0; i < 3;i++) {
896 temp <<= 8;
897 temp |= *pDspCode++;
898 }
899 return(temp);
900 }
902 /* ============================================================================
903 * @func swap4bytes
904 *
905 * @desc Endian swap: 0xA0B1C2D3 to 0xD3C2B1A0
906 *
907 * @modif None.
908 * ============================================================================
909 */
910 void swap4bytes(uint32_t *pDspCode, uint32_t size)
911 {
912 uint32_t i, temp;
914 for(i = 0; i < size; i += 4, pDspCode++) {
915 temp = *pDspCode;
916 temp = (temp>>24) |
917 ((temp<<8) & 0x00FF0000) |
918 ((temp>>8) & 0x0000FF00) |
919 (temp<<24);
921 *pDspCode = temp;
922 }
923 }
925 /* ============================================================================
926 * @func writeDSPMemory
927 *
928 * @desc Write a block of data into DSP memory from Linux host.
929 * Note the data buffer is in 32-bit format, unit of length is byte.
930 * coreNum: to write data: 0-7 for cores 0-7; 8 for MSMC; 9 for DDR.
931 *
932 * @modif None.
933 * ============================================================================
934 */
935 uint32_t writeDSPMemory(uint32_t coreNum, uint32_t DSPMemAddr, uint32_t *buffer, uint32_t length)
936 {
937 uint32_t i, offset, tempReg = 0;
938 uint32_t *ptr;
940 if (length == 0) {
941 return 0;
942 }
944 switch (coreNum) {
945 #if EVMC6678L
946 case 0:
947 case 1:
948 case 2:
949 case 3:
950 case 4:
951 case 5:
952 case 6:
953 case 7:
954 #endif
955 #if EVMC6670L
956 case 0:
957 case 1:
958 case 2:
959 case 3:
960 #endif
961 DSPMemAddr &= 0x00FFFFFF;
962 tempReg = ioread32(ptrReg + IB_OFFSET(1)/4);
963 iowrite32(tempReg + coreNum*0x01000000, ptrReg + IB_OFFSET(1)/4); /* pointing to a different core */
965 if (DSPMemAddr < LL2_START) {
966 return 0;
967 } else {
968 offset = DSPMemAddr - LL2_START;
969 ptr = (uint32_t *)memVirt + offset/4;
970 }
971 break;
972 case 8: /* this is for MSMC */
973 if (DSPMemAddr < MSMC_START) {
974 return 0;
975 } else {
976 offset = DSPMemAddr - MSMC_START;
977 ptr = (uint32_t *)msmcVirt + offset/4;
978 }
979 break;
980 case 9: /* this is for DDR */
981 if (DSPMemAddr < DDR_START) {
982 return 0;
983 } else {
984 offset = DSPMemAddr - DDR_START;
985 ptr = (uint32_t *)ddrVirt + offset/4;
986 }
987 break;
988 default:
989 printk("Use coreNum 0-7 for core 0-7 of EVMC6678L, or coreNum 0-3 for core 0-3 of EVMC6670L; coreNum 8 for MSMC and coreNum 9 for DDR.\n");
990 return 0;
991 break;
992 }
994 for (i = 0; i < length/4; i++) {
995 #if BIG_ENDIAN
996 swap4bytes(&buffer[i], 4);
997 #endif
998 *ptr = buffer[i];
999 ptr++;
1000 }
1002 if ((coreNum >= 0)&&(coreNum <= 7)) {
1003 iowrite32(tempReg, ptrReg + IB_OFFSET(1)/4); /* Restore IB_OFFSET1 */
1004 }
1006 return length;
1007 }
1009 /* ============================================================================
1010 * @func readDSPMemory
1011 *
1012 * @desc Read a block of DSP memory by Linux host.
1013 * Note the data buffer is in 32-bit format, unit of length is byte.
1014 * coreNum: to read data: 0-7 for cores 0-7; 8 for MSMC; 9 for DDR.
1015 *
1016 * @modif None.
1017 * ============================================================================
1018 */
1019 uint32_t readDSPMemory(uint32_t coreNum, uint32_t DSPMemAddr, uint32_t *buffer, uint32_t length)
1020 {
1021 uint32_t i, offset, tempReg = 0;
1022 uint32_t *ptr;
1024 if (length == 0) {
1025 return 0;
1026 }
1028 switch (coreNum) {
1029 #if EVMC6678L
1030 case 0:
1031 case 1:
1032 case 2:
1033 case 3:
1034 case 4:
1035 case 5:
1036 case 6:
1037 case 7:
1038 #endif
1039 #if EVMC6670L
1040 case 0:
1041 case 1:
1042 case 2:
1043 case 3:
1044 #endif
1045 DSPMemAddr &= 0x00FFFFFF;
1046 tempReg = ioread32(ptrReg + IB_OFFSET(1)/4);
1047 iowrite32(tempReg + coreNum*0x1000000, ptrReg + IB_OFFSET(1)/4); /* pointing to a different core */
1048 if (DSPMemAddr < LL2_START) {
1049 return 0;
1050 } else {
1051 offset = DSPMemAddr - LL2_START;
1052 ptr = (uint32_t *)memVirt + offset/4;
1053 }
1054 break;
1055 case 8: /* this is for MSMC */
1056 if (DSPMemAddr < MSMC_START) {
1057 return 0;
1058 } else {
1059 offset = DSPMemAddr - MSMC_START;
1060 ptr = (uint32_t *)msmcVirt + offset/4;
1061 }
1062 break;
1063 case 9: /* this is for DDR */
1064 if (DSPMemAddr < DDR_START) {
1065 return 0;
1066 } else {
1067 offset = DSPMemAddr - DDR_START;
1068 ptr = (uint32_t *)ddrVirt + offset/4;
1069 }
1070 break;
1071 default:
1072 printk("Use coreNum 0-7 for core 0-7 of EVMC6678L, or coreNum 0-3 for core 0-3 of EVMC6670L; coreNum 8 for MSMC and coreNum 9 for DDR.\n");
1073 return 0;
1074 break;
1075 }
1077 for (i = 0; i < length/4; i++) {
1078 buffer[i] = *ptr;
1079 #if BIG_ENDIAN
1080 swap4bytes(&buffer[i], 4);
1081 #endif
1082 ptr++;
1083 }
1085 if ((coreNum >= 0)&&(coreNum <= 7)) {
1086 iowrite32(tempReg, ptrReg + IB_OFFSET(1)/4); /* Restore IB_OFFSET1 */
1087 }
1089 return length;
1090 }
1092 /* ============================================================================
1093 * @func pushData
1094 *
1095 * @desc Parser function for DSP boot image array
1096 *
1097 * @modif None.
1098 * ============================================================================
1099 */
1100 void pushData(uint8_t *pDspCode, uint8_t coreNum, uint32_t *bootEntryAddr)
1101 {
1102 uint32_t i, j, tempArray[BLOCK_TRANSFER_SIZE/4];
1103 uint32_t size, section = 0, totalSize = 0;
1104 uint32_t count, remainder, startAddr, temp;
1105 uint8_t newCoreNum;
1107 /* Get the boot entry address */
1108 *bootEntryAddr = byteTo32bits(pDspCode);
1109 printk("Boot entry address is 0x%8x\n", *bootEntryAddr);
1110 pDspCode +=4;
1112 while(1) {
1114 /* Get the size */
1115 size = byteTo32bits(pDspCode);
1116 if(size == 0) break;
1118 if ((size/4)*4 != size) {
1119 size = ((size/4)+1)*4;
1120 }
1122 totalSize += size;
1123 section++;
1124 pDspCode += 4;
1125 startAddr = byteTo32bits(pDspCode);
1127 /* In case there are several sections within different memory regions */
1128 temp = (startAddr & 0xFF000000) >> 24;
1130 if (temp == 0x00 || ((temp >> 4) == 0x1)) {
1131 if (coreNum < 8) {
1132 /* Write address like 0x00800000 to core 1, 2, ... */
1133 newCoreNum = coreNum;
1134 } else {
1135 newCoreNum = 0;
1136 }
1137 } else if (temp == 0x0C) {
1138 newCoreNum = 8;
1139 } else {
1140 newCoreNum = 9;
1141 }
1143 pDspCode+= 4;
1144 count = size/BLOCK_TRANSFER_SIZE;
1145 remainder = size - count * BLOCK_TRANSFER_SIZE;
1147 for(i = 0; i < count; i++) {
1148 for (j = 0; j < BLOCK_TRANSFER_SIZE/4; j++) {
1149 tempArray[j] = byteTo32bits(pDspCode);
1150 pDspCode += 4;
1151 }
1152 /* Transfer boot tables to DSP */
1153 writeDSPMemory(newCoreNum, startAddr, tempArray, BLOCK_TRANSFER_SIZE);
1154 startAddr += BLOCK_TRANSFER_SIZE;
1155 }
1157 for (j = 0; j < remainder/4; j++) {
1158 tempArray[j] = byteTo32bits(pDspCode);
1159 pDspCode += 4;
1160 }
1161 writeDSPMemory(newCoreNum, startAddr, tempArray, remainder);
1162 // printk("Section %d started at 0x%8x with size 0x%8x bytes written to core %d\n", section, startAddr, size, newCoreNum);
1163 }
1164 printk("Total %d sections, 0x%x bytes of data were written\n", section, totalSize);
1165 }
1168 #if LOCAL_RESET
1169 /* ============================================================================
1170 * @func coreLocalReset
1171 *
1172 * @desc Reset a particular CorePac, 6678 Data Manual, section 7.4.4
1173 * initiated by LPSC MMRs
1174 *
1175 * @modif None.
1176 * ============================================================================
1177 */
1178 void coreLocalReset(uint32_t pid, uint32_t mid, uint32_t state)
1179 {
1180 uint32_t *pReg, temp, counter = 0;
1182 /* Point to PCIE application registers */
1183 pReg = (uint32_t *)regVirt;
1184 /* Set MST_PRIV bit to access PSC via PCIE */
1185 iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1187 /* Temporarily re-map IB region 3 from DDR memory to PSC registers */
1188 iowrite32(PSC_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1189 /* Now it points to the start of PSC_BASE_ADDRESS */
1190 pReg = (uint32_t*)ddrVirt;
1192 temp = myIoread32(pReg + MDCTL(mid)/4);
1193 if (state == 0) {
1194 /* Reset assert */
1195 temp = ((temp & ~0x1F) | PSC_ENABLE) & (~0x100);
1196 printk("Start local reset assert for core (module id): %d ...\n", mid);
1197 } else {
1198 /* Reset de-assert */
1199 temp = (temp & ~0x1F) | PSC_ENABLE | (1 << 8);
1200 printk("Start local reset de-assert for core (module id): %d ...\n", mid);
1201 }
1203 myIowrite32(temp, pReg + MDCTL(mid)/4); /* Assert/De-assert local reset */
1205 /* No previous transition in progress */
1206 counter = 0;
1207 while (true) {
1208 temp = myIoread32(pReg + PTSTAT/4);
1209 if ((temp & (1 << pid)) == 0) break;
1210 mdelay(1);
1211 counter ++;
1212 if (counter > 10) {
1213 printk("Previous transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1214 break;
1215 }
1216 }
1218 myIowrite32((1 << pid), pReg + PTCMD/4);
1220 /* Current transition finished */
1221 counter = 0;
1222 while (true) {
1223 temp = myIoread32(pReg + PTSTAT/4);
1224 if ((temp & (1 << pid)) == 0) break;
1225 mdelay(1);
1226 counter ++;
1227 if (counter > 10) {
1228 printk("Current transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1229 break;
1230 }
1231 }
1233 /* Verifying state change */
1234 counter = 0;
1235 while (true) {
1236 temp = myIoread32(pReg + MDSTAT(mid)/4);
1237 if ((temp & 0x1F) == 3) break;
1238 mdelay(1);
1239 counter ++;
1240 if (counter > 10) {
1241 printk("MD stat for pid %d mid %d state: %d timeout\n", pid, mid, state);
1242 break;
1243 }
1244 }
1246 /* Restore pointer */
1247 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
1248 iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1249 }
1251 /* ============================================================================
1252 * @func setPscState
1253 *
1254 * @desc Set a new power state for the specified domain id in a power controler
1255 * domain. Wait for the power transition to complete.
1256 *
1257 * pid - power domain.
1258 * mid - module id to use for module in the specified power domain
1259 * state - new state value to set (0 = RESET; 3 = ENABLE)
1260 *
1261 * @modif None.
1262 * ============================================================================
1263 */
1264 void setPscState(uint32_t pid, uint32_t mid, uint32_t state)
1265 {
1266 uint32_t *pReg, mdctl, pdctl, temp, counter = 0;
1268 /* Point to PCIE application registers */
1269 pReg = (uint32_t *)regVirt;
1270 /* Set MST_PRIV bit to access PSC via PCIE */
1271 iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1273 /* Temporarily re-map IB region 3 from DDR memory to PSC registers */
1274 iowrite32(PSC_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1275 /* Now it points to the start of PSC_BASE_ADDRESS */
1276 pReg = (uint32_t*)ddrVirt;
1278 mdctl = myIoread32(pReg + MDCTL(mid)/4);
1279 pdctl = myIoread32(pReg + PDCTL(pid)/4);
1281 /* No previous transition in progress */
1282 counter = 0;
1283 while (true) {
1284 temp = myIoread32(pReg + PTSTAT/4);
1285 if ((temp & (1 << pid)) == 0) break;
1286 mdelay(1);
1287 counter ++;
1288 if (counter > 10) {
1289 printk("Previous transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1290 break;
1291 }
1292 }
1294 /* Set power domain control */
1295 myIowrite32(pdctl | 0x1, pReg + PDCTL(pid)/4);
1297 /* Set MDCTL NEXT to new state */
1298 mdctl = ((mdctl) & ~(0x1f)) | state;
1299 myIowrite32(mdctl, pReg + MDCTL(mid)/4);
1301 /* Start power transition by setting PTCMD GO to 1 */
1302 temp = myIoread32(pReg + PTCMD/4);
1303 myIowrite32(temp | (0x1<<pid), pReg + PTCMD/4);
1305 /* Current transition finished */
1306 counter = 0;
1307 while (true) {
1308 temp = myIoread32(pReg + PTSTAT/4);
1309 if ((temp & (1 << pid)) == 0) break;
1310 mdelay(1);
1311 counter ++;
1312 if (counter > 10) {
1313 printk("Current transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1314 break;
1315 }
1316 }
1318 /* Verifying state change */
1319 counter = 0;
1320 while (true) {
1321 temp = myIoread32(pReg + MDSTAT(mid)/4);
1322 if ((temp & 0x1F) == state) break;
1323 mdelay(1);
1324 counter ++;
1325 if (counter > 10) {
1326 printk("MD stat for pid %d mid %d state: %d timeout\n", pid, mid, state);
1327 break;
1328 }
1329 }
1331 /* Restore pointer */
1332 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
1333 iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1334 }
1336 /* ============================================================================
1337 * @func setBootAddrIpcgr
1338 *
1339 * @desc Write boot entry point into DSP_BOOT_ADDR0 and the send an IPC
1340 *
1341 * @modif None.
1342 * ============================================================================
1343 */
1344 uint32_t setBootAddrIpcgr(uint32_t core, uint32_t addr)
1345 {
1346 uint32_t *pReg;
1347 /* Point to PCIE application registers */
1348 pReg = (uint32_t *)regVirt;
1349 /* Set MST_PRIV bit to access PSC via PCIE */
1350 iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1352 /* Temporarily re-map IB region 3 from DDR memory to chip level registers */
1353 iowrite32(CHIP_LEVEL_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1354 /* Now it points to the start of CHIP_LEVEL_BASE_ADDRESS */
1355 pReg = (uint32_t*)ddrVirt;
1357 /* Unlock KICK0, KICK1 */
1358 myIowrite32(KICK0_UNLOCK, pReg + KICK0/4);
1359 myIowrite32(KICK1_UNLOCK, pReg + KICK1/4);
1361 /* Check if the last 10 bits of addr is 0 */
1362 if ((addr & 0x3f) != 0) {
1363 printk("The address is not 1K aligned.\n");
1364 return 0;
1365 }
1367 myIowrite32(addr, pReg + DSP_BOOT_ADDR(core)/4);
1368 myIowrite32(1, pReg + IPCGR(core)/4);
1370 mdelay(1);
1372 /* Restore pointer */
1373 pReg = (uint32_t *)regVirt; /* Point to PCIE application registers */
1374 iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1376 return 1;
1377 }
1379 /* ============================================================================
1380 * @func dspLocalReset
1381 *
1382 * @desc Perform DSP cores and periphrals reset
1383 *
1384 * @modif None.
1385 * ============================================================================
1386 */
1387 void dspLocalReset(void)
1388 {
1389 uint32_t i, bootEntryAddr = 0;
1391 #if EVMC6670L
1392 /* Local reset of all cores */
1393 coreLocalReset(PD13, LPSC_C0_TIM0, LOC_RST_ASSERT);
1394 coreLocalReset(PD14, LPSC_C1_TIM1, LOC_RST_ASSERT);
1395 coreLocalReset(PD15, LPSC_C2_TIM2, LOC_RST_ASSERT);
1396 coreLocalReset(PD16, LPSC_C3_TIM3, LOC_RST_ASSERT);
1398 /* Disable all other modules */
1399 setPscState(PD0, LPSC_TCP3E, PSC_SWRSTDISABLE);
1400 setPscState(PD0, LPSC_VCP2A, PSC_SWRSTDISABLE);
1401 setPscState(PD1, LPSC_DEBUG, PSC_SWRSTDISABLE);
1402 setPscState(PD1, LPSC_TETB, PSC_SWRSTDISABLE);
1403 setPscState(PD2, LPSC_SA, PSC_SWRSTDISABLE);
1404 setPscState(PD2, LPSC_SGMII, PSC_SWRSTDISABLE);
1405 setPscState(PD2, LPSC_PA, PSC_SWRSTDISABLE);
1406 //setPscState(PD3, LPSC_PCIE, PSC_SWRSTDISABLE);
1407 setPscState(PD4, LPSC_SRIO, PSC_SWRSTDISABLE);
1408 setPscState(PD5, LPSC_HYPER, PSC_SWRSTDISABLE);
1409 //setPscState(PD6, LPSC_RESERV, PSC_SWRSTDISABLE);
1410 setPscState(PD7, LPSC_MSMCRAM, PSC_SWRSTDISABLE);
1411 setPscState(PD8, LPSC_RACA_RACB, PSC_SWRSTDISABLE);
1412 setPscState(PD8, LPSC_TAC, PSC_SWRSTDISABLE);
1413 setPscState(PD9, LPSC_FFTCA_FFTCB, PSC_SWRSTDISABLE);
1414 setPscState(PD10, LPSC_AIF2, PSC_SWRSTDISABLE);
1415 setPscState(PD11, LPSC_TCP3DA, PSC_SWRSTDISABLE);
1416 setPscState(PD12, LPSC_VCP2B, PSC_SWRSTDISABLE);
1417 setPscState(PD12, LPSC_VCP2C, PSC_SWRSTDISABLE);
1418 setPscState(PD12, LPSC_VCP2D, PSC_SWRSTDISABLE);
1419 setPscState(PD17, LPSC_TCP3dB, PSC_SWRSTDISABLE);
1421 for (i = 0; i < 4; i++) {
1422 pushData(localResetCode, i, &bootEntryAddr);
1423 if (setBootAddrIpcgr(i, bootEntryAddr) == 0) {
1424 printk("Core %d is not ready !!! \n", i);
1425 }
1426 }
1428 /* Enable all other modules */
1429 setPscState(PD0, LPSC_TCP3E, PSC_ENABLE);
1430 setPscState(PD0, LPSC_VCP2A, PSC_ENABLE);
1431 setPscState(PD1, LPSC_DEBUG, PSC_ENABLE);
1432 setPscState(PD1, LPSC_TETB, PSC_ENABLE);
1433 setPscState(PD2, LPSC_PA, PSC_ENABLE);
1434 setPscState(PD2, LPSC_SGMII, PSC_ENABLE);
1435 setPscState(PD2, LPSC_SA, PSC_ENABLE);
1436 //setPscState(PD3, LPSC_PCIE, PSC_ENABLE);
1437 setPscState(PD4, LPSC_SRIO, PSC_ENABLE);
1438 setPscState(PD5, LPSC_HYPER, PSC_ENABLE);
1439 //setPscState(PD6, LPSC_RESERV, PSC_ENABLE);
1440 setPscState(PD7, LPSC_MSMCRAM, PSC_ENABLE);
1441 setPscState(PD8, LPSC_RACA_RACB, PSC_ENABLE);
1442 setPscState(PD8, LPSC_TAC, PSC_ENABLE);
1443 setPscState(PD9, LPSC_FFTCA_FFTCB, PSC_ENABLE);
1444 setPscState(PD10, LPSC_AIF2, PSC_ENABLE);
1445 setPscState(PD11, LPSC_TCP3DA, PSC_ENABLE);
1446 setPscState(PD12, LPSC_VCP2B, PSC_ENABLE);
1447 setPscState(PD12, LPSC_VCP2C, PSC_ENABLE);
1448 setPscState(PD12, LPSC_VCP2D, PSC_ENABLE);
1449 setPscState(PD17, LPSC_TCP3dB, PSC_ENABLE);
1451 /* Local out of reset of all cores */
1452 coreLocalReset(PD13, LPSC_C0_TIM0, LOC_RST_DEASSERT);
1453 coreLocalReset(PD14, LPSC_C1_TIM1, LOC_RST_DEASSERT);
1454 coreLocalReset(PD15, LPSC_C2_TIM2, LOC_RST_DEASSERT);
1455 coreLocalReset(PD16, LPSC_C3_TIM3, LOC_RST_DEASSERT);
1456 #endif
1458 #if EVMC6678L
1459 /* Local reset of all cores */
1460 coreLocalReset(PD8, LPSC_C0_TIM0, LOC_RST_ASSERT);
1461 coreLocalReset(PD9, LPSC_C1_TIM1, LOC_RST_ASSERT);
1462 coreLocalReset(PD10, LPSC_C2_TIM2, LOC_RST_ASSERT);
1463 coreLocalReset(PD11, LPSC_C3_TIM3, LOC_RST_ASSERT);
1464 coreLocalReset(PD12, LPSC_C4_TIM4, LOC_RST_ASSERT);
1465 coreLocalReset(PD13, LPSC_C5_TIM5, LOC_RST_ASSERT);
1466 coreLocalReset(PD14, LPSC_C6_TIM6, LOC_RST_ASSERT);
1467 coreLocalReset(PD15, LPSC_C7_TIM7, LOC_RST_ASSERT);
1469 /* Disable all other modules */
1470 setPscState(PD0, LPSC_EMIF16_SPI, PSC_SWRSTDISABLE);
1471 setPscState(PD0, LPSC_TSIP, PSC_SWRSTDISABLE);
1472 setPscState(PD1, LPSC_DEBUG, PSC_SWRSTDISABLE);
1473 setPscState(PD1, LPSC_TETB_TRC, PSC_SWRSTDISABLE);
1474 setPscState(PD2, LPSC_SA, PSC_SWRSTDISABLE);
1475 setPscState(PD2, LPSC_SGMII, PSC_SWRSTDISABLE);
1476 setPscState(PD2, LPSC_PA, PSC_SWRSTDISABLE);
1477 //setPscState(PD3, LPSC_PCIE, PSC_SWRSTDISABLE);
1478 setPscState(PD4, LPSC_SRIO, PSC_SWRSTDISABLE);
1479 setPscState(PD5, LPSC_HYPER, PSC_SWRSTDISABLE);
1480 //setPscState(PD6, LPSC_RESERV, PSC_SWRSTDISABLE);
1481 setPscState(PD7, LPSC_MSMCRAM, PSC_SWRSTDISABLE);
1483 for (i = 0; i < 8; i++) {
1484 pushData(localResetCode, i, &bootEntryAddr);
1485 if (setBootAddrIpcgr(i, bootEntryAddr) == 0) {
1486 printk("Core %d is not ready !!! \n", i);
1487 }
1488 }
1490 /* Enable all other modules */
1491 setPscState(PD0, LPSC_EMIF16_SPI, PSC_ENABLE);
1492 setPscState(PD0, LPSC_TSIP, PSC_ENABLE);
1493 setPscState(PD1, LPSC_DEBUG, PSC_ENABLE);
1494 setPscState(PD1, LPSC_TETB_TRC, PSC_ENABLE);
1495 setPscState(PD2, LPSC_PA, PSC_ENABLE);
1496 setPscState(PD2, LPSC_SGMII, PSC_ENABLE);
1497 setPscState(PD2, LPSC_SA, PSC_ENABLE);
1498 //setPscState(PD3, LPSC_PCIE, PSC_ENABLE);
1499 setPscState(PD4, LPSC_SRIO, PSC_ENABLE);
1500 setPscState(PD5, LPSC_HYPER, PSC_ENABLE);
1501 //setPscState(PD6, LPSC_RESERV, PSC_ENABLE);
1502 setPscState(PD7, LPSC_MSMCRAM, PSC_ENABLE);
1504 /* Local out of reset of all cores */
1505 coreLocalReset(PD8, LPSC_C0_TIM0, LOC_RST_DEASSERT);
1506 coreLocalReset(PD9, LPSC_C1_TIM1, LOC_RST_DEASSERT);
1507 coreLocalReset(PD10, LPSC_C2_TIM2, LOC_RST_DEASSERT);
1508 coreLocalReset(PD11, LPSC_C3_TIM3, LOC_RST_DEASSERT);
1509 coreLocalReset(PD12, LPSC_C4_TIM4, LOC_RST_DEASSERT);
1510 coreLocalReset(PD13, LPSC_C5_TIM5, LOC_RST_DEASSERT);
1511 coreLocalReset(PD14, LPSC_C6_TIM6, LOC_RST_DEASSERT);
1512 coreLocalReset(PD15, LPSC_C7_TIM7, LOC_RST_DEASSERT);
1513 #endif
1514 }
1516 #endif
1517 /* ============================================================================
1518 * @func init_module
1519 *
1520 * @desc Initialize a loadable module
1521 *
1522 * @modif None.
1523 * ============================================================================
1524 */
1525 int init_module(void)
1526 {
1527 uint32_t i;
1528 uint32_t bootEntryAddr = 0; /* Store 32-bit boot entry address read from .h file */
1529 #if HELLO_WORLD_DEMO | EDMA_INTC_DEMO
1530 uint32_t buffer[BLOCK_TRANSFER_SIZE/4]; /* Store 32-bit DSP memory readback data */
1531 #endif
1533 #if EDMA_INTC_DEMO
1534 uint32_t diff;
1535 #endif
1537 printk ("Finding the device....\n") ;
1538 PCI_FindPciDevices();
1539 if (!PCIE_DEV) {
1540 printk ("No PCIE device found!!!\n") ;
1541 }
1543 if (PCIE_DEV != NULL) {
1545 printk("Reading the BAR areas....\n");
1546 PCI_readBAR();
1548 printk("Enabling the device....\n");
1549 /* Linux Function: Initialize device before it's used by a driver */
1550 pci_enable_device(PCIE_DEV);
1552 /* Linux Function: Associates the given data with the given pci_driver structure */
1553 pci_set_drvdata(PCIE_DEV, memVirt);
1555 PCI_setMaster();
1557 printk("Access PCIE application register ....\n");
1558 /* Pointing to the beginning of the application registers */
1559 ptrReg = (uint32_t *)regVirt;
1561 /* Configure IB_BAR0 to BAR0 for PCIE registers; Configure IB_BAR1 to BAR1 for LL2 for core 0
1562 Configure IB_BAR2 to BAR2 for MSMC; Configure IB_BAR3 to BAR3 for DDR */
1563 for (i = 0; i < 4; i++) {
1564 iowrite32(i, ptrReg + IB_BAR(i)/4);
1565 iowrite32(PCIE_DEV->resource[i].start, ptrReg + IB_START_LO(i)/4);
1566 iowrite32(0, ptrReg + IB_START_HI(i)/4);
1567 }
1568 iowrite32(PCIE_BASE_ADDRESS, ptrReg + IB_OFFSET(0)/4);
1569 iowrite32(LL2_START + (1 << 28), ptrReg + IB_OFFSET(1)/4);
1570 iowrite32(MSMC_START, ptrReg + IB_OFFSET(2)/4);
1571 iowrite32(DDR_START, ptrReg + IB_OFFSET(3)/4);
1573 printk("Registering the irq %d ...\n", irqNo);
1574 request_irq(irqNo, ISR_handler, IRQF_SHARED, "TI 667x PCIE", &dummy);
1575 HAL_PciEnableDspInterrupt();
1577 #if HELLO_WORLD_DEMO
1578 /* Load DDR init code into DSP */
1579 pushData(ddrInitCode, 0, &bootEntryAddr);
1581 /* Write boot entry address into MAGIC_ADDR */
1582 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1584 while (1) {
1585 readDSPMemory(0, MAGIC_ADDR, buffer, 4);
1586 if (buffer[0] == 0) break;
1587 for (i = 0; i < 1000; i++) i++;
1588 }
1590 /* Load "Hello World" demo into DSP */
1591 pushData(bootCode, 9, &bootEntryAddr);
1593 /* Write boot entry address into MAGIC_ADDR */
1594 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1595 #endif
1597 #if POST_DEMO
1598 /* Load POST demo code into DSP */
1599 pushData(post, 0, &bootEntryAddr);
1601 /* Write boot entry address into MAGIC_ADDR */
1602 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1603 #endif
1605 #if EDMA_INTC_DEMO
1607 printk("Allocating consistent memory ...\n");
1608 wDataVirt = (uint8_t*)dma_alloc_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, &wData, GFP_KERNEL);
1609 rDataVirt = (uint8_t*)dma_alloc_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, &rData, GFP_KERNEL);
1611 for (i = 0; i < DMA_TRANSFER_SIZE; i++) {
1612 wDataVirt[i] = i;
1613 rDataVirt[i] = 0;
1614 }
1616 /* Load Interrupt demo code into DSP */
1617 pushData(pcieInterrupt, 0, &bootEntryAddr);
1619 /* Write boot entry address into MAGIC_ADDR */
1620 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1622 while (1) {
1623 readDSPMemory(0, MAGIC_ADDR, buffer, 4);
1624 if (buffer[0] == 0) break;
1625 for (i = 0; i < 1000; i++) i++;
1626 }
1628 /* Wait 2 second for DDR init */
1629 mdelay(2000);
1631 printk ("Write DMA to DSP ...\n");
1632 do_gettimeofday(&test_time1);
1633 HAL_writeDMA (wData, DDR_START, DMA_TRANSFER_SIZE, 1); /* Move from GPP to DSP */
1634 do_gettimeofday(&test_time2);
1636 /* Note: From PCIE specification, legacy interrupts cannot be generated from RC and be passed downstream.
1637 The example below is just making use of the facility that RC can access EP side register to generate
1638 a generic interrupt on local (EP) side using one of the event inputs of Interrupt Controller (INTC).
1639 There is no real interrupt signal sent over the PCIe link */
1640 printk ("Generating interrupt to DSP ...\n");
1641 iowrite32(1, ptrReg + LEGACY_A_IRQ_STATUS_RAW/4);
1643 /* Waiting DSP ISR handler to process the interrupt from DSP and then generates an interrupt to host
1644 Waiting for host ISR handler to process the interrupt from DSP before program exits */
1645 mdelay(1000);
1647 /* For demo how to move inside DSP purpose only, you can directly move between GPP and DSP using flag = 1 */
1648 // HAL_writeDMA (0x80000000, 0x11800000, 0x10000, 0);
1649 // HAL_writeDMA (0x11800000, 0x0C000000, 0x10000, 0);
1651 diff = (test_time2.tv_sec - test_time1.tv_sec)*1000000 + (test_time2.tv_usec - test_time1.tv_usec);
1652 printk("DMA write throughput is: %d.%02d MB/s\n", DMA_TRANSFER_SIZE/(1024*1024)*1000*1000/diff,
1653 ((DMA_TRANSFER_SIZE/(1024*1024)*1000*1000)%diff)*100/diff);
1655 diff = (test_time4.tv_sec - test_time3.tv_sec)*1000000 + (test_time4.tv_usec - test_time3.tv_usec);
1656 printk("DMA read throughput is: %d.%02d MB/s\n", DMA_TRANSFER_SIZE/(1024*1024)*1000*1000/diff,
1657 ((DMA_TRANSFER_SIZE/(1024*1024)*1000*1000)%diff)*100/diff);
1659 printk("Freeing consistent memory ...\n");
1660 dma_free_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, wDataVirt, wData);
1661 dma_free_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, rDataVirt, rData);
1662 #endif
1664 #if LOCAL_RESET
1665 mdelay(10000);
1666 dspLocalReset();
1667 #endif
1668 }
1669 else {
1670 printk("No PCIE device found!!!\n");
1671 }
1672 return 0 ;
1673 }
1675 /* ============================================================================
1676 * @func cleanup_module
1677 *
1678 * @desc Unregister a loadable module
1679 *
1680 * @modif None.
1681 * ============================================================================
1682 */
1684 void cleanup_module(void)
1685 {
1687 if (PCIE_DEV != NULL) {
1688 HAL_PciDisableDspInterrupt();
1689 /* ---------------------------------------------------------------------
1690 * Unmap baseRegs region & release the reg region.
1691 * ---------------------------------------------------------------------
1692 */
1693 iounmap(regVirt);
1694 if (pci_resource_flags(PCIE_DEV, 0) & IORESOURCE_MEM) {
1695 /* Map the memory region. */
1696 release_mem_region(regBase, regLen);
1697 }
1698 else {
1699 /* Map the memory region. */
1700 release_region(regBase, regLen);
1701 }
1703 /* ---------------------------------------------------------------------
1704 * Unmap LL2 region & release the reg region.
1705 * ---------------------------------------------------------------------
1706 */
1707 iounmap(memVirt);
1708 if (pci_resource_flags(PCIE_DEV, 1) & IORESOURCE_MEM) {
1709 /* Map the memory region. */
1710 release_mem_region(memBase, memLen);
1711 }
1712 else {
1713 /* Map the memory region. */
1714 release_region(memBase, memLen);
1715 }
1717 /* ---------------------------------------------------------------------
1718 * Unmap MSMC region & release the reg region.
1719 * ---------------------------------------------------------------------
1720 */
1721 iounmap(msmcVirt);
1722 if (pci_resource_flags(PCIE_DEV, 2) & IORESOURCE_MEM) {
1723 /* Map the memory region. */
1724 release_mem_region(msmcBase, msmcLen);
1725 }
1726 else {
1727 /* Map the memory region. */
1728 release_region(msmcBase, msmcLen);
1729 }
1731 /* ---------------------------------------------------------------------
1732 * Unmap DDR region & release the reg region.
1733 * ---------------------------------------------------------------------
1734 */
1735 iounmap(ddrVirt);
1736 if (pci_resource_flags(PCIE_DEV, 3) & IORESOURCE_MEM) {
1737 /* Map the memory region. */
1738 release_mem_region(ddrBase, ddrLen);
1739 }
1740 else {
1741 /* Map the memory region. */
1742 release_region(ddrBase, ddrLen);
1743 }
1745 free_irq(irqNo, &dummy);
1746 }
1747 }