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