]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/devcfg_v3_1/src/xdevcfg.c
FreeRTOS source updates:
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / devcfg_v3_1 / src / xdevcfg.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2014 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal 
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32 /****************************************************************************/
33 /**
34 *
35 * @file xdevcfg.c
36 * @addtogroup devcfg_v3_1
37 * @{
38 *
39 * This file contains the implementation of the interface functions for XDcfg
40 * driver. Refer to the header file xdevcfg.h for more detailed information.
41 *
42 * <pre>
43 * MODIFICATION HISTORY:
44 *
45 * Ver   Who Date     Changes
46 * ----- --- -------- ---------------------------------------------
47 * 1.00a hvm 02/07/11 First release
48 * 2.00a nm  05/31/12 Updated the driver for CR 660835 so that input length for
49 *                    source/destination to the XDcfg_InitiateDma, XDcfg_Transfer
50 *                    APIs is words (32 bit) and not bytes.
51 *                    Updated the notes for XDcfg_InitiateDma/XDcfg_Transfer APIs
52 *                    to add information that 2 LSBs of the Source/Destination
53 *                    address when equal to 2\92b01 indicate the last DMA command
54 *                    of an overall transfer.
55 *                    Updated the XDcfg_Transfer function to use the
56 *                    Destination Address passed to this API for secure transfers
57 *                    instead of using 0xFFFFFFFF for CR 662197. This issue was
58 *                    resulting in the failure of secure transfers of
59 *                    non-bitstream images.
60 * 2.01a nm  08/27/12 Updated the XDcfg_Transfer API to clear the
61 *                    QUARTER_PCAP_RATE_EN bit in the control register for
62 *                    non secure writes for CR 675543.
63 * 2.02a nm  01/31/13 Fixed CR# 679335.
64 *                    Added Setting and Clearing the internal PCAP loopback.
65 *                    Removed code for enabling/disabling AES engine as BootROM
66 *                    locks down this setting.
67 *                    Fixed CR# 681976.
68 *                    Skip Checking the PCFG_INIT in case of non-secure DMA
69 *                    loopback.
70 *                    Fixed CR# 699558.
71 *                    XDcfg_Transfer fails to transfer data in loopback mode.
72 * 2.03a nm  04/19/13 Fixed CR# 703728.
73 *                    Updated the register definitions as per the latest TRM
74 *                    version UG585 (v1.4) November 16, 2012.
75 * 3.0   kpc 21/02/14 Implemented new function XDcfg_ClearControlRegister
76 * </pre>
77 *
78 ******************************************************************************/
79
80 /***************************** Include Files *********************************/
81
82 #include "xdevcfg.h"
83
84 /************************** Constant Definitions *****************************/
85
86 /**************************** Type Definitions *******************************/
87
88 /***************** Macros (Inline Functions) Definitions *********************/
89
90 /************************** Function Prototypes ******************************/
91
92 /************************** Variable Definitions *****************************/
93
94 /****************************************************************************/
95 /**
96 *
97 * Initialize the Device Config Interface driver. This function
98 * must be called before other functions of the driver are called.
99 *
100 * @param        InstancePtr is a pointer to the XDcfg instance.
101 * @param        ConfigPtr is the config structure.
102 * @param        EffectiveAddress is the base address for the device. It could be
103 *               a virtual address if address translation is supported in the
104 *               system, otherwise it is the physical address.
105 *
106 * @return
107 *               - XST_SUCCESS if initialization was successful.
108 *               - XST_DEVICE_IS_STARTED if the device has already been started.
109 *
110 * @note         The very first APB access to the Device Configuration Interface
111 *               block needs to be a write to the UNLOCK register with the value
112 *               of 0x757BDF0D. This step is to be done once after reset, any
113 *               other APB access has to come after this. The APB access is
114 *               considered illegal if the step is not done or if it is done
115 *               incorrectly. Furthermore, if any of efuse_sec_cfg[5:0] is high,
116 *               the following additional actions would be carried out.
117 *               In other words, if all bits are low, the following steps are not
118 *               done.
119 *                       1. AES is disabled
120 *                       2. All APB writes disabled
121 *                       3. SoC debug fully enabled
122 *
123 ******************************************************************************/
124 int XDcfg_CfgInitialize(XDcfg *InstancePtr,
125                          XDcfg_Config *ConfigPtr, u32 EffectiveAddress)
126 {
127         Xil_AssertNonvoid(InstancePtr != NULL);
128         Xil_AssertNonvoid(ConfigPtr != NULL);
129
130         /*
131          * If the device is started, disallow the initialize and return a
132          * status indicating it is started. This allows the user to stop the
133          * device and reinitialize, but prevents a user from inadvertently
134          * initializing.
135          */
136         if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
137                 return XST_DEVICE_IS_STARTED;
138         }
139
140         /*
141          * Copy configuration into instance.
142          */
143         InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
144
145         /*
146          * Save the base address pointer such that the registers of the block
147          * can be accessed and indicate it has not been started yet.
148          */
149         InstancePtr->Config.BaseAddr = EffectiveAddress;
150         InstancePtr->IsStarted = 0;
151
152
153         /* Unlock the Device Configuration Interface */
154         XDcfg_Unlock(InstancePtr);
155
156         /*
157          * Indicate the instance is ready to use, successfully initialized.
158          */
159         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
160
161         return XST_SUCCESS;
162 }
163
164 /****************************************************************************/
165 /**
166 *
167 * The functions enables the PCAP interface by setting the PCAP mode bit in the
168 * control register.
169 *
170 * @param        InstancePtr is a pointer to the XDcfg instance.
171 *
172 * @return       None.
173 *
174 * @note         Enable FPGA programming from PCAP interface. Enabling this bit
175 *               disables all the external interfaces from programming of FPGA
176 *               except for ICAP. The user needs to ensure that the FPGA is
177 *               programmed through either PCAP or ICAP.
178 *
179 *****************************************************************************/
180 void XDcfg_EnablePCAP(XDcfg *InstancePtr)
181 {
182         u32 CtrlReg;
183         /*
184          * Assert the arguments.
185          */
186         Xil_AssertVoid(InstancePtr != NULL);
187         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
188
189
190         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
191                                         XDCFG_CTRL_OFFSET);
192
193         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
194                         (CtrlReg | XDCFG_CTRL_PCAP_MODE_MASK));
195
196 }
197
198 /****************************************************************************/
199 /**
200 *
201 * The functions disables the PCAP interface by clearing the PCAP mode bit in
202 * the control register.
203 *
204 * @param        InstancePtr is a pointer to the XDcfg instance.
205 *
206 * @return       None.
207 *
208 * @note         None.
209 *
210 *****************************************************************************/
211 void XDcfg_DisablePCAP(XDcfg *InstancePtr)
212 {
213         u32 CtrlReg;
214         /*
215          * Assert the arguments.
216          */
217         Xil_AssertVoid(InstancePtr != NULL);
218         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
219
220
221         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
222                                         XDCFG_CTRL_OFFSET);
223
224         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
225                         (CtrlReg & ( ~XDCFG_CTRL_PCAP_MODE_MASK)));
226
227 }
228
229 /****************************************************************************/
230 /**
231 *
232 * The function sets the contents of the Control Register.
233 *
234 * @param        InstancePtr is a pointer to the XDcfg instance.
235 * @param        Mask is the 32 bit mask data to be written to the Register.
236 *               The mask definitions are defined in the xdevcfg_hw.h file.
237 *
238 * @return       None.
239 *
240 * @note         None.
241 *
242 *****************************************************************************/
243 void XDcfg_SetControlRegister(XDcfg *InstancePtr, u32 Mask)
244 {
245         u32 CtrlReg;
246         /*
247          * Assert the arguments.
248          */
249         Xil_AssertVoid(InstancePtr != NULL);
250         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
251
252
253         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
254                                         XDCFG_CTRL_OFFSET);
255
256         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
257                         (CtrlReg | Mask));
258
259 }
260
261 /****************************************************************************/
262 /**
263 *
264 * The function Clears the specified bit positions of the Control Register.
265 *
266 * @param        InstancePtr is a pointer to the XDcfg instance.
267 * @param        Mask is the 32 bit value which holds the bit positions to be cleared. 
268 *
269 * @return       None.
270 *
271 * @note         None.
272 *
273 *****************************************************************************/
274 void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask)
275 {
276         u32 CtrlReg;
277         /*
278          * Assert the arguments.
279          */
280         Xil_AssertVoid(InstancePtr != NULL);
281         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
282
283
284         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
285                                         XDCFG_CTRL_OFFSET);
286
287         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
288                         (CtrlReg & ~Mask));
289
290 }
291
292 /****************************************************************************/
293 /**
294 *
295 * The function reads the contents of the Control Register.
296 *
297 * @param        InstancePtr is a pointer to the XDcfg instance.
298 *
299 * @return       A 32-bit value representing the contents of the Control
300 *               Register.
301 *               Use the XDCFG_CTRL_*_MASK constants defined in xdevcfg_hw.h to
302 *               interpret the returned value.
303 *
304 * @note         None.
305 *
306 *****************************************************************************/
307 u32 XDcfg_GetControlRegister(XDcfg *InstancePtr)
308 {
309         /*
310          * Assert the arguments.
311          */
312         Xil_AssertNonvoid(InstancePtr != NULL);
313         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
314
315         /*
316          * Read the Control Register and return the value.
317          */
318         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CTRL_OFFSET);
319 }
320
321 /****************************************************************************/
322 /**
323 *
324 * The function sets the contents of the Lock Register. These bits
325 * can only be set to a 1. They will be cleared after a Power On Reset.
326 *
327 * @param        InstancePtr is a pointer to the XDcfg instance.
328 * @param        Data is the 32 bit data to be written to the Register.
329 *
330 * @return       None.
331 *
332 * @note         None.
333 *
334 *****************************************************************************/
335 void XDcfg_SetLockRegister(XDcfg *InstancePtr, u32 Data)
336 {
337         /*
338          * Assert the arguments.
339          */
340         Xil_AssertVoid(InstancePtr != NULL);
341         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
342
343         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_LOCK_OFFSET, Data);
344
345 }
346
347 /****************************************************************************/
348 /**
349 *
350 * The function reads the contents of the Lock Register.
351 *
352 * @param        InstancePtr is a pointer to the XDcfg instance.
353 *
354 * @return       A 32-bit value representing the contents of the Lock
355 *               Register.
356 *               Use the XDCFG_CR_*_MASK constants defined in xdevcfg_hw.h to
357 *               interpret the returned value.
358 *
359 * @note         None.
360 *
361 *****************************************************************************/
362 u32 XDcfg_GetLockRegister(XDcfg *InstancePtr)
363 {
364         /*
365          * Assert the arguments.
366          */
367         Xil_AssertNonvoid(InstancePtr != NULL);
368         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
369
370         /*
371          * Read the Lock Register and return the value.
372          */
373         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_LOCK_OFFSET);
374 }
375
376 /****************************************************************************/
377 /**
378 *
379 * The function sets the contents of the Configuration Register with the
380 * given value.
381 *
382 * @param        InstancePtr is a pointer to the XDcfg instance.
383 * @param        Data is the 32 bit data to be written to the Register.
384 *
385 * @return       None.
386 *
387 * @note         None.
388 *
389 *****************************************************************************/
390 void XDcfg_SetConfigRegister(XDcfg *InstancePtr, u32 Data)
391 {
392         /*
393          * Assert the arguments.
394          */
395         Xil_AssertVoid(InstancePtr != NULL);
396         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
397
398         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_CFG_OFFSET, Data);
399
400 }
401
402 /****************************************************************************/
403 /**
404 *
405 * The function reads the contents of the Configuration Register with the
406 * given value.
407 *
408 * @param        InstancePtr is a pointer to the XDcfg instance.
409 *
410 * @return       A 32-bit value representing the contents of the Config
411 *               Register.
412 *               Use the XDCFG_CFG_*_MASK constants defined in xdevcfg_hw.h to
413 *               interpret the returned value.
414 *
415 * @note         None.
416 *
417 *****************************************************************************/
418 u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr)
419 {
420         /*
421          * Assert the arguments.
422          */
423         Xil_AssertNonvoid(InstancePtr != NULL);
424         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
425
426         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CFG_OFFSET);
427
428 }
429
430 /****************************************************************************/
431 /**
432 *
433 * The function sets the contents of the Status Register.
434 *
435 * @param        InstancePtr is a pointer to the XDcfg instance.
436 * @param        Data is the 32 bit data to be written to the Register.
437 *
438 * @return       None.
439 *
440 * @note         None.
441 *
442 *****************************************************************************/
443 void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data)
444 {
445         /*
446          * Assert the arguments.
447          */
448         Xil_AssertVoid(InstancePtr != NULL);
449         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
450
451         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET, Data);
452
453 }
454
455 /****************************************************************************/
456 /**
457 *
458 * The function reads the contents of the Status Register.
459 *
460 * @param        InstancePtr is a pointer to the XDcfg instance.
461 *
462 * @return       A 32-bit value representing the contents of the Status
463 *               Register.
464 *               Use the XDCFG_STATUS_*_MASK constants defined in
465 *               xdevcfg_hw.h to interpret the returned value.
466 *
467 * @note         None.
468 *
469 *****************************************************************************/
470 u32 XDcfg_GetStatusRegister(XDcfg *InstancePtr)
471 {
472         /*
473          * Assert the arguments.
474          */
475         Xil_AssertNonvoid(InstancePtr != NULL);
476         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
477
478         /*
479          * Read the Status Register and return the value.
480          */
481         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET);
482 }
483
484 /****************************************************************************/
485 /**
486 *
487 * The function sets the contents of the ROM Shadow Control Register.
488 *
489 * @param        InstancePtr is a pointer to the XDcfg instance.
490 * @param        Data is the 32 bit data to be written to the Register.
491 *
492 * @return       None.
493 *
494 * @note         This register is can only be written and is used to control the
495 *               RAM shadow of 32 bit 4K page ROM pages in user mode
496 *
497 *****************************************************************************/
498 void XDcfg_SetRomShadowRegister(XDcfg *InstancePtr, u32 Data)
499 {
500         /*
501          * Assert the arguments.
502          */
503         Xil_AssertVoid(InstancePtr != NULL);
504         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
505
506         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_ROM_SHADOW_OFFSET,
507                                 Data);
508
509 }
510
511 /****************************************************************************/
512 /**
513 *
514 * The function reads the contents of the Software ID Register.
515 *
516 * @param        InstancePtr is a pointer to the XDcfg instance.
517 *
518 * @return       32 Bit boot software ID.
519 *
520 * @note         This register is locked for write once the system enters
521 *               usermode. Hence API for reading the register only is provided.
522 *
523 *****************************************************************************/
524 u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr)
525 {
526         /*
527          * Assert the arguments.
528          */
529         Xil_AssertNonvoid(InstancePtr != NULL);
530         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
531
532         /*
533          * Read the Software ID Register and return the value.
534          */
535         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_SW_ID_OFFSET);
536 }
537
538 /****************************************************************************/
539 /**
540 *
541 * The function sets the bit mask for the feature in Miscellaneous Control
542 * Register.
543 *
544 * @param        InstancePtr is a pointer to the XDcfg instance.
545 * @param        Mask is the bit-mask of the feature to be set.
546 *
547 * @return       None.
548 *
549 * @note         None
550 *
551 *****************************************************************************/
552 void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask)
553 {
554         u32 RegData;
555
556         /*
557          * Assert the arguments.
558          */
559         Xil_AssertVoid(InstancePtr != NULL);
560         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
561
562
563         RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
564                                         XDCFG_MCTRL_OFFSET);
565
566         XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET,
567                                 (RegData | Mask));
568 }
569
570 /****************************************************************************/
571 /**
572 *
573 * The function reads the contents of the Miscellaneous Control Register.
574 *
575 * @param        InstancePtr is a pointer to the XDcfg instance.
576 *
577 * @return       32 Bit boot software ID.
578 *
579 * @note         This register is locked for write once the system enters
580 *               usermode. Hence API to reading the register only is provided.
581 *
582 *****************************************************************************/
583 u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr)
584 {
585         /*
586          * Assert the arguments.
587          */
588         Xil_AssertNonvoid(InstancePtr != NULL);
589         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
590
591         /*
592          * Read the Miscellaneous Control Register and return the value.
593          */
594         return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET);
595 }
596
597 /******************************************************************************/
598 /**
599 *
600 * This function checks if DMA command queue is full.
601 *
602 * @param        InstancePtr is a pointer to the XDcfg instance.
603 *
604 * @return       XST_SUCCESS is the DMA is busy
605 *               XST_FAILURE if the DMA is idle
606 *
607 * @note         The DMA queue has a depth of two.
608 *
609 ****************************************************************************/
610 u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr)
611 {
612
613         u32 RegData;
614
615         Xil_AssertNonvoid(InstancePtr != NULL);
616         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
617
618         /* Read the PCAP status register for DMA status */
619         RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
620                                         XDCFG_STATUS_OFFSET);
621
622         if ((RegData & XDCFG_STATUS_DMA_CMD_Q_F_MASK) ==
623                                 XDCFG_STATUS_DMA_CMD_Q_F_MASK){
624                 return XST_SUCCESS;
625         }
626
627         return XST_FAILURE;
628 }
629
630 /******************************************************************************/
631 /**
632 *
633 * This function initiates the DMA transfer.
634 *
635 * @param        InstancePtr is a pointer to the XDcfg instance.
636 * @param        SourcePtr contains a pointer to the source memory where the data
637 *               is to be transferred from.
638 * @param        SrcWordLength is the number of words (32 bit) to be transferred
639 *               for the source transfer.
640 * @param        DestPtr contains a pointer to the destination memory
641 *               where the data is to be transferred to.
642 * @param        DestWordLength is the number of words (32 bit) to be transferred
643 *               for the Destination transfer.
644 *
645 * @return       None.
646 *
647 * @note         It is the responsibility of the caller function to ensure that
648 *               correct values are passed to this function.
649 *
650 *               The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination)
651 *               address when equal to 2\92b01 indicates the last DMA command of
652 *               an overall transfer.
653 *
654 ****************************************************************************/
655 void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr,
656                                 u32 SrcWordLength, u32 DestWordLength)
657 {
658
659         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
660                                 XDCFG_DMA_SRC_ADDR_OFFSET,
661                                 SourcePtr);
662
663         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
664                                 XDCFG_DMA_DEST_ADDR_OFFSET,
665                                 DestPtr);
666
667         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
668                                 XDCFG_DMA_SRC_LEN_OFFSET,
669                                 SrcWordLength);
670
671         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
672                                 XDCFG_DMA_DEST_LEN_OFFSET,
673                                 DestWordLength);
674 }
675
676 /******************************************************************************/
677 /**
678 *
679 * This function Implements the DMA Read Command. This command is used to
680 * transfer the image data from FPGA to the external memory.
681 *
682 * @param        InstancePtr is a pointer to the XDcfg instance.
683 * @param        SourcePtr contains a pointer to the source memory where the data
684 *               is to be transferred from.
685 * @param        SrcWordLength is the number of words (32 bit) to be transferred
686 *               for the source transfer.
687 * @param        DestPtr contains a pointer to the destination memory
688 *               where the data is to be transferred to.
689 * @param        DestWordLength is the number of words (32 bit) to be transferred
690 *               for the Destination transfer.
691 *
692 * @return       - XST_INVALID_PARAM if source address/length is invalid.
693 *               - XST_SUCCESS if DMA transfer initiated properly.
694 *
695 * @note         None.
696 *
697 ****************************************************************************/
698 static u32 XDcfg_PcapReadback(XDcfg *InstancePtr, u32 SourcePtr,
699                                 u32 SrcWordLength, u32 DestPtr,
700                                 u32 DestWordLength)
701 {
702         u32 IntrReg;
703
704         /*
705          * Send READ Frame command to FPGA
706          */
707         XDcfg_InitiateDma(InstancePtr, SourcePtr, XDCFG_DMA_INVALID_ADDRESS,
708                                 SrcWordLength, 0);
709
710         /*
711          * Store the enabled interrupts to enable before the actual read
712          * transfer is initiated and Disable all the interrupts temporarily.
713          */
714         IntrReg = XDcfg_IntrGetEnabled(InstancePtr);
715         XDcfg_IntrDisable(InstancePtr, XDCFG_IXR_ALL_MASK);
716
717         /*
718          * Wait till you get the DMA done for the read command sent
719          */
720          while ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
721                         XDCFG_INT_STS_OFFSET) &
722                         XDCFG_IXR_D_P_DONE_MASK) ==
723                         XDCFG_IXR_D_P_DONE_MASK);
724         /*
725          * Enable the previously stored Interrupts .
726          */
727         XDcfg_IntrEnable(InstancePtr, IntrReg);
728
729         /*
730          * Initiate the DMA write command.
731          */
732         XDcfg_InitiateDma(InstancePtr, XDCFG_DMA_INVALID_ADDRESS, (u32)DestPtr,
733                                 0, DestWordLength);
734
735         return XST_SUCCESS;
736 }
737
738
739 /****************************************************************************/
740 /**
741 *
742 * This function starts the DMA transfer. This function only starts the
743 * operation and returns before the operation may be completed.
744 * If the interrupt is enabled, an interrupt will be generated when the
745 * operation is completed, otherwise it is necessary to poll the Status register
746 * to determine when it is completed. It is the responsibility of the caller to
747 * determine when the operation is completed by handling the generated interrupt
748 * or polling the Status Register.
749 *
750 * @param        InstancePtr is a pointer to the XDcfg instance.
751 * @param        SourcePtr contains a pointer to the source memory where the data
752 *               is to be transferred from.
753 * @param        SrcWordLength is the number of words (32 bit) to be transferred
754 *               for the source transfer.
755 * @param        DestPtr contains a pointer to the destination memory
756 *               where the data is to be transferred to.
757 * @param        DestWordLength is the number of words (32 bit) to be transferred
758 *               for the Destination transfer.
759 * @param        TransferType contains the type of PCAP transfer being requested.
760 *               The definitions can be found in the xdevcfg.h file.
761 * @return
762 *               - XST_SUCCESS.if DMA transfer initiated successfully
763 *               - XST_DEVICE_BUSY if DMA is busy
764 *               - XST_INVALID_PARAM if invalid Source / Destination address
765 *                       is sent or an invalid Source / Destination length is
766 *                       sent
767 *
768 * @note         It is the responsibility of the caller to ensure that the cache
769 *               is flushed and invalidated both before the DMA operation is
770 *               started and after the DMA operation completes if the memory
771 *               pointed to is  cached. The caller must also ensure that the
772 *               pointers contain physical address rather than a virtual address
773 *               if address translation is being used.
774 *
775 *               The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination)
776 *               address when equal to 2\92b01 indicates the last DMA command of
777 *               an overall transfer.
778 *
779 *****************************************************************************/
780 u32 XDcfg_Transfer(XDcfg *InstancePtr,
781                         void *SourcePtr, u32 SrcWordLength,
782                         void *DestPtr, u32 DestWordLength,
783                         u32 TransferType)
784 {
785
786         u32 CtrlReg;
787
788         Xil_AssertNonvoid(InstancePtr != NULL);
789         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
790
791
792         if (XDcfg_IsDmaBusy(InstancePtr) == XST_SUCCESS) {
793                 return XST_DEVICE_BUSY;
794         }
795
796         /*
797          * Check whether the fabric is in initialized state
798          */
799         if ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET)
800                         & XDCFG_STATUS_PCFG_INIT_MASK) == 0) {
801                 /*
802                  * We don't need to check PCFG_INIT to be high for
803                  * non-encrypted loopback transfers.
804                  */
805                 if (TransferType != XDCFG_CONCURRENT_NONSEC_READ_WRITE) {
806                         return XST_FAILURE;
807                 }
808         }
809
810         if ((TransferType == XDCFG_SECURE_PCAP_WRITE) ||
811                 (TransferType == XDCFG_NON_SECURE_PCAP_WRITE)) {
812
813                 /* Check for valid source pointer and length */
814                 if ((!SourcePtr) || (SrcWordLength == 0)) {
815                         return XST_INVALID_PARAM;
816                 }
817
818                 /* Clear internal PCAP loopback */
819                 CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
820                                         XDCFG_MCTRL_OFFSET);
821                 XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
822                                 XDCFG_MCTRL_OFFSET, (CtrlReg &
823                                 ~(XDCFG_MCTRL_PCAP_LPBK_MASK)));
824
825                 if (TransferType == XDCFG_NON_SECURE_PCAP_WRITE) {
826                         /*
827                          * Clear QUARTER_PCAP_RATE_EN bit
828                          * so that the PCAP data is transmitted every clock
829                          */
830                         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
831                                                 XDCFG_CTRL_OFFSET);
832
833                         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
834                                         XDCFG_CTRL_OFFSET, (CtrlReg &
835                                           ~XDCFG_CTRL_PCAP_RATE_EN_MASK));
836
837                 }
838                 if (TransferType == XDCFG_SECURE_PCAP_WRITE) {
839                         /*
840                          * AES engine handles only 8 bit data every clock cycle.
841                          * Hence, Encrypted PCAP data which is 32 bit data can
842                          * only be sent in every 4 clock cycles. Set the control
843                          * register QUARTER_PCAP_RATE_EN bit to achieve this
844                          * operation.
845                          */
846                         XDcfg_SetControlRegister(InstancePtr,
847                                                 XDCFG_CTRL_PCAP_RATE_EN_MASK);
848                 }
849
850                 XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr,
851                                 (u32)DestPtr, SrcWordLength, DestWordLength);
852
853         }
854
855         if (TransferType == XDCFG_PCAP_READBACK) {
856
857                 if ((!DestPtr) || (DestWordLength == 0)) {
858
859                         return XST_INVALID_PARAM;
860                 }
861
862                 /* Clear internal PCAP loopback */
863                 CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
864                                         XDCFG_MCTRL_OFFSET);
865                 XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
866                                 XDCFG_MCTRL_OFFSET, (CtrlReg &
867                                 ~(XDCFG_MCTRL_PCAP_LPBK_MASK)));
868
869                 /*
870                  * For PCAP readback of FPGA configuration register or memory,
871                  * the read command is first sent (written) to the FPGA fabric
872                  * which responds by returning the required read data. Read data
873                  * from the FPGA is captured if pcap_radata_v is active.A DMA
874                  * read transfer is required to obtain the readback command,
875                  * which is then sent to the FPGA, followed by a DMA write
876                  * transfer to support this mode of operation.
877                  */
878                 return XDcfg_PcapReadback(InstancePtr,
879                                          (u32)SourcePtr, SrcWordLength,
880                                          (u32)DestPtr,   DestWordLength);
881         }
882
883
884         if ((TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) ||
885                 (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE)) {
886
887                 if ((!SourcePtr) || (SrcWordLength == 0) ||
888                         (!DestPtr) || (DestWordLength == 0)) {
889                         return XST_INVALID_PARAM;
890                 }
891
892                 if (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE) {
893                         /* Enable internal PCAP loopback */
894                         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
895                                         XDCFG_MCTRL_OFFSET);
896                         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
897                                         XDCFG_MCTRL_OFFSET, (CtrlReg |
898                                         XDCFG_MCTRL_PCAP_LPBK_MASK));
899
900                         /*
901                          * Clear QUARTER_PCAP_RATE_EN bit
902                          * so that the PCAP data is transmitted every clock
903                          */
904                         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
905                                                 XDCFG_CTRL_OFFSET);
906
907                         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
908                                         XDCFG_CTRL_OFFSET, (CtrlReg &
909                                           ~XDCFG_CTRL_PCAP_RATE_EN_MASK));
910
911                 }
912                 if (TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) {
913                         /* Clear internal PCAP loopback */
914                         CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
915                                                 XDCFG_MCTRL_OFFSET);
916                         XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
917                                         XDCFG_MCTRL_OFFSET, (CtrlReg &
918                                         ~(XDCFG_MCTRL_PCAP_LPBK_MASK)));
919
920                         /*
921                          * Set the QUARTER_PCAP_RATE_EN bit
922                          * so that the PCAP data is transmitted every 4 clock
923                          * cycles, this is required for encrypted data.
924                          */
925                         XDcfg_SetControlRegister(InstancePtr,
926                                         XDCFG_CTRL_PCAP_RATE_EN_MASK);
927                 }
928
929                 XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr,
930                                 (u32)DestPtr, SrcWordLength, DestWordLength);
931         }
932
933         return XST_SUCCESS;
934 }
935 /** @} */