9be0aeab63c34d50f7947c163233a4790ab8a892
[keystone-rtos/mcsdk-tools.git] / boot_loader / examples / pcie / linux_host_loader / pciedemo.c
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)
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         }
412 /* ============================================================================
413  *  @func   PCI_readBAR
414  *
415  *  @desc   This function reads config.
416  *
417  *  @modif  None.
418  *  ============================================================================
419  */
420 void PCI_readBAR(void)
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];
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)
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);
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)
565         uint32_t *pReg = (uint32_t *)regVirt;
566         return ioread32(pReg + EP_IRQ_STATUS/4);
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)
579         uint32_t *pReg = (uint32_t *)regVirt;
580         iowrite32(1, pReg+EP_IRQ_CLR/4);
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)
593         uint32_t *pReg = (uint32_t *)regVirt;
594         iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_SET/4);
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)
607         uint32_t *pReg = (uint32_t *)regVirt;
608         iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_CLR/4);
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)
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); 
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)
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);  
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) 
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;
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)
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);
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)
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         }
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) 
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;
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) 
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;
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)
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);
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) 
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);  
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)
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);  
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)  
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;
1379 /* ============================================================================
1380  *  @func   dspLocalReset
1381  *
1382  *  @desc   Perform DSP cores and periphrals reset
1383  *
1384  *  @modif  None.
1385  *  ============================================================================
1386  */
1387 void dspLocalReset(void) 
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
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)
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 ;
1675 /* ============================================================================
1676  *  @func   cleanup_module
1677  *
1678  *  @desc   Unregister a loadable module 
1679  *
1680  *  @modif  None.
1681  *  ============================================================================
1682  */
1684 void cleanup_module(void)
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         }