Merge pull request #2 in PROCESSOR-SDK/mcsdk-tools from PRSDK-2194 to master
[keystone-rtos/mcsdk-tools.git] / boot_loader / examples / pcie / linux_host_loader / pciedemo.c
1 /******************************************************************************
2  * Copyright (c) 2011-2012 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  *    - 1.5:  Support 6657 boot
29  *    - 1.6:  Support TCI6636K2H boot
30  ***************************************************************************************/
32 #include <linux/module.h>
33 #include <linux/types.h>
34 #include <linux/kernel.h>
35 #include <linux/pci.h>
36 #include <linux/delay.h>
37 #include <linux/fs.h>
38 #include <linux/init.h>
39 #include <linux/ioport.h>
40 #include <linux/interrupt.h>
41 #include <asm/uaccess.h>
42 #include <asm/dma-mapping.h>
43 #include <linux/time.h>
45 MODULE_LICENSE("GPL v2");
47 /* Must select the endianess */
48 #define BIG_ENDIAN          0
50 /* Must select which demo to run */
51 #define HELLO_WORLD_DEMO    1
52 #define POST_DEMO           0
53 #define EDMA_INTC_DEMO      0
54 #define LOCAL_RESET         0
56 /* Must select a platform */
57 #define EVMC6678L           1
58 #define EVMC6670L           0
59 #define EVMC6657L           0
60 #define EVMK2H              0
62 #if BIG_ENDIAN
63 #define myIoread32  ioread32be
64 #define myIowrite32 iowrite32be
65 #else
66 #define myIoread32  ioread32
67 #define myIowrite32 iowrite32
68 #endif
70 #if EVMC6678L
71 #define MAGIC_ADDR          0x0087FFFC
72 #endif
74 #if EVMC6670L
75 #define MAGIC_ADDR          0x008FFFFC
76 #endif
78 #if EVMC6657L
79 #define MAGIC_ADDR          0x008FFFFC
80 #endif
82 #if EVMK2H
83 #define MAGIC_ADDR          0x008FFFFC
84 #endif
86 /* Include header array */
87 #if HELLO_WORLD_DEMO
89 #if EVMC6678L
90 #include "pcieDdrInit_6678.h"     /* DDR init */
91 #include "pcieBootCode_6678.h"    /* "Hello world" boot example */
92 #endif
94 #if EVMC6670L
95 #include "pcieDdrInit_6670.h"     /* DDR init */
96 #include "pcieBootCode_6670.h"    /* "Hello world" boot example */
97 #endif
99 #if EVMC6657L
100 #include "pcieDdrInit_6657.h"     /* DDR init */
101 #include "pcieBootCode_6657.h"    /* "Hello world" boot example */
102 #endif
104 #if EVMK2H
105 #include "pcieDdrInit_k2h.h"      /* DDR init */
106 #include "pcieBootCode_k2h.h"     /* "Hello world" boot example */
107 #endif
109 #endif
111 #if POST_DEMO
113 #if EVMC6678L
114 #include "post_6678.h"            /* POST boot example */
115 #endif
117 #if EVMC6670L
118 #include "post_6670.h"            /* POST boot example */
119 #endif
121 #if EVMC6657L
122 #include "post_6657.h"            /* POST boot example */
123 #endif
125 #if EVMK2H
126 #include "post_k2h.h"             /* POST boot example */
127 #endif
129 #endif
131 #if EDMA_INTC_DEMO
133 #if EVMC6678L
134 #include "pcieInterrupt_6678.h"   /* EDMA-Interrupt boot example */
135 #endif
137 #if EVMC6670L
138 #include "pcieInterrupt_6670.h"   /* EDMA-Interrupt boot example */
139 #endif
141 #endif
143 #if LOCAL_RESET
145 #if EVMC6678L
146 #include "pcieLocalReset_6678.h"
147 #endif
149 #if EVMC6670L
150 #include "pcieLocalReset_6670.h"
151 #endif
153 #endif
155 /* PCIE registers */
156 #define PCIE_BASE_ADDRESS            0x21800000
157 #define OB_SIZE                      0x30
158 #define PRIORITY                     0x3C
159 #define EP_IRQ_CLR                   0x68
160 #define EP_IRQ_STATUS                0x6C
161 #define LEGACY_A_IRQ_STATUS_RAW      0x180
162 #define LEGACY_A_IRQ_ENABLE_SET      0x188
163 #define LEGACY_A_IRQ_ENABLE_CLR      0x18C
164 #define OB_OFFSET_INDEX(n)           (0x200 + (8 * (n)))
165 #define OB_OFFSET_HI(n)              (0x204 + (8 * (n)))
166 #define IB_BAR(n)                    (0x300 + (0x10 * (n)))
167 #define IB_START_LO(n)               (0x304 + (0x10 * (n)))
168 #define IB_START_HI(n)               (0x308 + (0x10 * (n)))
169 #define IB_OFFSET(n)                 (0x30C + (0x10 * (n)))
171 #define PCIE_TI_VENDOR               0x104C
172 #define PCIE_TI_DEVICE               0xB005
174 /* PSC registers */
175 #define PSC_BASE_ADDRESS             0x02350000
176 #define PTCMD                        0x120
177 #define PTSTAT                       0x128
178 #define PDSTAT(n)                    (0x200 + (4 * (n)))
179 #define PDCTL(n)                     (0x300 + (4 * (n)))
180 #define MDSTAT(n)                    (0x800 + (4 * (n)))
181 #define MDCTL(n)                     (0xA00 + (4 * (n)))
183 /* EDMA registers */
184 #define EDMA_TPCC0_BASE_ADDRESS      0x02700000
185 #define DMAQNUM0                     0x0240
186 #define ESR                          0x1010
187 #define EESR                         0x1030
188 #define IESR                         0x1060
189 #define IPR                          0x1068
190 #define ICR                          0x1070
191 #define PARAM_0_OPT                  0x4000
192 #define PARAM_0_SRC                  0x4004
193 #define PARAM_0_A_B_CNT              0x4008
194 #define PARAM_0_DST                  0x400C
195 #define PARAM_0_SRC_DST_BIDX         0x4010
196 #define PARAM_0_LINK_BCNTRLD         0x4014
197 #define PARAM_0_SRC_DST_CIDX         0x4018
198 #define PARAM_0_CCNT                 0x401C
200 /* Chip level registers */
201 #define CHIP_LEVEL_BASE_ADDRESS      0x02620000
202 #define KICK0                        0x38
203 #define KICK1                        0x3C
204 #define KICK0_UNLOCK                 0x83E70B13
205 #define KICK1_UNLOCK                 0x95A4F1E0
206 #define KICK_LOCK                    0x0
207 #define DSP_BOOT_ADDR(n)             (0x040 + (4 * (n)))
208 #define IPCGR(n)                     (0x240 + (4 * (n)))
211 #define LL2_START                    0x00800000
212 #define MSMC_START                   0x0C000000  /* Shared L2 */
213 #define DDR_START                    0x80000000
214 #define PCIE_DATA                    0x60000000
216 /* Block size in bytes when r/w data between GPP and DSP via DSP CPU */
217 #define BLOCK_TRANSFER_SIZE          0x100
219 /* Data size in bytes when r/w data bewteen GPP and DSP via EDMA:
220    GPP----PCIE link----PCIE data space----EDMA----DSP device memory (L2, DDR, ...) */
221 #define DMA_TRANSFER_SIZE            0x400000   /* 4MB */
223 /* Payload size in bytes over PCIE link. PCIe module supports
224    outbound payload size of 128 bytes and inbound payload size of 256 bytes */
225 #define PCIE_TRANSFER_SIZE           0x80
227 /* For 1MB outbound translation window size */
228 #define PCIE_ADLEN_1MB               0x00100000
229 #define PCIE_1MB_BITMASK             0xFFF00000
231 #define PSC_SWRSTDISABLE             0x0
232 #define PSC_ENABLE                   0x3
234 #define LOC_RST_ASSERT               0x0
235 #define LOC_RST_DEASSERT             0x1
237 /* Power domains definitions */
238 #define PD0         0     // Power Domain-0
239 #define PD1         1     // Power Domain-1
240 #define PD2         2     // Power Domain-2
241 #define PD3         3     // Power Domain-3
242 #define PD4         4     // Power Domain-4
243 #define PD5         5     // Power Domain-5
244 #define PD6         6     // Power Domain-6
245 #define PD7         7     // Power Domain-7
246 #define PD8         8     // Power Domain-8
247 #define PD9         9     // Power Domain-9
248 #define PD10        10    // Power Domain-10
249 #define PD11        11    // Power Domain-11
250 #define PD12        12    // Power Domain-12
251 #define PD13        13    // Power Domain-13
252 #define PD14        14    // Power Domain-14
253 #define PD15        15    // Power Domain-15
254 #define PD16        16    // Power Domain-16
255 #define PD17        17    // Power Domain-17
257 #if EVMC6670L
258 /* Modules on power domain 0 */
259 #define LPSC_TCP3E     3
260 #define LPSC_VCP2A     4
262 /* Modules on power domain 1 */
263 #define LPSC_DEBUG     5
264 #define LPSC_TETB      6
266 /* Modules on power domain 2 */
267 #define LPSC_PA        7
268 #define LPSC_SGMII     8
269 #define LPSC_SA        9
271 /* Modules on power domain 3 */
272 #define LPSC_PCIE      10
274 /* Modules on power domain 4 */
275 #define LPSC_SRIO      11
277 /* Modules on power domain 5 */
278 #define LPSC_HYPER     12
280 /* Modules on power domain 6 */
281 #define LPSC_RESERV    13
283 /* Modules on power domain 7 */
284 #define LPSC_MSMCRAM   14
286 /* Modules on power domain 8 */
287 #define LPSC_RACA_RACB 15
288 #define LPSC_TAC       16
290 /* Modules on power domain 9 */
291 #define LPSC_FFTCA_FFTCB 17
293 /* Modules on power domain 10 */
294 #define LPSC_AIF2      18
296 /* Modules on power domain 11 */
297 #define LPSC_TCP3DA    19
299 /* Modules on power domain 12 */
300 #define LPSC_VCP2B     20
301 #define LPSC_VCP2C     21
302 #define LPSC_VCP2D     22
304 /* Modules on power domain 13 */
305 #define LPSC_C0_TIM0   23
307 /* Modules on power domain 14 */
308 #define LPSC_C1_TIM1   24
309 #define LPSC_C1_RSA    25
311 /* Modules on power domain 15 */
312 #define LPSC_C2_TIM2   26
313 #define LPSC_C2_RSA    27
315 /* Modules on power domain 16 */
316 #define LPSC_C3_TIM3   28
318 /* Modules on power domain 17 */
319 #define LPSC_TCP3dB    29
321 #endif
323 #if EVMC6678L
324 /* Modules on power domain 0 */
325 #define LPSC_EMIF16_SPI  3
326 #define LPSC_TSIP        4
328 /* Modules on power domain 1 */
329 #define LPSC_DEBUG       5
330 #define LPSC_TETB_TRC    6
332 /* Modules on power domain 2 */
333 #define LPSC_PA          7
334 #define LPSC_SGMII       8
335 #define LPSC_SA          9
337 /* Modules on power domain 3 */
338 #define LPSC_PCIE        10
340 /* Modules on power domain 4 */
341 #define LPSC_SRIO        11
343 /* Modules on power domain 5 */
344 #define LPSC_HYPER       12
346 /* Modules on power domain 6 */
347 #define LPSC_RESERV      13
349 /* Modules on power domain 7 */
350 #define LPSC_MSMCRAM     14
352 /* Modules on power domain 8 */
353 #define LPSC_C0_TIM0     15
355 /* Modules on power domain 9 */
356 #define LPSC_C1_TIM1     16
358 /* Modules on power domain 10 */
359 #define LPSC_C2_TIM2     17
361 /* Modules on power domain 11 */
362 #define LPSC_C3_TIM3     18
364 /* Modules on power domain 12 */
365 #define LPSC_C4_TIM4     19
367 /* Modules on power domain 13 */
368 #define LPSC_C5_TIM5     20
370 /* Modules on power domain 14 */
371 #define LPSC_C6_TIM6     21
373 /* Modules on power domain 15 */
374 #define LPSC_C7_TIM7     22
376 #endif
378 /*
379 reg:  PCIE application registers
380 mem:  Local L2
381 msmc: Shared L2 memory
382 ddr:  DDR3
383  */
385 uint8_t *wDataVirt, *rDataVirt;          /* Virtue address for CPU */
386 dma_addr_t wData, rData;                 /* Physical PCIE bus address */
389 /***********************************************
390  * uncomment following line on very old kernels:
391  * typedef unsigned long resource_size_t;
392  **********************************************/
393 resource_size_t regBase = 0;
394 resource_size_t memBase = 0;
395 resource_size_t msmcBase = 0;
396 resource_size_t ddrBase = 0;
398 uint32_t *regVirt = NULL;
399 uint32_t *memVirt = NULL;
400 uint32_t *msmcVirt = NULL;
401 uint32_t *ddrVirt = NULL;
403 resource_size_t memLen = 0;
404 resource_size_t regLen = 0;
405 resource_size_t msmcLen = 0;
406 resource_size_t ddrLen = 0;
408 uint32_t *ptrReg = 0;
409 int32_t  irqNo;
410 uint32_t dummy;
411 struct pci_dev *PCIE_DEV = NULL;
413 struct timeval test_time1;
414 struct timeval test_time2;
415 struct timeval test_time3;
416 struct timeval test_time4;
418 /* ============================================================================
419  *  @func   PCI_FindPciDevices
420  *
421  *  @desc   This function locates 6670/6678/6657/K2H PCIE cards on system.
422  *
423  *  @modif  None.
424  *  ============================================================================
425  */
426 void PCI_FindPciDevices(void)
428         struct pci_dev *dev = NULL;
430         while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
431         {
432                 if ((dev->vendor == PCIE_TI_VENDOR) && (dev->device == PCIE_TI_DEVICE)) {
433                         printk("Found TI device\n");
434                         irqNo = dev->irq;
435                         PCIE_DEV = dev;
436                         printk("TI device: vendor=0x%04x, dev=0x%04x, irq=0x%08x\n", dev->vendor, dev->device, dev->irq);
437                         break;
438                 }
439         }
442 /* ============================================================================
443  *  @func   PCI_readBAR
444  *
445  *  @desc   This function reads config.
446  *
447  *  @modif  None.
448  *  ============================================================================
449  */
450 void PCI_readBAR(void)
452         resource_size_t  barStart[4];
453         resource_size_t  barLen[4];
454         resource_size_t  barFlags[4];
456         barStart [0] = pci_resource_start (PCIE_DEV, 0);   /* BAR0 4K for PCIE application registers */
457         barLen   [0] = pci_resource_len   (PCIE_DEV, 0);
458         barFlags [0] = pci_resource_flags (PCIE_DEV, 0);
459         barStart [1] = pci_resource_start (PCIE_DEV, 1);   /* BAR1 512K/1024K for 6678/6670 Local L2 */
460         barLen   [1] = pci_resource_len   (PCIE_DEV, 1);
461         barFlags [1] = pci_resource_flags (PCIE_DEV, 1);
462         barStart [2] = pci_resource_start (PCIE_DEV, 2);   /* BAR2 4M/2M for 6678/6670 Shared L2 */
463         barLen   [2] = pci_resource_len   (PCIE_DEV, 2);
464         barFlags [2] = pci_resource_flags (PCIE_DEV, 2);
465         barStart [3] = pci_resource_start (PCIE_DEV, 3);   /* BAR3 16M for DDR3 */
466         barLen   [3] = pci_resource_len   (PCIE_DEV, 3);
467         barFlags [3] = pci_resource_flags (PCIE_DEV, 3);
469         /* ---------------------------------------------------------------------
470          * Map the REG memory region
471          * ---------------------------------------------------------------------
472          */
473         if (barFlags[0] & IORESOURCE_MEM) {
474                 regBase = barStart[0];
475                 /* Map the memory region. */
476                 request_mem_region(regBase, barLen[0], "DSPLINK");
477         }
478         else {
479                 /* Map the memory region. */
480                 request_region(regBase, barLen[0], "DSPLINK");
481         }
483         if (regBase > 0) {
484                 regVirt = ioremap(barStart[0], barLen[0]);
485         }
487         /* ---------------------------------------------------------------------
488          * Map the LL2RAM memory region
489          * ---------------------------------------------------------------------
490          */
491         if (barFlags[1] & IORESOURCE_MEM) {
492                 memBase = barStart[1];
493                 /* Map the memory region. */
494                 request_mem_region(memBase, barLen[1], "DSPLINK");
495         }
496         else {
497                 /* Map the memory region. */
498                 request_region(memBase, barLen[1], "DSPLINK");
499         }
501         if (memBase > 0) {
502                 memVirt = ioremap(barStart[1], barLen[1]);
503         }
505         /* ---------------------------------------------------------------------
506          * Map the MSMC memory region
507          * ---------------------------------------------------------------------
508          */
509         if (barFlags[2] & IORESOURCE_MEM) {
510                 msmcBase = barStart[2];
511                 /* Map the memory region. */
512                 request_mem_region(msmcBase, barLen[2], "DSPLINK");
513         }
514         else {
515                 /* Map the memory region. */
516                 request_region(msmcBase, barLen[2], "DSPLINK");
517         }
519         if (msmcBase > 0) {
520                 msmcVirt = ioremap(barStart[2], barLen[2]);
521         }
523         /* ---------------------------------------------------------------------
524          * Map the DDR memory region
525          * ---------------------------------------------------------------------
526          */
527         if (barFlags[3] & IORESOURCE_MEM) {
528                 ddrBase = barStart[3];
529                 /* Map the memory region. */
530                 request_mem_region(ddrBase, barLen[3], "DSPLINK");
531         }
532         else {
533                 /* Map the memory region. */
534                 request_region(ddrBase, barLen[3], "DSPLINK");
535         }
537         if (ddrBase > 0) {
538                 ddrVirt = ioremap(barStart[3], barLen[3]);
539         }
541         regLen  = barLen[0];
542         memLen  = barLen[1];
543         msmcLen = barLen[2];
544         ddrLen  = barLen[3];
548 /* =============================================================================
549  *  @func   PCI_setMaster
550  *
551  *  @desc   This function makes the given device to be master.
552  *
553  *  @modif  None.
554  *  ============================================================================
555  */
556 void PCI_setMaster(void)
558         int32_t  retVal;
559         uint16_t cmdVal;
560         struct pci_dev *dev;
562         dev = PCIE_DEV;
564         /* set the DMA mask */
565         if (pci_set_dma_mask(dev, 0xfffffff0ULL)) {
566         }
568         /* set the desired PCI dev to be master, this internally sets the latency timer */
569         pci_set_master(dev);
570         pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
572         /* Add support memory write invalidate */
573         retVal = pci_set_mwi(dev);
575         pci_read_config_word(dev, PCI_COMMAND, (u16 *)&cmdVal);
576         /* and set the master bit in command register. */
577         cmdVal |= PCI_COMMAND_MEMORY
578                 | PCI_COMMAND_MASTER
579                 | PCI_COMMAND_SERR;
580         /* and clear the interrupt disable bit in command register. */
581         cmdVal &= ~PCI_COMMAND_INTX_DISABLE;
582         pci_write_config_word(dev, PCI_COMMAND, cmdVal);
585 /* =============================================================================
586  *  @func   HAL_CheckPciInterrupt
587  *
588  *  @desc   This function check whether interrupt is generated by C667x or not.
589  *
590  *  @modif  None.
591  *  ============================================================================
592  */
593 bool HAL_CheckPciInterrupt(void)
595         uint32_t *pReg = (uint32_t *)regVirt;
596         return ioread32(pReg + EP_IRQ_STATUS/4);
599 /** ============================================================================
600  *  @func   HAL_PciClearDspInterrupt
601  *
602  *  @desc   Clear pending interrupt from DSP to Host.
603  *
604  *  @modif  None.
605  *  ============================================================================
606  */
607 void HAL_PciClearDspInterrupt(void)
609         uint32_t *pReg = (uint32_t *)regVirt;
610         iowrite32(1, pReg+EP_IRQ_CLR/4);
613 /** ============================================================================
614  *  @func   HAL_PciEnableDspInterrupt
615  *
616  *  @desc   Allow the DSP to generate interrupts to the Host.
617  *
618  *  @modif  None.
619  *  ============================================================================
620  */
621 void HAL_PciEnableDspInterrupt(void)
623         uint32_t *pReg = (uint32_t *)regVirt;
624         iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_SET/4);
627 /** ============================================================================
628  *  @func   HAL_PciDisableDspInterrupt
629  *
630  *  @desc   Disable the DSP to generate interrupts to the Host.
631  *
632  *  @modif  None.
633  *  ============================================================================
634  */
635 void HAL_PciDisableDspInterrupt(void)
637         uint32_t *pReg = (uint32_t *)regVirt;
638         iowrite32(1, pReg+LEGACY_A_IRQ_ENABLE_CLR/4);
642 /* ============================================================================
643  *  @func   HAL_readDMA
644  *
645  *  @desc   Move DMAs contents from DSP memory to GPP Memory. For DSP this is
646  *          outbound write.
647  *  flag:   0: Move data inside DSP; 1: Move data between GPP and DSP
648  *
649  *  @modif  None.
650  *  ============================================================================
651  */
652 void HAL_readDMA(uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag)
654         uint32_t *pReg, tmp, pageBase, i, tSize;
656         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
658         /* Move data between GPP and DSP, need to program PCIE OB registers */
659         if (flag) {
660                 iowrite32(0x0, pReg + OB_SIZE/4); /* 1MB outbound translation size */
662                 if (size <= PCIE_ADLEN_1MB) {
663                         pageBase = dstAddr & PCIE_1MB_BITMASK;
664                         iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(0)/4);
665                         iowrite32(0x0, pReg + OB_OFFSET_HI(0)/4);
666                 }
667                 else {
668                         for (tmp = size, i = 0; tmp > 0; tmp -= PCIE_ADLEN_1MB, i++) {
669                                 pageBase = (dstAddr + (PCIE_ADLEN_1MB * i)) & PCIE_1MB_BITMASK;
670                                 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(i)/4);
671                                 iowrite32(0x0, pReg + OB_OFFSET_HI(i)/4);
672                         }
673                 }
674         }
676         /* Temporarily re-map IB region 3 from DDR memory to EDMA registers */
677         iowrite32(EDMA_TPCC0_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
679         pReg = (uint32_t*)ddrVirt;   /* Now it points to the start of EDMA_TPCC0_BASE_ADDRESS */
681         while (true) {
682                 /* Use TC0 for DBS = 128 bytes */
683                 myIowrite32(0x0, pReg + DMAQNUM0/4);
685                 /* Set the interrupt enable for 1st Channel (IER). */
686                 myIowrite32(0x1, pReg + IESR/4);
688                 /* Clear any pending interrupt (IPR). */
689                 myIowrite32(0x1, pReg + ICR/4);
691                 /* Populate the Param entry. */
692                 myIowrite32(0x00100004, pReg + PARAM_0_OPT/4);    /* Enable SYNCDIM and TCINTEN, TCC = 0 */
694                 if (flag == 1) {
695                         /* Calculate the DSP PCI address for the PC address */
696                         tmp = PCIE_DATA + (dstAddr & ~PCIE_1MB_BITMASK);
697                         myIowrite32(tmp, pReg + PARAM_0_DST/4);
698                 } else {
699                         myIowrite32(dstAddr, pReg + PARAM_0_DST/4);
700                 }
702                 /* Calculate the A & B count */
703                 if (size > PCIE_TRANSFER_SIZE)  {
704                         tmp = size/PCIE_TRANSFER_SIZE;
705                         tSize = tmp*PCIE_TRANSFER_SIZE;
706                         size -= (tmp*PCIE_TRANSFER_SIZE);
707                         tmp <<= 16;
708                         tmp |= PCIE_TRANSFER_SIZE;
709                 }
710                 else {
711                         tmp = 0x10000|size;
712                         tSize = size;
713                         size = 0;
714                 }
716                 myIowrite32(tmp, pReg + PARAM_0_A_B_CNT/4);
717                 myIowrite32(srcAddr, pReg + PARAM_0_SRC/4);
719                 myIowrite32(((PCIE_TRANSFER_SIZE<<16)|PCIE_TRANSFER_SIZE), pReg + PARAM_0_SRC_DST_BIDX/4);
720                 myIowrite32(0xFFFF, pReg + PARAM_0_LINK_BCNTRLD/4);
721                 myIowrite32(0x0, pReg + PARAM_0_SRC_DST_CIDX/4);
723                 /* C Count is set to 1 since mostly size will not be more than 1.75GB */
724                 myIowrite32(0x1, pReg + PARAM_0_CCNT/4);
726                 /* Set the Event Enable Set Register. */
727                 myIowrite32(0x1, pReg + EESR/4);
729                 /* Set the event set register. */
730                 myIowrite32(0x1, pReg + ESR/4);
732                 /* wait for current DMA to finish. */
733                 while (true) {
734                         /* check in steps of 10 usec. */
735                         udelay(10);
736                         tmp = myIoread32(pReg + IPR/4);
737                         if ((tmp & 0x1) == 1) {
738                                 break;
739                         }
740                 }
742                 if (size != 0) {
743                         srcAddr += tSize;
744                         dstAddr += tSize;
745                 } else {
746                         break;
747                 }
748         }
750         /* Clear any pending interrupt. */
751         myIowrite32(1, pReg + ICR/4);
753         /* Restore pointer */
754         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
755         iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
758 /* ============================================================================
759  *  @func   HAL_writeDMA
760  *
761  *  @desc   Move DMAs contents from GPP memory to DSP Memory. For DSP this is
762  *          outbound read.
763  *  flag:   0: Move data inside DSP; 1: Move data between GPP and DSP
764  *
765  *  @modif  None.
766  *  ============================================================================
767  */
768 void HAL_writeDMA(uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag)
770         uint32_t *pReg, tmp, pageBase, i, tSize;
772         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
774         /* Move data between GPP and DSP, need to program PCIE OB registers */
775         if (flag) {
776                 iowrite32(0x0, pReg + OB_SIZE/4); /* 1MB outbound translation size */
778                 if (size <= PCIE_ADLEN_1MB) {
779                         pageBase = srcAddr & PCIE_1MB_BITMASK;
780                         iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(0)/4);
781                         iowrite32(0x0, pReg + OB_OFFSET_HI(0)/4);
782                 }
783                 else {
784                         for (tmp = size, i = 0; tmp > 0; tmp -= PCIE_ADLEN_1MB, i++) {
785                                 pageBase = (srcAddr + (PCIE_ADLEN_1MB * i)) & PCIE_1MB_BITMASK;
786                                 iowrite32(pageBase|0x1, pReg + OB_OFFSET_INDEX(i)/4);
787                                 iowrite32(0x0, pReg + OB_OFFSET_HI(i)/4);
788                         }
789                 }
790         }
792         /* Temporarily re-map IB region 3 from DDR memory to EDMA registers */
793         iowrite32(EDMA_TPCC0_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
795         pReg = (uint32_t*)ddrVirt;   /* Now it points to the start of EDMA_TPCC0_BASE_ADDRESS */
797         while (true) {
798                 /* Use TC0 for DBS = 128 bytes */
799                 myIowrite32(0x0, pReg + DMAQNUM0/4);
801                 /* Set the interrupt enable for 1st Channel (IER). */
802                 myIowrite32(0x1, pReg + IESR/4);
804                 /* Clear any pending interrupt (IPR). */
805                 myIowrite32(0x1, pReg + ICR/4);
807                 /* Populate the Param entry. */
808                 myIowrite32(0x00100004, pReg + PARAM_0_OPT/4);    /* Enable SYNCDIM and TCINTEN, TCC = 0 */
810                 if (flag == 1) {
811                         /* Calculate the DSP PCI address for the PC address */
812                         tmp = PCIE_DATA + (srcAddr & ~PCIE_1MB_BITMASK);
813                         myIowrite32(tmp, pReg + PARAM_0_SRC/4);
814                 } else {
815                         myIowrite32(srcAddr, pReg + PARAM_0_SRC/4);
816                 }
818                 /* Calculate the A & B count */
819                 if (size > PCIE_TRANSFER_SIZE)  {
820                         tmp = size/PCIE_TRANSFER_SIZE;
821                         tSize = tmp*PCIE_TRANSFER_SIZE;
822                         size -= (tmp*PCIE_TRANSFER_SIZE);
823                         tmp <<= 16;
824                         tmp |= PCIE_TRANSFER_SIZE;
825                 }
826                 else {
827                         tmp = 0x10000|size;
828                         tSize = size;
829                         size = 0;
830                 }
832                 myIowrite32(tmp, pReg + PARAM_0_A_B_CNT/4);
833                 myIowrite32(dstAddr, pReg + PARAM_0_DST/4);
835                 myIowrite32(((PCIE_TRANSFER_SIZE<<16)|PCIE_TRANSFER_SIZE), pReg + PARAM_0_SRC_DST_BIDX/4);
836                 myIowrite32(0xFFFF, pReg + PARAM_0_LINK_BCNTRLD/4);
837                 myIowrite32(0x0, pReg + PARAM_0_SRC_DST_CIDX/4);
839                 /* C Count is set to 1 since mostly size will not be more than 1.75GB */
840                 myIowrite32(0x1, pReg + PARAM_0_CCNT/4);
842                 /* Set the Event Enable Set Register. */
843                 myIowrite32(0x1, pReg + EESR/4);
845                 /* Set the event set register. */
846                 myIowrite32(0x1, pReg + ESR/4);
848                 /* wait for current DMA to finish. */
849                 while (true) {
850                         /* check in steps of 10 usec. */
851                         udelay(10);
852                         tmp = myIoread32(pReg + IPR/4);
853                         if ((tmp & 0x1) == 1) {
854                                 break;
855                         }
856                 }
858                 if (size != 0) {
859                         srcAddr += tSize;
860                         dstAddr += tSize;
861                 } else {
862                         break;
863                 }
864         }
866         /* Clear any pending interrupt. */
867         myIowrite32(1, pReg + ICR/4);
869         /* Restore pointer */
870         pReg = (uint32_t *)regVirt;     //Point to PCIE application registers
871         iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
874 /** ============================================================================
875  *  @func   ISR_handler
876  *
877  *  @desc   ISR.
878  *
879  *  @modif  None.
880  *  ============================================================================
881  */
882 static irqreturn_t ISR_handler(int irq, void *arg)
884         uint32_t i, dma_failure_flag = 0, counter = 0;
885         uint32_t status = HAL_CheckPciInterrupt();
887         if (status == 1) {
888                 printk("Interrupt %d received from DSP\n", irq);
889                 printk("Read DMA from DSP ...\n");
890                 do_gettimeofday(&test_time3);
891                 HAL_readDMA(DDR_START, rData, DMA_TRANSFER_SIZE, 1);     /* Move from DSP to GPP */
892                 do_gettimeofday(&test_time4);
894                 for (i = 0; i < DMA_TRANSFER_SIZE; i++) {
895                         if ((~(rDataVirt[i])&0xFF) != wDataVirt[i]) {
896                                 dma_failure_flag = 1;
897                                 counter++;
898                         }
899                 }
901                 if (dma_failure_flag)
902                         printk("DMA test failed with %d locations !\n", counter);
903                 else
904                         printk("DMA test passed!\n");
906                 HAL_PciClearDspInterrupt();
907                 return IRQ_HANDLED;
908         }
909         return IRQ_NONE;
912 /* ============================================================================
913  *  @func   byteto32bits
914  *
915  *  @desc   Convert 4 bytes to 32 bits long word
916  *
917  *  @modif  None.
918  *  ============================================================================
919  */
920 uint32_t byteTo32bits(uint8_t *pDspCode)
922         uint32_t i, temp;
924         temp = *pDspCode++;
925         for(i = 0; i < 3;i++) {
926                 temp <<= 8;
927                 temp |= *pDspCode++;
928         }
929         return(temp);
932 /* ============================================================================
933  *  @func   swap4bytes
934  *
935  *  @desc   Endian swap: 0xA0B1C2D3 to 0xD3C2B1A0
936  *
937  *  @modif  None.
938  *  ============================================================================
939  */
940 void swap4bytes(uint32_t *pDspCode, uint32_t size)
942         uint32_t i, temp;
944         for(i = 0; i < size; i += 4, pDspCode++) {
945                 temp = *pDspCode;
946                 temp = (temp>>24) |
947                         ((temp<<8) & 0x00FF0000) |
948                         ((temp>>8) & 0x0000FF00) |
949                         (temp<<24);
951                 *pDspCode = temp;
952         }
955 /* ============================================================================
956  *  @func   writeDSPMemory
957  *
958  *  @desc   Write a block of data into DSP memory from Linux host.
959  *          Note the data buffer is in 32-bit format, unit of length is byte.
960  *          coreNum: to write data: 0-7 for cores 0-7; 8 for MSMC; 9 for DDR.
961  *
962  *  @modif  None.
963  *  ============================================================================
964  */
965 uint32_t writeDSPMemory(uint32_t coreNum, uint32_t DSPMemAddr, uint32_t *buffer, uint32_t length)
967         uint32_t i, offset, tempReg = 0;
968         uint32_t *ptr;
970         if (length == 0) {
971                 return 0;
972         }
974         switch (coreNum) {
975 #if EVMC6678L
976                 case 0:
977                 case 1:
978                 case 2:
979                 case 3:
980                 case 4:
981                 case 5:
982                 case 6:
983                 case 7:
984 #endif
985 #if EVMC6670L
986                 case 0:
987                 case 1:
988                 case 2:
989                 case 3:
990 #endif
991 #if EVMC6657L
992                 case 0:
993                 case 1:
994 #endif
995 #if EVMK2H
996                 case 0:
997                 case 1:
998                 case 2:
999                 case 3:
1000                 case 4:
1001                 case 5:
1002                 case 6:
1003                 case 7:
1004 #endif
1005                         DSPMemAddr &= 0x00FFFFFF;
1006                         tempReg = ioread32(ptrReg + IB_OFFSET(1)/4);
1007                         iowrite32(tempReg + coreNum*0x01000000, ptrReg + IB_OFFSET(1)/4); /* pointing to a different core */
1009                         if (DSPMemAddr < LL2_START) {
1010                                 return 0;
1011                         } else {
1012                                 offset = DSPMemAddr - LL2_START;
1013                                 ptr = (uint32_t *)memVirt + offset/4;
1014                         }
1015                         break;
1016                 case 8:  /* this is for MSMC */
1017                         if (DSPMemAddr < MSMC_START) {
1018                                 return 0;
1019                         } else {
1020                                 offset = DSPMemAddr - MSMC_START;
1021                                 ptr = (uint32_t *)msmcVirt + offset/4;
1022                         }
1023                         break;
1024                 case 9:  /* this is for DDR */
1025                         if (DSPMemAddr < DDR_START) {
1026                                 return 0;
1027                         } else {
1028                                 offset = DSPMemAddr - DDR_START;
1029                                 ptr = (uint32_t *)ddrVirt + offset/4;
1030                         }
1031                         break;
1032                 default:
1033                         printk("Use coreNum 0-7 for core 0-7 of EVMC6678L/EVMK2H, or coreNum 0-3 for core 0-3 of EVMC6670L; coreNum 8 for MSMC and coreNum 9 for DDR.\n");
1034                         return 0;
1035                         break;
1036         }
1038         for (i = 0; i < length/4; i++) {
1039 #if BIG_ENDIAN
1040                 swap4bytes(&buffer[i], 4);
1041 #endif
1042                 *ptr = buffer[i];
1043                 ptr++;
1044         }
1046         if ((coreNum >= 0)&&(coreNum <= 7)) {
1047                 iowrite32(tempReg, ptrReg + IB_OFFSET(1)/4);  /* Restore IB_OFFSET1 */
1048         }
1050         return length;
1053 /* ============================================================================
1054  *  @func   readDSPMemory
1055  *
1056  *  @desc   Read a block of DSP memory by Linux host.
1057  *          Note the data buffer is in 32-bit format, unit of length is byte.
1058  *          coreNum: to read data: 0-7 for cores 0-7; 8 for MSMC; 9 for DDR.
1059  *
1060  *  @modif  None.
1061  *  ============================================================================
1062  */
1063 uint32_t readDSPMemory(uint32_t coreNum, uint32_t DSPMemAddr, uint32_t *buffer, uint32_t length)
1065         uint32_t i, offset, tempReg = 0;
1066         uint32_t *ptr;
1068         if (length == 0) {
1069                 return 0;
1070         }
1072         switch (coreNum) {
1073 #if EVMC6678L
1074                 case 0:
1075                 case 1:
1076                 case 2:
1077                 case 3:
1078                 case 4:
1079                 case 5:
1080                 case 6:
1081                 case 7:
1082 #endif
1083 #if EVMC6670L
1084                 case 0:
1085                 case 1:
1086                 case 2:
1087                 case 3:
1088 #endif
1089 #if EVMC6657L
1090                 case 0:
1091                 case 1:
1092 #endif
1093 #if EVMK2H
1094                 case 0:
1095                 case 1:
1096                 case 2:
1097                 case 3:
1098                 case 4:
1099                 case 5:
1100                 case 6:
1101                 case 7:
1102 #endif
1103                         DSPMemAddr &= 0x00FFFFFF;
1104                         tempReg = ioread32(ptrReg + IB_OFFSET(1)/4);
1105                         iowrite32(tempReg + coreNum*0x1000000, ptrReg + IB_OFFSET(1)/4);        /* pointing to a different core */
1106                         if (DSPMemAddr < LL2_START) {
1107                                 return 0;
1108                         } else {
1109                                 offset = DSPMemAddr - LL2_START;
1110                                 ptr = (uint32_t *)memVirt + offset/4;
1111                         }
1112                         break;
1113                 case 8:  /* this is for MSMC */
1114                         if (DSPMemAddr < MSMC_START) {
1115                                 return 0;
1116                         } else {
1117                                 offset = DSPMemAddr - MSMC_START;
1118                                 ptr = (uint32_t *)msmcVirt + offset/4;
1119                         }
1120                         break;
1121                 case 9:  /* this is for DDR */
1122                         if (DSPMemAddr < DDR_START) {
1123                                 return 0;
1124                         } else {
1125                                 offset = DSPMemAddr - DDR_START;
1126                                 ptr = (uint32_t *)ddrVirt + offset/4;
1127                         }
1128                         break;
1129                 default:
1130                         printk("Use coreNum 0-7 for core 0-7 of EVMC6678L/EVMK2H, or coreNum 0-3 for core 0-3 of EVMC6670L; coreNum 8 for MSMC and coreNum 9 for DDR.\n");
1131                         return 0;
1132                         break;
1133         }
1135         for (i = 0; i < length/4; i++) {
1136                 buffer[i] = *ptr;
1137 #if BIG_ENDIAN
1138                 swap4bytes(&buffer[i], 4);
1139 #endif
1140                 ptr++;
1141         }
1143         if ((coreNum >= 0)&&(coreNum <= 7)) {
1144                 iowrite32(tempReg, ptrReg + IB_OFFSET(1)/4);  /* Restore IB_OFFSET1 */
1145         }
1147         return length;
1150 /* ============================================================================
1151  *  @func   pushData
1152  *
1153  *  @desc   Parser function for DSP boot image array
1154  *
1155  *  @modif  None.
1156  *  ============================================================================
1157  */
1158 void pushData(uint8_t *pDspCode, uint8_t coreNum, uint32_t *bootEntryAddr)
1160         uint32_t i, j, tempArray[BLOCK_TRANSFER_SIZE/4];
1161         uint32_t size, section = 0, totalSize = 0;
1162         uint32_t count, remainder, startAddr, temp;
1163         uint8_t newCoreNum;
1165         /* Get the boot entry address */
1166         *bootEntryAddr = byteTo32bits(pDspCode);
1167         printk("Boot entry address is 0x%8x\n", *bootEntryAddr);
1168         pDspCode +=4;
1170         while(1) {
1172                 /* Get the size */
1173                 size = byteTo32bits(pDspCode);
1174                 if(size == 0) break;
1176                 if ((size/4)*4 != size) {
1177                         size = ((size/4)+1)*4;
1178                 }
1180                 totalSize += size;
1181                 section++;
1182                 pDspCode += 4;
1183                 startAddr = byteTo32bits(pDspCode);
1185                 /* In case there are several sections within different memory regions */
1186                 temp = (startAddr & 0xFF000000) >> 24;
1188                 if (temp == 0x00 || ((temp >> 4) == 0x1)) {
1189                         if (coreNum < 8) {
1190                                 /* Write address like 0x00800000 to core 1, 2, ... */
1191                                 newCoreNum = coreNum;
1192                         } else {
1193                                 newCoreNum = 0;
1194                         }
1195                 } else if (temp == 0x0C) {
1196                         newCoreNum = 8;
1197                 } else {
1198                         newCoreNum = 9;
1199                 }
1201                 pDspCode+= 4;
1202                 count = size/BLOCK_TRANSFER_SIZE;
1203                 remainder = size - count * BLOCK_TRANSFER_SIZE;
1205                 for(i = 0; i < count; i++) {
1206                         for (j = 0; j < BLOCK_TRANSFER_SIZE/4; j++) {
1207                                 tempArray[j] = byteTo32bits(pDspCode);
1208                                 pDspCode += 4;
1209                         }
1210                         /* Transfer boot tables to DSP */
1211                         writeDSPMemory(newCoreNum, startAddr, tempArray, BLOCK_TRANSFER_SIZE);
1212                         startAddr += BLOCK_TRANSFER_SIZE;
1213                 }
1215                 for (j = 0; j < remainder/4; j++) {
1216                         tempArray[j] = byteTo32bits(pDspCode);
1217                         pDspCode += 4;
1218                 }
1219                 writeDSPMemory(newCoreNum, startAddr, tempArray, remainder);
1220                 // printk("Section %d started at 0x%8x with size 0x%8x bytes written to core %d\n", section, startAddr, size, newCoreNum);
1221         }
1222         printk("Total %d sections, 0x%x bytes of data were written\n", section, totalSize);
1226 #if LOCAL_RESET
1227 /* ============================================================================
1228  *  @func   coreLocalReset
1229  *
1230  *  @desc   Reset a particular CorePac, 6678 Data Manual, section 7.4.4
1231  *          initiated by LPSC MMRs
1232  *
1233  *  @modif  None.
1234  *  ============================================================================
1235  */
1236 void coreLocalReset(uint32_t pid, uint32_t mid, uint32_t state)
1238         uint32_t *pReg, temp, counter = 0;
1240         /* Point to PCIE application registers */
1241         pReg = (uint32_t *)regVirt;
1242         /* Set MST_PRIV bit to access PSC via PCIE */
1243         iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1245         /* Temporarily re-map IB region 3 from DDR memory to PSC registers */
1246         iowrite32(PSC_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1247         /* Now it points to the start of PSC_BASE_ADDRESS */
1248         pReg = (uint32_t*)ddrVirt;
1250         temp = myIoread32(pReg + MDCTL(mid)/4);
1251         if (state == 0) {
1252                 /* Reset assert */
1253                 temp = ((temp & ~0x1F) | PSC_ENABLE) & (~0x100);
1254                 printk("Start local reset assert for core (module id): %d ...\n", mid);
1255         } else  {
1256                 /* Reset de-assert */
1257                 temp = (temp & ~0x1F) | PSC_ENABLE | (1 << 8);
1258                 printk("Start local reset de-assert for core (module id): %d ...\n", mid);
1259         }
1261         myIowrite32(temp, pReg + MDCTL(mid)/4);    /* Assert/De-assert local reset */
1263         /* No previous transition in progress */
1264         counter = 0;
1265         while (true) {
1266                 temp = myIoread32(pReg + PTSTAT/4);
1267                 if ((temp & (1 << pid)) == 0) break;
1268                 mdelay(1);
1269                 counter ++;
1270                 if (counter > 10) {
1271                         printk("Previous transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1272                         break;
1273                 }
1274         }
1276         myIowrite32((1 << pid), pReg + PTCMD/4);
1278         /* Current transition finished */
1279         counter = 0;
1280         while (true) {
1281                 temp = myIoread32(pReg + PTSTAT/4);
1282                 if ((temp & (1 << pid)) == 0) break;
1283                 mdelay(1);
1284                 counter ++;
1285                 if (counter > 10) {
1286                         printk("Current transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1287                         break;
1288                 }
1289         }
1291         /* Verifying state change */
1292         counter = 0;
1293         while (true) {
1294                 temp = myIoread32(pReg + MDSTAT(mid)/4);
1295                 if ((temp & 0x1F) == 3) break;
1296                 mdelay(1);
1297                 counter ++;
1298                 if (counter > 10) {
1299                         printk("MD stat for pid %d mid %d state: %d timeout\n", pid, mid, state);
1300                         break;
1301                 }
1302         }
1304         /* Restore pointer */
1305         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
1306         iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1309 /* ============================================================================
1310  *  @func   setPscState
1311  *
1312  *  @desc   Set a new power state for the specified domain id in a power controler
1313  *          domain. Wait for the power transition to complete.
1314  *
1315  *      pid   -  power domain.
1316  *      mid   -  module id to use for module in the specified power domain
1317  *      state -  new state value to set (0 = RESET; 3 = ENABLE)
1318  *
1319  *  @modif  None.
1320  *  ============================================================================
1321  */
1322 void setPscState(uint32_t pid, uint32_t mid, uint32_t state)
1324         uint32_t *pReg, mdctl, pdctl, temp, counter = 0;
1326         /* Point to PCIE application registers */
1327         pReg = (uint32_t *)regVirt;
1328         /* Set MST_PRIV bit to access PSC via PCIE */
1329         iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1331         /* Temporarily re-map IB region 3 from DDR memory to PSC registers */
1332         iowrite32(PSC_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1333         /* Now it points to the start of PSC_BASE_ADDRESS */
1334         pReg = (uint32_t*)ddrVirt;
1336         mdctl = myIoread32(pReg + MDCTL(mid)/4);
1337         pdctl = myIoread32(pReg + PDCTL(pid)/4);
1339         /* No previous transition in progress */
1340         counter = 0;
1341         while (true) {
1342                 temp = myIoread32(pReg + PTSTAT/4);
1343                 if ((temp & (1 << pid)) == 0) break;
1344                 mdelay(1);
1345                 counter ++;
1346                 if (counter > 10) {
1347                         printk("Previous transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1348                         break;
1349                 }
1350         }
1352         /* Set power domain control */
1353         myIowrite32(pdctl | 0x1, pReg + PDCTL(pid)/4);
1355         /* Set MDCTL NEXT to new state */
1356         mdctl = ((mdctl) & ~(0x1f)) | state;
1357         myIowrite32(mdctl, pReg + MDCTL(mid)/4);
1359         /* Start power transition by setting PTCMD GO to 1 */
1360         temp = myIoread32(pReg + PTCMD/4);
1361         myIowrite32(temp | (0x1<<pid), pReg + PTCMD/4);
1363         /* Current transition finished */
1364         counter = 0;
1365         while (true) {
1366                 temp = myIoread32(pReg + PTSTAT/4);
1367                 if ((temp & (1 << pid)) == 0) break;
1368                 mdelay(1);
1369                 counter ++;
1370                 if (counter > 10) {
1371                         printk("Current transition in progress pid %d mid %d state: %d\n", pid, mid, state);
1372                         break;
1373                 }
1374         }
1376         /* Verifying state change */
1377         counter = 0;
1378         while (true) {
1379                 temp = myIoread32(pReg + MDSTAT(mid)/4);
1380                 if ((temp & 0x1F) == state) break;
1381                 mdelay(1);
1382                 counter ++;
1383                 if (counter > 10) {
1384                         printk("MD stat for pid %d mid %d state: %d timeout\n", pid, mid, state);
1385                         break;
1386                 }
1387         }
1389         /* Restore pointer */
1390         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
1391         iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1394 /* ============================================================================
1395  *  @func   setBootAddrIpcgr
1396  *
1397  *  @desc   Write boot entry point into DSP_BOOT_ADDR0 and the send an IPC
1398  *
1399  *  @modif  None.
1400  *  ============================================================================
1401  */
1402 uint32_t setBootAddrIpcgr(uint32_t core, uint32_t addr)
1404         uint32_t *pReg;
1405         /* Point to PCIE application registers */
1406         pReg = (uint32_t *)regVirt;
1407         /* Set MST_PRIV bit to access PSC via PCIE */
1408         iowrite32(((ioread32(pReg + PRIORITY/4))|0x00010000), pReg + PRIORITY/4);
1410         /* Temporarily re-map IB region 3 from DDR memory to chip level registers */
1411         iowrite32(CHIP_LEVEL_BASE_ADDRESS, pReg + IB_OFFSET(3)/4);
1412         /* Now it points to the start of CHIP_LEVEL_BASE_ADDRESS */
1413         pReg = (uint32_t*)ddrVirt;
1415         /* Unlock KICK0, KICK1 */
1416         myIowrite32(KICK0_UNLOCK, pReg + KICK0/4);
1417         myIowrite32(KICK1_UNLOCK, pReg + KICK1/4);
1419         /* Check if the last 10 bits of addr is 0 */
1420         if ((addr & 0x3f) != 0) {
1421                 printk("The address is not 1K aligned.\n");
1422                 return 0;
1423         }
1425         myIowrite32(addr, pReg + DSP_BOOT_ADDR(core)/4);
1426         myIowrite32(1, pReg + IPCGR(core)/4);
1428         mdelay(1);
1430         /* Restore pointer */
1431         pReg = (uint32_t *)regVirt;     /* Point to PCIE application registers */
1432         iowrite32(DDR_START, pReg + IB_OFFSET(3)/4);
1434         return 1;
1437 /* ============================================================================
1438  *  @func   dspLocalReset
1439  *
1440  *  @desc   Perform DSP cores and periphrals reset
1441  *
1442  *  @modif  None.
1443  *  ============================================================================
1444  */
1445 void dspLocalReset(void)
1447         uint32_t i, bootEntryAddr = 0;
1449 #if EVMC6670L
1450         /* Local reset of all cores */
1451         coreLocalReset(PD13, LPSC_C0_TIM0, LOC_RST_ASSERT);
1452         coreLocalReset(PD14, LPSC_C1_TIM1, LOC_RST_ASSERT);
1453         coreLocalReset(PD15, LPSC_C2_TIM2, LOC_RST_ASSERT);
1454         coreLocalReset(PD16, LPSC_C3_TIM3, LOC_RST_ASSERT);
1456         /* Disable all other modules */
1457         setPscState(PD0, LPSC_TCP3E, PSC_SWRSTDISABLE);
1458         setPscState(PD0, LPSC_VCP2A, PSC_SWRSTDISABLE);
1459         setPscState(PD1, LPSC_DEBUG, PSC_SWRSTDISABLE);
1460         setPscState(PD1, LPSC_TETB, PSC_SWRSTDISABLE);
1461         setPscState(PD2, LPSC_SA, PSC_SWRSTDISABLE);
1462         setPscState(PD2, LPSC_SGMII, PSC_SWRSTDISABLE);
1463         setPscState(PD2, LPSC_PA, PSC_SWRSTDISABLE);
1464         //setPscState(PD3, LPSC_PCIE, PSC_SWRSTDISABLE);
1465         setPscState(PD4, LPSC_SRIO, PSC_SWRSTDISABLE);
1466         setPscState(PD5, LPSC_HYPER, PSC_SWRSTDISABLE);
1467         //setPscState(PD6, LPSC_RESERV, PSC_SWRSTDISABLE);
1468         setPscState(PD7, LPSC_MSMCRAM, PSC_SWRSTDISABLE);
1469         setPscState(PD8, LPSC_RACA_RACB, PSC_SWRSTDISABLE);
1470         setPscState(PD8, LPSC_TAC, PSC_SWRSTDISABLE);
1471         setPscState(PD9, LPSC_FFTCA_FFTCB, PSC_SWRSTDISABLE);
1472         setPscState(PD10, LPSC_AIF2, PSC_SWRSTDISABLE);
1473         setPscState(PD11, LPSC_TCP3DA, PSC_SWRSTDISABLE);
1474         setPscState(PD12, LPSC_VCP2B, PSC_SWRSTDISABLE);
1475         setPscState(PD12, LPSC_VCP2C, PSC_SWRSTDISABLE);
1476         setPscState(PD12, LPSC_VCP2D, PSC_SWRSTDISABLE);
1477         setPscState(PD17, LPSC_TCP3dB, PSC_SWRSTDISABLE);
1479         for (i = 0; i < 4; i++) {
1480                 pushData(localResetCode, i, &bootEntryAddr);
1481                 if (setBootAddrIpcgr(i, bootEntryAddr) == 0) {
1482                         printk("Core %d is not ready !!! \n", i);
1483                 }
1484         }
1486         /* Enable all other modules */
1487         setPscState(PD0, LPSC_TCP3E, PSC_ENABLE);
1488         setPscState(PD0, LPSC_VCP2A, PSC_ENABLE);
1489         setPscState(PD1, LPSC_DEBUG, PSC_ENABLE);
1490         setPscState(PD1, LPSC_TETB, PSC_ENABLE);
1491         setPscState(PD2, LPSC_PA, PSC_ENABLE);
1492         setPscState(PD2, LPSC_SGMII, PSC_ENABLE);
1493         setPscState(PD2, LPSC_SA, PSC_ENABLE);
1494         //setPscState(PD3, LPSC_PCIE, PSC_ENABLE);
1495         setPscState(PD4, LPSC_SRIO, PSC_ENABLE);
1496         setPscState(PD5, LPSC_HYPER, PSC_ENABLE);
1497         //setPscState(PD6, LPSC_RESERV, PSC_ENABLE);
1498         setPscState(PD7, LPSC_MSMCRAM, PSC_ENABLE);
1499         setPscState(PD8, LPSC_RACA_RACB, PSC_ENABLE);
1500         setPscState(PD8, LPSC_TAC, PSC_ENABLE);
1501         setPscState(PD9, LPSC_FFTCA_FFTCB, PSC_ENABLE);
1502         setPscState(PD10, LPSC_AIF2, PSC_ENABLE);
1503         setPscState(PD11, LPSC_TCP3DA, PSC_ENABLE);
1504         setPscState(PD12, LPSC_VCP2B, PSC_ENABLE);
1505         setPscState(PD12, LPSC_VCP2C, PSC_ENABLE);
1506         setPscState(PD12, LPSC_VCP2D, PSC_ENABLE);
1507         setPscState(PD17, LPSC_TCP3dB, PSC_ENABLE);
1509         /* Local out of reset of all cores */
1510         coreLocalReset(PD13, LPSC_C0_TIM0, LOC_RST_DEASSERT);
1511         coreLocalReset(PD14, LPSC_C1_TIM1, LOC_RST_DEASSERT);
1512         coreLocalReset(PD15, LPSC_C2_TIM2, LOC_RST_DEASSERT);
1513         coreLocalReset(PD16, LPSC_C3_TIM3, LOC_RST_DEASSERT);
1514 #endif
1516 #if EVMC6678L
1517         /* Local reset of all cores */
1518         coreLocalReset(PD8,  LPSC_C0_TIM0, LOC_RST_ASSERT);
1519         coreLocalReset(PD9,  LPSC_C1_TIM1, LOC_RST_ASSERT);
1520         coreLocalReset(PD10, LPSC_C2_TIM2, LOC_RST_ASSERT);
1521         coreLocalReset(PD11, LPSC_C3_TIM3, LOC_RST_ASSERT);
1522         coreLocalReset(PD12, LPSC_C4_TIM4, LOC_RST_ASSERT);
1523         coreLocalReset(PD13, LPSC_C5_TIM5, LOC_RST_ASSERT);
1524         coreLocalReset(PD14, LPSC_C6_TIM6, LOC_RST_ASSERT);
1525         coreLocalReset(PD15, LPSC_C7_TIM7, LOC_RST_ASSERT);
1527         /* Disable all other modules */
1528         setPscState(PD0, LPSC_EMIF16_SPI, PSC_SWRSTDISABLE);
1529         setPscState(PD0, LPSC_TSIP, PSC_SWRSTDISABLE);
1530         setPscState(PD1, LPSC_DEBUG, PSC_SWRSTDISABLE);
1531         setPscState(PD1, LPSC_TETB_TRC, PSC_SWRSTDISABLE);
1532         setPscState(PD2, LPSC_SA, PSC_SWRSTDISABLE);
1533         setPscState(PD2, LPSC_SGMII, PSC_SWRSTDISABLE);
1534         setPscState(PD2, LPSC_PA, PSC_SWRSTDISABLE);
1535         //setPscState(PD3, LPSC_PCIE, PSC_SWRSTDISABLE);
1536         setPscState(PD4, LPSC_SRIO, PSC_SWRSTDISABLE);
1537         setPscState(PD5, LPSC_HYPER, PSC_SWRSTDISABLE);
1538         //setPscState(PD6, LPSC_RESERV, PSC_SWRSTDISABLE);
1539         setPscState(PD7, LPSC_MSMCRAM, PSC_SWRSTDISABLE);
1541         for (i = 0; i < 8; i++) {
1542                 pushData(localResetCode, i, &bootEntryAddr);
1543                 if (setBootAddrIpcgr(i, bootEntryAddr) == 0) {
1544                         printk("Core %d is not ready !!! \n", i);
1545                 }
1546         }
1548         /* Enable all other modules */
1549         setPscState(PD0, LPSC_EMIF16_SPI, PSC_ENABLE);
1550         setPscState(PD0, LPSC_TSIP, PSC_ENABLE);
1551         setPscState(PD1, LPSC_DEBUG, PSC_ENABLE);
1552         setPscState(PD1, LPSC_TETB_TRC, PSC_ENABLE);
1553         setPscState(PD2, LPSC_PA, PSC_ENABLE);
1554         setPscState(PD2, LPSC_SGMII, PSC_ENABLE);
1555         setPscState(PD2, LPSC_SA, PSC_ENABLE);
1556         //setPscState(PD3, LPSC_PCIE, PSC_ENABLE);
1557         setPscState(PD4, LPSC_SRIO, PSC_ENABLE);
1558         setPscState(PD5, LPSC_HYPER, PSC_ENABLE);
1559         //setPscState(PD6, LPSC_RESERV, PSC_ENABLE);
1560         setPscState(PD7, LPSC_MSMCRAM, PSC_ENABLE);
1562         /* Local out of reset of all cores */
1563         coreLocalReset(PD8,  LPSC_C0_TIM0, LOC_RST_DEASSERT);
1564         coreLocalReset(PD9,  LPSC_C1_TIM1, LOC_RST_DEASSERT);
1565         coreLocalReset(PD10, LPSC_C2_TIM2, LOC_RST_DEASSERT);
1566         coreLocalReset(PD11, LPSC_C3_TIM3, LOC_RST_DEASSERT);
1567         coreLocalReset(PD12, LPSC_C4_TIM4, LOC_RST_DEASSERT);
1568         coreLocalReset(PD13, LPSC_C5_TIM5, LOC_RST_DEASSERT);
1569         coreLocalReset(PD14, LPSC_C6_TIM6, LOC_RST_DEASSERT);
1570         coreLocalReset(PD15, LPSC_C7_TIM7, LOC_RST_DEASSERT);
1571 #endif
1574 #endif
1575 /* ============================================================================
1576  *  @func   init_module
1577  *
1578  *  @desc   Initialize a loadable module
1579  *
1580  *  @modif  None.
1581  *  ============================================================================
1582  */
1583 int init_module(void)
1585         uint32_t i;
1586         uint32_t bootEntryAddr = 0;              /* Store 32-bit boot entry address read from .h file */
1587 #if HELLO_WORLD_DEMO | EDMA_INTC_DEMO
1588         uint32_t buffer[BLOCK_TRANSFER_SIZE/4];  /* Store 32-bit DSP memory readback data */
1589 #endif
1591 #if EDMA_INTC_DEMO
1592         uint32_t diff;
1593 #endif
1595         printk ("Finding the device....\n") ;
1596         PCI_FindPciDevices();
1597         if (!PCIE_DEV) {
1598                 printk ("No PCIE device found!!!\n") ;
1599         }
1601         if (PCIE_DEV != NULL) {
1603                 printk("Reading the BAR areas....\n");
1604                 PCI_readBAR();
1606                 printk("Enabling the device....\n");
1607                 /* Linux Function: Initialize device before it's used by a driver */
1608                 pci_enable_device(PCIE_DEV);
1610                 /* Linux Function: Associates the given data with the given pci_driver structure */
1611                 pci_set_drvdata(PCIE_DEV, memVirt);
1613                 PCI_setMaster();
1615                 printk("Access PCIE application register ....\n");
1616                 /* Pointing to the beginning of the application registers */
1617                 ptrReg = (uint32_t *)regVirt;
1619                 /* Configure IB_BAR0 to BAR0 for PCIE registers; Configure IB_BAR1 to BAR1 for LL2 for core 0
1620                    Configure IB_BAR2 to BAR2 for MSMC; Configure IB_BAR3 to BAR3 for DDR */
1621                 for (i = 0; i < 4; i++) {
1622                         iowrite32(i, ptrReg + IB_BAR(i)/4);
1623                         iowrite32(PCIE_DEV->resource[i].start, ptrReg + IB_START_LO(i)/4);
1624                         iowrite32(0, ptrReg + IB_START_HI(i)/4);
1625                 }
1626                 iowrite32(PCIE_BASE_ADDRESS, ptrReg + IB_OFFSET(0)/4);
1627                 iowrite32(LL2_START + (1 << 28), ptrReg + IB_OFFSET(1)/4);
1628                 iowrite32(MSMC_START, ptrReg + IB_OFFSET(2)/4);
1629                 iowrite32(DDR_START, ptrReg + IB_OFFSET(3)/4);
1631                 printk("Registering the irq %d ...\n", irqNo);
1632                 request_irq(irqNo, ISR_handler, IRQF_SHARED, "TI 667x PCIE", &dummy);
1633                 HAL_PciEnableDspInterrupt();
1635 #if HELLO_WORLD_DEMO
1636                 /* Load DDR init code into DSP */
1637                 pushData(ddrInitCode, 0, &bootEntryAddr);
1639                 /* Write boot entry address into MAGIC_ADDR */
1640                 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1642                 while (1) {
1643                         readDSPMemory(0, MAGIC_ADDR, buffer, 4);
1644                         if (buffer[0] == 0)  break;
1645                         for (i = 0; i < 1000; i++) i++;
1646                 }
1648                 /* Load "Hello World" demo into DSP */
1649                 pushData(bootCode, 9, &bootEntryAddr);
1651                 /* Write boot entry address into MAGIC_ADDR */
1652                 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1653 #endif
1655 #if POST_DEMO
1656                 /* Load POST demo code into DSP */
1657                 pushData(post, 0, &bootEntryAddr);
1659                 /* Write boot entry address into MAGIC_ADDR */
1660                 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1661 #endif
1663 #if EDMA_INTC_DEMO
1665                 printk("Allocating consistent memory ...\n");
1666                 wDataVirt = (uint8_t*)dma_alloc_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, &wData, GFP_KERNEL);
1667                 rDataVirt = (uint8_t*)dma_alloc_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, &rData, GFP_KERNEL);
1669                 for (i = 0; i < DMA_TRANSFER_SIZE; i++) {
1670                         wDataVirt[i] = i;
1671                         rDataVirt[i] = 0;
1672                 }
1674                 /* Load Interrupt demo code into DSP */
1675                 pushData(pcieInterrupt, 0, &bootEntryAddr);
1677                 /* Write boot entry address into MAGIC_ADDR */
1678                 writeDSPMemory(0, MAGIC_ADDR, &bootEntryAddr, 4);
1680                 while (1) {
1681                         readDSPMemory(0, MAGIC_ADDR, buffer, 4);
1682                         if (buffer[0] == 0)  break;
1683                         for (i = 0; i < 1000; i++) i++;
1684                 }
1686                 /* Wait 2 second for DDR init */
1687                 mdelay(2000);
1689                 printk ("Write DMA to DSP ...\n");
1690                 do_gettimeofday(&test_time1);
1691                 HAL_writeDMA (wData, DDR_START, DMA_TRANSFER_SIZE, 1);   /* Move from GPP to DSP */
1692                 do_gettimeofday(&test_time2);
1694                 /* Note: From PCIE specification, legacy interrupts cannot be generated from RC and be passed downstream.
1695                    The example below is just making use of the facility that RC can access EP side register to generate
1696                    a generic interrupt on local (EP) side using one of the event inputs of Interrupt Controller (INTC).
1697                    There is no real interrupt signal sent over the PCIe link */
1698                 printk ("Generating interrupt to DSP ...\n");
1699                 iowrite32(1, ptrReg + LEGACY_A_IRQ_STATUS_RAW/4);
1701                 /* Waiting DSP ISR handler to process the interrupt from DSP and then generates an interrupt to host
1702                    Waiting for host ISR handler to process the interrupt from DSP before program exits */
1703                 mdelay(1000);
1705                 /* For demo how to move inside DSP purpose only, you can directly move between GPP and DSP using flag = 1 */
1706                 //      HAL_writeDMA (0x80000000, 0x11800000, 0x10000, 0);
1707                 //      HAL_writeDMA (0x11800000, 0x0C000000, 0x10000, 0);
1709                 diff = (test_time2.tv_sec - test_time1.tv_sec)*1000000 + (test_time2.tv_usec - test_time1.tv_usec);
1710                 printk("DMA write throughput is: %d.%02d MB/s\n", DMA_TRANSFER_SIZE/(1024*1024)*1000*1000/diff,
1711                                 ((DMA_TRANSFER_SIZE/(1024*1024)*1000*1000)%diff)*100/diff);
1713                 diff = (test_time4.tv_sec - test_time3.tv_sec)*1000000 + (test_time4.tv_usec - test_time3.tv_usec);
1714                 printk("DMA read throughput is: %d.%02d MB/s\n", DMA_TRANSFER_SIZE/(1024*1024)*1000*1000/diff,
1715                                 ((DMA_TRANSFER_SIZE/(1024*1024)*1000*1000)%diff)*100/diff);
1717                 printk("Freeing consistent memory ...\n");
1718                 dma_free_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, wDataVirt, wData);
1719                 dma_free_coherent(&PCIE_DEV->dev, DMA_TRANSFER_SIZE, rDataVirt, rData);
1720 #endif
1722 #if LOCAL_RESET
1723                 mdelay(10000);
1724                 dspLocalReset();
1725 #endif
1726         }
1727         else {
1728                 printk("No PCIE device found!!!\n");
1729         }
1730         return 0 ;
1733 /* ============================================================================
1734  *  @func   cleanup_module
1735  *
1736  *  @desc   Unregister a loadable module
1737  *
1738  *  @modif  None.
1739  *  ============================================================================
1740  */
1742 void cleanup_module(void)
1745         if (PCIE_DEV != NULL) {
1746                 HAL_PciDisableDspInterrupt();
1747                 /* ---------------------------------------------------------------------
1748                  * Unmap baseRegs region & release the reg region.
1749                  * ---------------------------------------------------------------------
1750                  */
1751                 iounmap(regVirt);
1752                 if (pci_resource_flags(PCIE_DEV, 0) & IORESOURCE_MEM) {
1753                         /* Map the memory region. */
1754                         release_mem_region(regBase, regLen);
1755                 }
1756                 else {
1757                         /* Map the memory region. */
1758                         release_region(regBase, regLen);
1759                 }
1761                 /* ---------------------------------------------------------------------
1762                  * Unmap LL2 region & release the reg region.
1763                  * ---------------------------------------------------------------------
1764                  */
1765                 iounmap(memVirt);
1766                 if (pci_resource_flags(PCIE_DEV, 1) & IORESOURCE_MEM) {
1767                         /* Map the memory region. */
1768                         release_mem_region(memBase, memLen);
1769                 }
1770                 else {
1771                         /* Map the memory region. */
1772                         release_region(memBase, memLen);
1773                 }
1775                 /* ---------------------------------------------------------------------
1776                  * Unmap MSMC region & release the reg region.
1777                  * ---------------------------------------------------------------------
1778                  */
1779                 iounmap(msmcVirt);
1780                 if (pci_resource_flags(PCIE_DEV, 2) & IORESOURCE_MEM) {
1781                         /* Map the memory region. */
1782                         release_mem_region(msmcBase, msmcLen);
1783                 }
1784                 else {
1785                         /* Map the memory region. */
1786                         release_region(msmcBase, msmcLen);
1787                 }
1789                 /* ---------------------------------------------------------------------
1790                  * Unmap DDR region & release the reg region.
1791                  * ---------------------------------------------------------------------
1792                  */
1793                 iounmap(ddrVirt);
1794                 if (pci_resource_flags(PCIE_DEV, 3) & IORESOURCE_MEM) {
1795                         /* Map the memory region. */
1796                         release_mem_region(ddrBase, ddrLen);
1797                 }
1798                 else {
1799                         /* Map the memory region. */
1800                         release_region(ddrBase, ddrLen);
1801                 }
1803                 free_irq(irqNo, &dummy);
1804         }