]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/qspipsu_v1_3/src/xqspipsu.c
Update Zynq MPSoC hardware definition and BSP files to be those shipped with the...
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / qspipsu_v1_3 / src / xqspipsu.c
1 /******************************************************************************
2 *
3 * Copyright (C) 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 xqspipsu.c
36 * @addtogroup qspipsu_v1_0
37 * @{
38 *
39 * This file implements the functions required to use the QSPIPSU hardware to
40 * perform a transfer. These are accessible to the user via xqspipsu.h.
41 *
42 * <pre>
43 * MODIFICATION HISTORY:
44 *
45 * Ver   Who Date     Changes
46 * ----- --- -------- -----------------------------------------------
47 * 1.0   hk  08/21/14 First release
48 *       sk  03/13/15 Added IO mode support.
49 *       hk  03/18/15 Switch to I/O mode before clearing RX FIFO.
50 *                    Clear and disbale DMA interrupts/status in abort.
51 *                    Use DMA DONE bit instead of BUSY as recommended.
52 *       sk  04/24/15 Modified the code according to MISRAC-2012.
53 *       sk  06/17/15 Removed NULL checks for Rx/Tx buffers. As
54 *                    writing/reading from 0x0 location is permitted.
55 * 1.1   sk  04/12/16 Added debug message prints.
56 * 1.2   nsk 07/01/16 Changed XQspiPsu_Select to support GQSPI and LQSPI
57 *                    selection.
58 *       rk  07/15/16 Added support for TapDelays at different frequencies.
59 *       nsk 08/05/16 Added example support PollData and PollTimeout
60 * 1.3   nsk 09/16/16 Update PollData and PollTimeout support for dual
61 *                    parallel configurations, modified XQspiPsu_PollData()
62 *                    and XQspiPsu_Create_PollConfigData()
63 *
64 * </pre>
65 *
66 ******************************************************************************/
67
68 /***************************** Include Files *********************************/
69
70 #include "xqspipsu.h"
71
72 /************************** Constant Definitions *****************************/
73
74 /**************************** Type Definitions *******************************/
75
76 /***************** Macros (Inline Functions) Definitions *********************/
77
78 /************************** Function Prototypes ******************************/
79 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
80                         u32 ByteCount);
81 static inline u32 XQspiPsu_SelectSpiMode(u8 SpiMode);
82 static inline void XQspiPsu_TXRXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
83                         u32 *GenFifoEntry);
84 static inline void XQspiPsu_FillTxFifo(XQspiPsu *InstancePtr,
85                         XQspiPsu_Msg *Msg, s32 Size);
86 static inline void XQspiPsu_SetupRxDma(XQspiPsu *InstancePtr,
87                         XQspiPsu_Msg *Msg);
88 static inline void XQspiPsu_GenFifoEntryCSAssert(XQspiPsu *InstancePtr);
89 static inline void XQspiPsu_GenFifoEntryData(XQspiPsu *InstancePtr,
90                         XQspiPsu_Msg *Msg, s32 Index);
91 static inline void XQspiPsu_GenFifoEntryCSDeAssert(XQspiPsu *InstancePtr);
92 static inline void XQspiPsu_ReadRxFifo(XQspiPsu *InstancePtr,
93                         XQspiPsu_Msg *Msg, s32 Size);
94 static inline void XQspiPsu_PollData(XQspiPsu *QspiPsuPtr,
95                 XQspiPsu_Msg *FlashMsg);
96 static inline u32 XQspiPsu_Create_PollConfigData(XQspiPsu *QspiPsuPtr,
97                 XQspiPsu_Msg *FlashMsg);
98
99 /************************** Variable Definitions *****************************/
100
101 /*****************************************************************************/
102 /**
103 *
104 * Initializes a specific XQspiPsu instance such that the driver is ready to use.
105 *
106 *
107 * @param        InstancePtr is a pointer to the XQspiPsu instance.
108 * @param        ConfigPtr is a reference to a structure containing information
109 *               about a specific QSPIPSU device. This function initializes an
110 *               InstancePtr object for a specific device specified by the
111 *               contents of Config.
112 * @param        EffectiveAddr is the device base address in the virtual memory
113 *               address space. The caller is responsible for keeping the address
114 *               mapping from EffectiveAddr to the device physical base address
115 *               unchanged once this function is invoked. Unexpected errors may
116 *               occur if the address mapping changes after this function is
117 *               called. If address translation is not used, use
118 *               ConfigPtr->Config.BaseAddress for this device.
119 *
120 * @return
121 *               - XST_SUCCESS if successful.
122 *               - XST_DEVICE_IS_STARTED if the device is already started.
123 *               It must be stopped to re-initialize.
124 *
125 * @note         None.
126 *
127 ******************************************************************************/
128 s32 XQspiPsu_CfgInitialize(XQspiPsu *InstancePtr, XQspiPsu_Config *ConfigPtr,
129                                 u32 EffectiveAddr)
130 {
131         Xil_AssertNonvoid(InstancePtr != NULL);
132         Xil_AssertNonvoid(ConfigPtr != NULL);
133         s32 Status;
134
135         /*
136          * If the device is busy, disallow the initialize and return a status
137          * indicating it is already started. This allows the user to stop the
138          * device and re-initialize, but prevents a user from inadvertently
139          * initializing. This assumes the busy flag is cleared at startup.
140          */
141         if (InstancePtr->IsBusy == TRUE) {
142                 Status = (s32)XST_DEVICE_IS_STARTED;
143         } else {
144
145                 /* Set some default values. */
146                 InstancePtr->IsBusy = FALSE;
147
148                 InstancePtr->Config.BaseAddress = EffectiveAddr + XQSPIPSU_OFFSET;
149                 InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode;
150                 InstancePtr->StatusHandler = StubStatusHandler;
151                 InstancePtr->Config.BusWidth = ConfigPtr->BusWidth;
152                 InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
153                 /* Other instance variable initializations */
154                 InstancePtr->SendBufferPtr = NULL;
155                 InstancePtr->RecvBufferPtr = NULL;
156                 InstancePtr->GenFifoBufferPtr = NULL;
157                 InstancePtr->TxBytes = 0;
158                 InstancePtr->RxBytes = 0;
159                 InstancePtr->GenFifoEntries = 0;
160                 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
161                 InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
162                 InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
163                 InstancePtr->IsUnaligned = 0;
164                 InstancePtr->IsManualstart = TRUE;
165
166                 /* Select QSPIPSU */
167                 XQspiPsu_Select(InstancePtr, XQSPIPSU_SEL_GQSPI_MASK);
168
169                 /*
170                  * Reset the QSPIPSU device to get it into its initial state. It is
171                  * expected that device configuration will take place after this
172                  * initialization is done, but before the device is started.
173                  */
174                 XQspiPsu_Reset(InstancePtr);
175
176                 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
177
178                 Status = XST_SUCCESS;
179         }
180
181         return Status;
182 }
183
184 /*****************************************************************************/
185 /**
186 *
187 * Resets the QSPIPSU device. Reset must only be called after the driver has
188 * been initialized. Any data transfer that is in progress is aborted.
189 *
190 * The upper layer software is responsible for re-configuring (if necessary)
191 * and restarting the QSPIPSU device after the reset.
192 *
193 * @param        InstancePtr is a pointer to the XQspiPsu instance.
194 *
195 * @return       None.
196 *
197 * @note         None.
198 *
199 ******************************************************************************/
200 void XQspiPsu_Reset(XQspiPsu *InstancePtr)
201 {
202         u32 ConfigReg;
203
204         Xil_AssertVoid(InstancePtr != NULL);
205
206         /* Abort any transfer that is in progress */
207         XQspiPsu_Abort(InstancePtr);
208
209         /* Default value to config register */
210         ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
211                         XQSPIPSU_CFG_OFFSET);
212
213         /* DMA mode */
214         ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
215         ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
216         /* Manual start */
217         ConfigReg |= XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK;
218         /* Little endain by default */
219         ConfigReg &= ~XQSPIPSU_CFG_ENDIAN_MASK;
220         /* Disable poll timeout */
221         ConfigReg &= ~XQSPIPSU_CFG_EN_POLL_TO_MASK;
222         /* Set hold bit */
223         ConfigReg |= XQSPIPSU_CFG_WP_HOLD_MASK;
224         /* Clear prescalar by default */
225         ConfigReg &= (u32)(~XQSPIPSU_CFG_BAUD_RATE_DIV_MASK);
226         /* CPOL CPHA 00 */
227         ConfigReg &= (u32)(~XQSPIPSU_CFG_CLK_PHA_MASK);
228         ConfigReg &= (u32)(~XQSPIPSU_CFG_CLK_POL_MASK);
229
230         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
231                 XQSPIPSU_CFG_OFFSET, ConfigReg);
232
233         /* Set by default to allow for high frequencies */
234         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
235                 XQSPIPSU_LPBK_DLY_ADJ_OFFSET,
236                 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
237                         XQSPIPSU_LPBK_DLY_ADJ_OFFSET) |
238                         XQSPIPSU_LPBK_DLY_ADJ_USE_LPBK_MASK);
239
240         /* Reset thresholds */
241         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
242                 XQSPIPSU_TX_THRESHOLD_OFFSET,
243                 XQSPIPSU_TX_FIFO_THRESHOLD_RESET_VAL);
244         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
245                 XQSPIPSU_RX_THRESHOLD_OFFSET,
246                 XQSPIPSU_RX_FIFO_THRESHOLD_RESET_VAL);
247         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
248                 XQSPIPSU_GF_THRESHOLD_OFFSET,
249                 XQSPIPSU_GEN_FIFO_THRESHOLD_RESET_VAL);
250
251         /* DMA init */
252         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
253                         XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET,
254                         XQSPIPSU_QSPIDMA_DST_CTRL_RESET_VAL);
255
256 }
257
258 /*****************************************************************************/
259 /**
260 *
261 * Aborts a transfer in progress by
262 *
263 * @param        InstancePtr is a pointer to the XQspiPsu instance.
264 *
265 * @return       None.
266 *
267 * @note
268 *
269 ******************************************************************************/
270 void XQspiPsu_Abort(XQspiPsu *InstancePtr)
271 {
272
273         u32 IntrStatus, ConfigReg;
274
275         IntrStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
276                                         XQSPIPSU_ISR_OFFSET);
277
278         /* Clear and disable interrupts */
279         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
280                 XQSPIPSU_ISR_OFFSET, IntrStatus | XQSPIPSU_ISR_WR_TO_CLR_MASK);
281         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
282                         XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
283                 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
284                                 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET));
285         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
286                         XQSPIPSU_QSPIDMA_DST_STS_OFFSET,
287                         XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
288                                 XQSPIPSU_QSPIDMA_DST_STS_OFFSET) |
289                                 XQSPIPSU_QSPIDMA_DST_STS_WTC);
290         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
291                 XQSPIPSU_IDR_OFFSET, XQSPIPSU_IDR_ALL_MASK);
292         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
293                         XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
294                         XQSPIPSU_QSPIDMA_DST_INTR_ALL_MASK);
295
296         /* Clear FIFO */
297         if((XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
298                         XQSPIPSU_ISR_OFFSET) & XQSPIPSU_ISR_RXEMPTY_MASK) != FALSE) {
299                 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
300                         XQSPIPSU_FIFO_CTRL_OFFSET,
301                         XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_MASK |
302                         XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_MASK);
303         }
304
305         /*
306          * Switch to IO mode to Clear RX FIFO. This is becuase of DMA behaviour
307          * where it waits on RX empty and goes busy assuming there is data
308          * to be transfered even if there is no request.
309          */
310         if ((IntrStatus & XQSPIPSU_ISR_RXEMPTY_MASK) != 0U) {
311                 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
312                                         XQSPIPSU_CFG_OFFSET);
313                 ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
314                 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
315                                 XQSPIPSU_CFG_OFFSET, ConfigReg);
316
317                 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
318                                 XQSPIPSU_FIFO_CTRL_OFFSET,
319                                 XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_MASK);
320
321                 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
322                         ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
323                         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
324                                         XQSPIPSU_CFG_OFFSET, ConfigReg);
325                 }
326         }
327
328         /* Disable QSPIPSU */
329         XQspiPsu_Disable(InstancePtr);
330
331         InstancePtr->TxBytes = 0;
332         InstancePtr->RxBytes = 0;
333         InstancePtr->GenFifoEntries = 0;
334         InstancePtr->IsBusy = FALSE;
335 }
336
337 /*****************************************************************************/
338 /**
339 *
340 * This function performs a transfer on the bus in polled mode. The messages
341 * passed are all transferred on the bus between one CS assert and de-assert.
342 *
343 * @param        InstancePtr is a pointer to the XQspiPsu instance.
344 * @param        Msg is a pointer to the structure containing transfer data.
345 * @param        NumMsg is the number of messages to be transferred.
346 *
347 * @return
348 *               - XST_SUCCESS if successful.
349 *               - XST_FAILURE if transfer fails.
350 *               - XST_DEVICE_BUSY if a transfer is already in progress.
351 *
352 * @note         None.
353 *
354 ******************************************************************************/
355 s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
356                                 u32 NumMsg)
357 {
358
359         s32 Index;
360         u32 QspiPsuStatusReg;
361         u32 BaseAddress;
362         s32 RxThr;
363         u32 IOPending = (u32)FALSE;
364
365         Xil_AssertNonvoid(InstancePtr != NULL);
366         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
367         for (Index = 0; Index < (s32)NumMsg; Index++) {
368                 Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
369         }
370
371         /* Check whether there is another transfer in progress. Not thread-safe */
372         if (InstancePtr->IsBusy == TRUE) {
373                 return (s32)XST_DEVICE_BUSY;
374         }
375
376         /* Check for ByteCount upper limit - 2^28 for DMA */
377         for (Index = 0; Index < (s32)NumMsg; Index++) {
378                 if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
379                                 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
380                         return (s32)XST_FAILURE;
381                 }
382         }
383
384         /*
385          * Set the busy flag, which will be cleared when the transfer is
386          * entirely done.
387          */
388         InstancePtr->IsBusy = TRUE;
389
390         BaseAddress = InstancePtr->Config.BaseAddress;
391
392         /* Enable */
393         XQspiPsu_Enable(InstancePtr);
394
395         /* Select slave */
396         XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
397
398         /* list */
399         Index = 0;
400         while (Index < (s32)NumMsg) {
401                 XQspiPsu_GenFifoEntryData(InstancePtr, Msg, Index);
402
403                 if (InstancePtr->IsManualstart == TRUE) {
404 #ifdef DEBUG
405         xil_printf("\nManual Start\r\n");
406 #endif
407                         XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_CFG_OFFSET,
408                                 XQspiPsu_ReadReg(BaseAddress,
409                                         XQSPIPSU_CFG_OFFSET) |
410                                         XQSPIPSU_CFG_START_GEN_FIFO_MASK);
411                 }
412
413                 /* Use thresholds here */
414                 /* If there is more data to be transmitted */
415                 do {
416                         QspiPsuStatusReg = XQspiPsu_ReadReg(BaseAddress,
417                                                 XQSPIPSU_ISR_OFFSET);
418
419                         /* Transmit more data if left */
420                         if (((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != FALSE) &&
421                                 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_TX) != FALSE) &&
422                                 (InstancePtr->TxBytes > 0)) {
423                                 XQspiPsu_FillTxFifo(InstancePtr, &Msg[Index],
424                                                 XQSPIPSU_TXD_DEPTH);
425                         }
426
427                         /* Check if DMA RX is complete and update RxBytes */
428                         if ((InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) &&
429                                 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
430                                 u32 DmaIntrSts;
431                                 DmaIntrSts = XQspiPsu_ReadReg(BaseAddress,
432                                                                 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
433                                 if ((DmaIntrSts & XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != FALSE) {
434                                         XQspiPsu_WriteReg(BaseAddress,
435                                                 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
436                                                 DmaIntrSts);
437                                         /* Read remaining bytes using IO mode */
438                                         if((InstancePtr->RxBytes % 4) != 0 ) {
439                                                 XQspiPsu_WriteReg(BaseAddress,
440                                                         XQSPIPSU_CFG_OFFSET,
441                                                         (XQspiPsu_ReadReg(BaseAddress,
442                                                         XQSPIPSU_CFG_OFFSET) &
443                                                         ~XQSPIPSU_CFG_MODE_EN_MASK));
444                                                 InstancePtr->ReadMode = XQSPIPSU_READMODE_IO;
445                                                 Msg[Index].ByteCount =
446                                                         (InstancePtr->RxBytes % 4);
447                                                 Msg[Index].RxBfrPtr += (InstancePtr->RxBytes -
448                                                                 (InstancePtr->RxBytes % 4));
449                                                 InstancePtr->IsUnaligned = 1;
450                                                 IOPending = (u32)TRUE;
451                                                 break;
452                                         }
453                                         InstancePtr->RxBytes = 0;
454                                 }
455                         } else {
456                                 if ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE) {
457                                         /* Check if PIO RX is complete and update RxBytes */
458                                         RxThr = (s32)XQspiPsu_ReadReg(BaseAddress,
459                                                         XQSPIPSU_RX_THRESHOLD_OFFSET);
460                                         if ((QspiPsuStatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK)
461                                                                         != 0U) {
462                                                 XQspiPsu_ReadRxFifo(InstancePtr,
463                                                                 &Msg[Index], RxThr*4);
464
465                                         } else {
466                                                 if ((QspiPsuStatusReg &
467                                                         XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != 0U) {
468                                                                 XQspiPsu_ReadRxFifo(InstancePtr,
469                                                                         &Msg[Index], InstancePtr->RxBytes);
470                                                 }
471                                         }
472                                 }
473                         }
474                 } while (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == FALSE) ||
475                         (InstancePtr->TxBytes != 0) ||
476                         ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == FALSE) ||
477                         (InstancePtr->RxBytes != 0));
478
479                 if((InstancePtr->IsUnaligned != 0) && (IOPending == (u32)FALSE)) {
480                         InstancePtr->IsUnaligned = 0;
481                         XQspiPsu_WriteReg(BaseAddress,
482                                 XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
483                                 BaseAddress,
484                                 XQSPIPSU_CFG_OFFSET) |
485                                 XQSPIPSU_CFG_MODE_EN_DMA_MASK));
486                         InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
487                 }
488
489                 if (IOPending == (u32)TRUE) {
490                         IOPending = (u32)FALSE;
491                 } else {
492                         Index++;
493                 }
494         }
495
496         /* De-select slave */
497         XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
498
499         if (InstancePtr->IsManualstart == TRUE) {
500 #ifdef DEBUG
501         xil_printf("\nManual Start\r\n");
502 #endif
503                 XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_CFG_OFFSET,
504                         XQspiPsu_ReadReg(BaseAddress, XQSPIPSU_CFG_OFFSET) |
505                                 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
506         }
507
508         QspiPsuStatusReg = XQspiPsu_ReadReg(BaseAddress, XQSPIPSU_ISR_OFFSET);
509         while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == FALSE) {
510                 QspiPsuStatusReg = XQspiPsu_ReadReg(BaseAddress,
511                                                 XQSPIPSU_ISR_OFFSET);
512         }
513
514         /* Clear the busy flag. */
515         InstancePtr->IsBusy = FALSE;
516
517         /* Disable the device. */
518         XQspiPsu_Disable(InstancePtr);
519
520         return XST_SUCCESS;
521 }
522
523 /*****************************************************************************/
524 /**
525 *
526 * This function initiates a transfer on the bus and enables interrupts.
527 * The transfer is completed by the interrupt handler. The messages passed are
528 * all transferred on the bus between one CS assert and de-assert.
529 *
530 * @param        InstancePtr is a pointer to the XQspiPsu instance.
531 * @param        Msg is a pointer to the structure containing transfer data.
532 * @param        NumMsg is the number of messages to be transferred.
533 *
534 * @return
535 *               - XST_SUCCESS if successful.
536 *               - XST_FAILURE if transfer fails.
537 *               - XST_DEVICE_BUSY if a transfer is already in progress.
538 *
539 * @note         None.
540 *
541 ******************************************************************************/
542 s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
543                                 u32 NumMsg)
544 {
545
546         s32 Index;
547         u32 BaseAddress;
548
549         Xil_AssertNonvoid(InstancePtr != NULL);
550         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
551         for (Index = 0; Index < (s32)NumMsg; Index++) {
552                 Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
553         }
554
555         /* Check whether there is another transfer in progress. Not thread-safe */
556         if (InstancePtr->IsBusy == TRUE) {
557                 return (s32)XST_DEVICE_BUSY;
558         }
559
560         if (Msg[0].Flags & XQSPIPSU_MSG_FLAG_POLL) {
561                 InstancePtr->IsBusy = TRUE;
562                 XQspiPsu_PollData(InstancePtr, Msg);
563         } else {
564                 /* Check for ByteCount upper limit - 2^28 for DMA */
565                 for (Index = 0; Index < (s32)NumMsg; Index++) {
566                         if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
567                                         ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
568                         return (s32)XST_FAILURE;
569                 }
570         }
571
572         /*
573          * Set the busy flag, which will be cleared when the transfer is
574          * entirely done.
575          */
576         InstancePtr->IsBusy = TRUE;
577
578         BaseAddress = InstancePtr->Config.BaseAddress;
579
580         InstancePtr->Msg = Msg;
581         InstancePtr->NumMsg = (s32)NumMsg;
582         InstancePtr->MsgCnt = 0;
583
584         /* Enable */
585         XQspiPsu_Enable(InstancePtr);
586
587         /* Select slave */
588         XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
589
590         /* This might not work if not manual start */
591         /* Put first message in FIFO along with the above slave select */
592         XQspiPsu_GenFifoEntryData(InstancePtr, Msg, 0);
593
594         if (InstancePtr->IsManualstart == TRUE) {
595 #ifdef DEBUG
596         xil_printf("\nManual Start\r\n");
597 #endif
598                 XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_CFG_OFFSET,
599                         XQspiPsu_ReadReg(BaseAddress, XQSPIPSU_CFG_OFFSET) |
600                                 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
601         }
602
603         /* Enable interrupts */
604         XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_IER_OFFSET,
605                 (u32)XQSPIPSU_IER_TXNOT_FULL_MASK | (u32)XQSPIPSU_IER_TXEMPTY_MASK |
606                 (u32)XQSPIPSU_IER_RXNEMPTY_MASK | (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
607                 (u32)XQSPIPSU_IER_RXEMPTY_MASK);
608
609         if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
610                 XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_QSPIDMA_DST_I_EN_OFFSET,
611                                 XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
612         }
613         }
614         return XST_SUCCESS;
615 }
616
617 /*****************************************************************************/
618 /**
619 *
620 * Handles interrupt based transfers by acting on GENFIFO and DMA interurpts.
621 *
622 * @param        InstancePtr is a pointer to the XQspiPsu instance.
623 *
624 * @return
625 *               - XST_SUCCESS if successful.
626 *               - XST_FAILURE if transfer fails.
627 *
628 * @note         None.
629 *
630 ******************************************************************************/
631 s32 XQspiPsu_InterruptHandler(XQspiPsu *InstancePtr)
632 {
633         u32 QspiPsuStatusReg, DmaIntrStatusReg = 0;
634         u32 BaseAddress;
635         XQspiPsu_Msg *Msg;
636         s32 NumMsg;
637         s32 MsgCnt;
638         u8 DeltaMsgCnt = 0;
639         s32 RxThr;
640         u32 TxRxFlag;
641
642         Xil_AssertNonvoid(InstancePtr != NULL);
643
644         BaseAddress = InstancePtr->Config.BaseAddress;
645         Msg = InstancePtr->Msg;
646         NumMsg = InstancePtr->NumMsg;
647         MsgCnt = InstancePtr->MsgCnt;
648         TxRxFlag = Msg[MsgCnt].Flags;
649
650         /* QSPIPSU Intr cleared on read */
651         QspiPsuStatusReg = XQspiPsu_ReadReg(BaseAddress, XQSPIPSU_ISR_OFFSET);
652         if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
653                 /* DMA Intr write to clear */
654                 DmaIntrStatusReg = XQspiPsu_ReadReg(BaseAddress,
655                                         XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
656
657                 XQspiPsu_WriteReg(BaseAddress,
658                         XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrStatusReg);
659         }
660         if (((DmaIntrStatusReg & XQSPIPSU_QSPIDMA_DST_INTR_ERR_MASK) != FALSE)) {
661                 /* Call status handler to indicate error */
662                 InstancePtr->StatusHandler(InstancePtr->StatusRef,
663                                         XST_SPI_COMMAND_ERROR, 0);
664         }
665
666         /* Fill more data to be txed if required */
667         if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != FALSE) &&
668                 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != FALSE) &&
669                 (InstancePtr->TxBytes > 0)) {
670                 XQspiPsu_FillTxFifo(InstancePtr, &Msg[MsgCnt],
671                                 XQSPIPSU_TXD_DEPTH);
672         }
673
674         /*
675          * Check if the entry is ONLY TX and increase MsgCnt.
676          * This is to allow TX and RX together in one entry - corner case.
677          */
678         if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != FALSE) &&
679                 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) != FALSE) &&
680                 ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != FALSE) &&
681                 (InstancePtr->TxBytes == 0) &&
682                 ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == FALSE)) {
683                 MsgCnt += 1;
684                 DeltaMsgCnt = 1U;
685         }
686
687         if ((InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) &&
688                 (MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
689                 if ((DmaIntrStatusReg & XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != FALSE) {
690                                 /* Read remaining bytes using IO mode */
691                         if((InstancePtr->RxBytes % 4) != 0 ) {
692                                 XQspiPsu_WriteReg(BaseAddress,
693                                         XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
694                                         BaseAddress, XQSPIPSU_CFG_OFFSET) &
695                                         ~XQSPIPSU_CFG_MODE_EN_MASK));
696                                 InstancePtr->ReadMode = XQSPIPSU_READMODE_IO;
697                                 Msg[MsgCnt].ByteCount = (InstancePtr->RxBytes % 4);
698                                 Msg[MsgCnt].RxBfrPtr += (InstancePtr->RxBytes -
699                                                 (InstancePtr->RxBytes % 4));
700                                 InstancePtr->IsUnaligned = 1;
701                                 XQspiPsu_GenFifoEntryData(InstancePtr, Msg,
702                                                 MsgCnt);
703                                 if(InstancePtr->IsManualstart == TRUE) {
704 #ifdef DEBUG
705         xil_printf("\nManual Start\r\n");
706 #endif
707                                         XQspiPsu_WriteReg(BaseAddress,
708                                                 XQSPIPSU_CFG_OFFSET,
709                                                 XQspiPsu_ReadReg(BaseAddress,
710                                                 XQSPIPSU_CFG_OFFSET) |
711                                                 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
712                                 }
713                         }
714                         else {
715                                 InstancePtr->RxBytes = 0;
716                                 MsgCnt += 1;
717                                 DeltaMsgCnt = 1U;
718                         }
719                 }
720         } else {
721                 if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
722                         if (InstancePtr->RxBytes != 0) {
723                                 if ((QspiPsuStatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK)
724                                                                 != FALSE) {
725                                         RxThr = (s32)XQspiPsu_ReadReg(BaseAddress,
726                                                                 XQSPIPSU_RX_THRESHOLD_OFFSET);
727                                         XQspiPsu_ReadRxFifo(InstancePtr, &Msg[MsgCnt],
728                                                 RxThr*4);
729                                 } else {
730                                         if (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != FALSE) &&
731                                                 ((QspiPsuStatusReg & XQSPIPSU_ISR_RXEMPTY_MASK) == FALSE)) {
732                                                 XQspiPsu_ReadRxFifo(InstancePtr, &Msg[MsgCnt],
733                                                         InstancePtr->RxBytes);
734                                         }
735                                 }
736                                 if (InstancePtr->RxBytes == 0) {
737                                         MsgCnt += 1;
738                                         DeltaMsgCnt = 1U;
739                                 }
740                         }
741                 }
742         }
743
744         /*
745          * Dummy byte transfer
746          * MsgCnt < NumMsg check is to ensure is it a valid dummy cycle message
747          * If one of the above conditions increased MsgCnt, then
748          * the new message is yet to be placed in the FIFO; hence !DeltaMsgCnt.
749          */
750         if ((MsgCnt < NumMsg) && (DeltaMsgCnt == FALSE) &&
751                 ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == FALSE) &&
752                 ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) == FALSE) &&
753                 ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) == FALSE) &&
754                 ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != FALSE)) {
755                 MsgCnt += 1;
756                 DeltaMsgCnt = 1U;
757         }
758         InstancePtr->MsgCnt = MsgCnt;
759
760         /*
761          * DeltaMsgCnt is to handle conditions where genfifo empty can be set
762          * while tx is still not empty or rx dma is not yet done.
763          * MsgCnt > NumMsg indicates CS de-assert entry was also executed.
764          */
765         if (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != FALSE) &&
766                 ((DeltaMsgCnt != FALSE) || (MsgCnt > NumMsg))) {
767                 if (MsgCnt < NumMsg) {
768                         if(InstancePtr->IsUnaligned != 0) {
769                                 InstancePtr->IsUnaligned = 0;
770                                 XQspiPsu_WriteReg(InstancePtr->Config.
771                                         BaseAddress, XQSPIPSU_CFG_OFFSET,
772                                         (XQspiPsu_ReadReg(InstancePtr->Config.
773                                         BaseAddress, XQSPIPSU_CFG_OFFSET) |
774                                         XQSPIPSU_CFG_MODE_EN_DMA_MASK));
775                                 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
776                         }
777                         /* This might not work if not manual start */
778                         XQspiPsu_GenFifoEntryData(InstancePtr, Msg, MsgCnt);
779
780                         if (InstancePtr->IsManualstart == TRUE) {
781 #ifdef DEBUG
782         xil_printf("\nManual Start\r\n");
783 #endif
784                                 XQspiPsu_WriteReg(BaseAddress,
785                                         XQSPIPSU_CFG_OFFSET,
786                                         XQspiPsu_ReadReg(BaseAddress,
787                                                 XQSPIPSU_CFG_OFFSET) |
788                                                 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
789                         }
790                 } else if (MsgCnt == NumMsg) {
791                         /* This is just to keep track of the de-assert entry */
792                         MsgCnt += 1;
793                         InstancePtr->MsgCnt = MsgCnt;
794
795                         /* De-select slave */
796                         XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
797
798                         if (InstancePtr->IsManualstart == TRUE) {
799 #ifdef DEBUG
800         xil_printf("\nManual Start\r\n");
801 #endif
802                                 XQspiPsu_WriteReg(BaseAddress,
803                                         XQSPIPSU_CFG_OFFSET,
804                                         XQspiPsu_ReadReg(BaseAddress,
805                                                 XQSPIPSU_CFG_OFFSET) |
806                                                 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
807                         }
808                 } else {
809                         /* Disable interrupts */
810                         XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_IDR_OFFSET,
811                                         (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
812                                         (u32)XQSPIPSU_IER_TXEMPTY_MASK |
813                                         (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
814                                         (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
815                                         (u32)XQSPIPSU_IER_RXEMPTY_MASK);
816                         if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
817                                 XQspiPsu_WriteReg(BaseAddress,
818                                         XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
819                                         XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
820                         }
821
822                         /* Clear the busy flag. */
823                         InstancePtr->IsBusy = FALSE;
824
825                         /* Disable the device. */
826                         XQspiPsu_Disable(InstancePtr);
827
828                         /* Call status handler to indicate completion */
829                         InstancePtr->StatusHandler(InstancePtr->StatusRef,
830                                                 XST_SPI_TRANSFER_DONE, 0);
831                 }
832         }
833         if ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) != FALSE){
834                  if (QspiPsuStatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK){
835                          /*
836                           * Read data from RXFIFO, since when data from the flash device
837                           * (status data) matched with configured value in poll_cfg, then
838                           * controller writes the matched data into RXFIFO.
839                           */
840                         XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_RXD_OFFSET);
841
842                         XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_IDR_OFFSET,
843                                         (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
844                                         (u32)XQSPIPSU_IER_TXEMPTY_MASK |
845                                         (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
846                                         (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
847                                         (u32)XQSPIPSU_IER_RXEMPTY_MASK |
848                                         (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK);
849                         InstancePtr->StatusHandler(InstancePtr->StatusRef, XST_SPI_POLL_DONE, 0);
850
851                         InstancePtr->IsBusy = FALSE;
852                         /* Disable the device. */
853                         XQspiPsu_Disable(InstancePtr);
854
855                  }
856                  if (QspiPsuStatusReg & XQSPIPSU_ISR_POLL_TIME_EXPIRE_MASK){
857                         InstancePtr->StatusHandler(InstancePtr->StatusRef,
858                                         XST_FLASH_TIMEOUT_ERROR, 0);
859                  }
860         }
861         return XST_SUCCESS;
862 }
863
864 /*****************************************************************************/
865 /**
866 *
867 * Sets the status callback function, the status handler, which the driver
868 * calls when it encounters conditions that should be reported to upper
869 * layer software. The handler executes in an interrupt context, so it must
870 * minimize the amount of processing performed. One of the following status
871 * events is passed to the status handler.
872 *
873 * <pre>
874 *
875 * XST_SPI_TRANSFER_DONE         The requested data transfer is done
876 *
877 * XST_SPI_TRANSMIT_UNDERRUN     As a slave device, the master clocked data
878 *                               but there were none available in the transmit
879 *                               register/FIFO. This typically means the slave
880 *                               application did not issue a transfer request
881 *                               fast enough, or the processor/driver could not
882 *                               fill the transmit register/FIFO fast enough.
883 *
884 * XST_SPI_RECEIVE_OVERRUN       The QSPIPSU device lost data. Data was received
885 *                               but the receive data register/FIFO was full.
886 *
887 * </pre>
888 * @param        InstancePtr is a pointer to the XQspiPsu instance.
889 * @param        CallBackRef is the upper layer callback reference passed back
890 *               when the callback function is invoked.
891 * @param        FuncPointer is the pointer to the callback function.
892 *
893 * @return       None.
894 *
895 * @note
896 *
897 * The handler is called within interrupt context, so it should do its work
898 * quickly and queue potentially time-consuming work to a task-level thread.
899 *
900 ******************************************************************************/
901 void XQspiPsu_SetStatusHandler(XQspiPsu *InstancePtr, void *CallBackRef,
902                                 XQspiPsu_StatusHandler FuncPointer)
903 {
904         Xil_AssertVoid(InstancePtr != NULL);
905         Xil_AssertVoid(FuncPointer != NULL);
906         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
907
908         InstancePtr->StatusHandler = FuncPointer;
909         InstancePtr->StatusRef = CallBackRef;
910 }
911
912 /*****************************************************************************/
913 /**
914 *
915 * This is a stub for the status callback. The stub is here in case the upper
916 * layers forget to set the handler.
917 *
918 * @param        CallBackRef is a pointer to the upper layer callback reference
919 * @param        StatusEvent is the event that just occurred.
920 * @param        ByteCount is the number of bytes transferred up until the event
921 *               occurred.
922 *
923 * @return       None.
924 *
925 * @note         None.
926 *
927 ******************************************************************************/
928 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
929                                 u32 ByteCount)
930 {
931         (void *) CallBackRef;
932         (void) StatusEvent;
933         (void) ByteCount;
934
935         Xil_AssertVoidAlways();
936 }
937
938 /*****************************************************************************/
939 /**
940 *
941 * Selects SPI mode - x1 or x2 or x4.
942 *
943 * @param        SpiMode - spi or dual or quad.
944 * @return       Mask to set desired SPI mode in GENFIFO entry.
945 *
946 * @note         None.
947 *
948 ******************************************************************************/
949 static inline u32 XQspiPsu_SelectSpiMode(u8 SpiMode)
950 {
951         u32 Mask;
952
953 #ifdef DEBUG
954         xil_printf("\nXQspiPsu_SelectSpiMode\r\n");
955 #endif
956
957         switch (SpiMode) {
958                 case XQSPIPSU_SELECT_MODE_DUALSPI:
959                         Mask = XQSPIPSU_GENFIFO_MODE_DUALSPI;
960                         break;
961                 case XQSPIPSU_SELECT_MODE_QUADSPI:
962                         Mask = XQSPIPSU_GENFIFO_MODE_QUADSPI;
963                         break;
964                 case XQSPIPSU_SELECT_MODE_SPI:
965                         Mask = XQSPIPSU_GENFIFO_MODE_SPI;
966                         break;
967                 default:
968                         Mask = XQSPIPSU_GENFIFO_MODE_SPI;
969                         break;
970         }
971 #ifdef DEBUG
972         xil_printf("\nSPIMode is %08x\r\n", SpiMode);
973 #endif
974
975         return Mask;
976 }
977
978 /*****************************************************************************/
979 /**
980 *
981 * This function checks the TX/RX buffers in the message and setups up the
982 * GENFIFO entries, TX FIFO or RX DMA as required.
983 *
984 * @param        InstancePtr is a pointer to the XQspiPsu instance.
985 * @param        Msg is a pointer to the structure containing transfer data.
986 * @param        GenFifoEntry is pointer to the variable in which GENFIFO mask
987 *               is returned to calling function
988 *
989 * @return       None
990 *
991 * @note         None.
992 *
993 ******************************************************************************/
994 static inline void XQspiPsu_TXRXSetup(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
995                                         u32 *GenFifoEntry)
996 {
997         Xil_AssertVoid(InstancePtr != NULL);
998
999         /* Transmit */
1000         if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != FALSE) &&
1001                         ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == FALSE)) {
1002                 /* Setup data to be TXed */
1003                 *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
1004                 *GenFifoEntry |= XQSPIPSU_GENFIFO_TX;
1005                 InstancePtr->TxBytes = (s32)Msg->ByteCount;
1006                 InstancePtr->SendBufferPtr = Msg->TxBfrPtr;
1007                 InstancePtr->RecvBufferPtr = NULL;
1008                 XQspiPsu_FillTxFifo(InstancePtr, Msg, XQSPIPSU_TXD_DEPTH);
1009                 /* Discard RX data */
1010                 *GenFifoEntry &= ~XQSPIPSU_GENFIFO_RX;
1011                 InstancePtr->RxBytes = 0;
1012         }
1013
1014         /* Receive */
1015         if (((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE) &&
1016                         ((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == FALSE)) {
1017                 /* TX auto fill */
1018                 *GenFifoEntry &= ~XQSPIPSU_GENFIFO_TX;
1019                 InstancePtr->TxBytes = 0;
1020                 /* Setup RX */
1021                 *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
1022                 *GenFifoEntry |= XQSPIPSU_GENFIFO_RX;
1023                 InstancePtr->RxBytes = (s32)Msg->ByteCount;
1024                 InstancePtr->SendBufferPtr = NULL;
1025                 InstancePtr->RecvBufferPtr = Msg->RxBfrPtr;
1026                 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
1027                         XQspiPsu_SetupRxDma(InstancePtr, Msg);
1028                 }
1029         }
1030
1031         /* If only dummy is requested as a separate entry */
1032         if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) == FALSE) &&
1033                         (Msg->Flags & XQSPIPSU_MSG_FLAG_RX) == FALSE) {
1034                 *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
1035                 *GenFifoEntry &= ~(XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX);
1036                 InstancePtr->TxBytes = 0;
1037                 InstancePtr->RxBytes = 0;
1038                 InstancePtr->SendBufferPtr = NULL;
1039                 InstancePtr->RecvBufferPtr = NULL;
1040         }
1041
1042         /* Dummy and cmd sent by upper layer to received data */
1043         if (((Msg->Flags & XQSPIPSU_MSG_FLAG_TX) != FALSE) &&
1044                         ((Msg->Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
1045                 *GenFifoEntry |= XQSPIPSU_GENFIFO_DATA_XFER;
1046                 *GenFifoEntry |= (XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX);
1047                 InstancePtr->TxBytes = (s32)Msg->ByteCount;
1048                 InstancePtr->RxBytes = (s32)Msg->ByteCount;
1049                 InstancePtr->SendBufferPtr = Msg->TxBfrPtr;
1050                 InstancePtr->RecvBufferPtr = Msg->RxBfrPtr;
1051                 XQspiPsu_FillTxFifo(InstancePtr, Msg, XQSPIPSU_TXD_DEPTH);
1052                 /* Add check for DMA or PIO here */
1053                 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
1054                         XQspiPsu_SetupRxDma(InstancePtr, Msg);
1055                 }
1056         }
1057 }
1058
1059 /*****************************************************************************/
1060 /**
1061 *
1062 * Fills the TX FIFO as long as there is room in the FIFO or the bytes required
1063 * to be transmitted.
1064 *
1065 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1066 * @param        Msg is a pointer to the structure containing transfer data.
1067 * @param        Size is the number of bytes to be transmitted.
1068 *
1069 * @return       None
1070 *
1071 * @note         None.
1072 *
1073 ******************************************************************************/
1074 static inline void XQspiPsu_FillTxFifo(XQspiPsu *InstancePtr,
1075                                         XQspiPsu_Msg *Msg, s32 Size)
1076 {
1077         s32 Count = 0;
1078         u32 Data;
1079
1080         Xil_AssertVoid(InstancePtr != NULL);
1081
1082 #ifdef DEBUG
1083         xil_printf("\nXQspiPsu_FillTxFifo\r\n");
1084 #endif
1085
1086         while ((InstancePtr->TxBytes > 0) && (Count < Size)) {
1087                 if (InstancePtr->TxBytes >= 4) {
1088                         (void)memcpy(&Data, Msg->TxBfrPtr, 4);
1089                         Msg->TxBfrPtr += 4;
1090                         InstancePtr->TxBytes -= 4;
1091                         Count += 4;
1092                 } else {
1093                         (void)memcpy(&Data, Msg->TxBfrPtr, InstancePtr->TxBytes);
1094                         Msg->TxBfrPtr += InstancePtr->TxBytes;
1095                         Count += InstancePtr->TxBytes;
1096                         InstancePtr->TxBytes = 0;
1097                 }
1098                 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1099                                 XQSPIPSU_TXD_OFFSET, Data);
1100 #ifdef DEBUG
1101         xil_printf("\nData is %08x\r\n", Data);
1102 #endif
1103
1104         }
1105         if (InstancePtr->TxBytes < 0) {
1106                 InstancePtr->TxBytes = 0;
1107         }
1108 }
1109
1110 /*****************************************************************************/
1111 /**
1112 *
1113 * This function sets up the RX DMA operation.
1114 *
1115 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1116 * @param        Msg is a pointer to the structure containing transfer data.
1117 *
1118 * @return       None
1119 *
1120 * @note         None.
1121 *
1122 ******************************************************************************/
1123 static inline void XQspiPsu_SetupRxDma(XQspiPsu *InstancePtr,
1124                                         XQspiPsu_Msg *Msg)
1125 {
1126         s32 Remainder;
1127         s32 DmaRxBytes;
1128         u64 AddrTemp;
1129
1130         Xil_AssertVoid(InstancePtr != NULL);
1131
1132         AddrTemp = (u64)((INTPTR)(Msg->RxBfrPtr) &
1133                                 XQSPIPSU_QSPIDMA_DST_ADDR_MASK);
1134         /* Check for RXBfrPtr to be word aligned */
1135         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1136                         XQSPIPSU_QSPIDMA_DST_ADDR_OFFSET,
1137                         (u32)AddrTemp);
1138
1139         AddrTemp = AddrTemp >> 32;
1140         if ((AddrTemp & 0xFFFU) != FALSE) {
1141                 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1142                                 XQSPIPSU_QSPIDMA_DST_ADDR_MSB_OFFSET,
1143                                 (u32)AddrTemp &
1144                                 XQSPIPSU_QSPIDMA_DST_ADDR_MSB_MASK);
1145         }
1146
1147         Remainder = InstancePtr->RxBytes % 4;
1148         DmaRxBytes = InstancePtr->RxBytes;
1149         if (Remainder != 0) {
1150                 /* This is done to make Dma bytes aligned */
1151                 DmaRxBytes = InstancePtr->RxBytes - Remainder;
1152                 Msg->ByteCount = (u32)DmaRxBytes;
1153         }
1154
1155         Xil_DCacheInvalidateRange((INTPTR)InstancePtr->RecvBufferPtr, Msg->ByteCount);
1156
1157         /* Write no. of words to DMA DST SIZE */
1158         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1159                         XQSPIPSU_QSPIDMA_DST_SIZE_OFFSET, (u32)DmaRxBytes);
1160
1161 }
1162
1163 /*****************************************************************************/
1164 /**
1165 *
1166 * This function writes the GENFIFO entry to assert CS.
1167 *
1168 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1169 *
1170 * @return       None
1171 *
1172 * @note         None.
1173 *
1174 ******************************************************************************/
1175 static inline void XQspiPsu_GenFifoEntryCSAssert(XQspiPsu *InstancePtr)
1176 {
1177         u32 GenFifoEntry;
1178
1179 #ifdef DEBUG
1180         xil_printf("\nXQspiPsu_GenFifoEntryCSAssert\r\n");
1181 #endif
1182
1183         GenFifoEntry = 0x0U;
1184         GenFifoEntry &= ~((u32)XQSPIPSU_GENFIFO_DATA_XFER | (u32)XQSPIPSU_GENFIFO_EXP);
1185         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_MODE_MASK);
1186         GenFifoEntry |= XQSPIPSU_GENFIFO_MODE_SPI;
1187         GenFifoEntry |= InstancePtr->GenFifoCS;
1188         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_BUS_MASK);
1189         GenFifoEntry |= InstancePtr->GenFifoBus;
1190         GenFifoEntry &= ~(XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX |
1191                         XQSPIPSU_GENFIFO_STRIPE | XQSPIPSU_GENFIFO_POLL);
1192         GenFifoEntry |= XQSPIPSU_GENFIFO_CS_SETUP;
1193 #ifdef DEBUG
1194         xil_printf("\nFifoEntry=%08x\r\n",GenFifoEntry);
1195 #endif
1196         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1197                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1198 }
1199
1200 /*****************************************************************************/
1201 /**
1202 *
1203 * This function writes the GENFIFO entries to transmit the messages requested.
1204 *
1205 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1206 * @param        Msg is a pointer to the structure containing transfer data.
1207 * @param        Index of the current message to be handled.
1208 *
1209 * @return
1210 *               - XST_SUCCESS if successful.
1211 *               - XST_FAILURE if transfer fails.
1212 *               - XST_DEVICE_BUSY if a transfer is already in progress.
1213 *
1214 * @note         None.
1215 *
1216 ******************************************************************************/
1217 static inline void XQspiPsu_GenFifoEntryData(XQspiPsu *InstancePtr,
1218                                                 XQspiPsu_Msg *Msg, s32 Index)
1219 {
1220         u32 GenFifoEntry;
1221         u32 BaseAddress;
1222         u32 TempCount;
1223         u32 ImmData;
1224
1225 #ifdef DEBUG
1226         xil_printf("\nXQspiPsu_GenFifoEntryData\r\n");
1227 #endif
1228
1229         BaseAddress = InstancePtr->Config.BaseAddress;
1230
1231         GenFifoEntry = 0x0U;
1232         /* Bus width */
1233         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_MODE_MASK);
1234         GenFifoEntry |= XQspiPsu_SelectSpiMode((u8)Msg[Index].BusWidth);
1235
1236         GenFifoEntry |= InstancePtr->GenFifoCS;
1237         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_BUS_MASK);
1238         GenFifoEntry |= InstancePtr->GenFifoBus;
1239
1240         /* Data */
1241         if (((Msg[Index].Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != FALSE) {
1242                 GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE;
1243         } else {
1244                 GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE;
1245         }
1246
1247         /* If Byte Count is less than 8 bytes do the transfer in IO mode */
1248         if ((Msg[Index].ByteCount < 8U) &&
1249                 (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA)) {
1250                         InstancePtr->ReadMode = XQSPIPSU_READMODE_IO;
1251                         XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_CFG_OFFSET,
1252                                 (XQspiPsu_ReadReg(BaseAddress, XQSPIPSU_CFG_OFFSET) &
1253                                                 ~XQSPIPSU_CFG_MODE_EN_MASK));
1254                         InstancePtr->IsUnaligned = 1;
1255         }
1256
1257         XQspiPsu_TXRXSetup(InstancePtr, &Msg[Index], &GenFifoEntry);
1258
1259         if (Msg[Index].ByteCount < XQSPIPSU_GENFIFO_IMM_DATA_MASK) {
1260                 GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_IMM_DATA_MASK);
1261                 GenFifoEntry |= Msg[Index].ByteCount;
1262 #ifdef DEBUG
1263         xil_printf("\nFifoEntry=%08x\r\n",GenFifoEntry);
1264 #endif
1265                 XQspiPsu_WriteReg(BaseAddress, XQSPIPSU_GEN_FIFO_OFFSET,
1266                                 GenFifoEntry);
1267         } else {
1268                 TempCount = Msg[Index].ByteCount;
1269                 u32 Exponent = 8;       /* 2^8 = 256 */
1270
1271                 ImmData = TempCount & 0xFFU;
1272                 /* Exponent entries */
1273                 GenFifoEntry |= XQSPIPSU_GENFIFO_EXP;
1274                 while (TempCount != 0U) {
1275                         if ((TempCount & XQSPIPSU_GENFIFO_EXP_START) != FALSE) {
1276                                 GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_IMM_DATA_MASK);
1277                                 GenFifoEntry |= Exponent;
1278 #ifdef DEBUG
1279         xil_printf("\nFifoEntry=%08x\r\n",GenFifoEntry);
1280 #endif
1281                                 XQspiPsu_WriteReg(BaseAddress,
1282                                         XQSPIPSU_GEN_FIFO_OFFSET,
1283                                         GenFifoEntry);
1284                         }
1285                         TempCount = TempCount >> 1;
1286                         Exponent++;
1287                 }
1288
1289                 /* Immediate entry */
1290                 GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_EXP);
1291                 if ((ImmData & 0xFFU) != FALSE) {
1292                         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_IMM_DATA_MASK);
1293                         GenFifoEntry |= ImmData & 0xFFU;
1294 #ifdef DEBUG
1295         xil_printf("\nFifoEntry=%08x\r\n",GenFifoEntry);
1296 #endif
1297                         XQspiPsu_WriteReg(BaseAddress,
1298                                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1299                 }
1300         }
1301
1302         /* One dummy GenFifo entry in case of IO mode */
1303         if ((InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) &&
1304                         ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != FALSE)) {
1305                 GenFifoEntry = 0x0U;
1306 #ifdef DEBUG
1307         xil_printf("\nDummy FifoEntry=%08x\r\n",GenFifoEntry);
1308 #endif
1309                 XQspiPsu_WriteReg(BaseAddress,
1310                                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1311         }
1312 }
1313
1314 /*****************************************************************************/
1315 /**
1316 *
1317 * This function writes the GENFIFO entry to de-assert CS.
1318 *
1319 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1320 *
1321 * @return       None
1322 *
1323 * @note         None.
1324 *
1325 ******************************************************************************/
1326 static inline void XQspiPsu_GenFifoEntryCSDeAssert(XQspiPsu *InstancePtr)
1327 {
1328         u32 GenFifoEntry;
1329
1330 #ifdef DEBUG
1331         xil_printf("\nXQspiPsu_GenFifoEntryCSDeAssert\r\n");
1332 #endif
1333
1334         GenFifoEntry = 0x0U;
1335         GenFifoEntry &= ~((u32)XQSPIPSU_GENFIFO_DATA_XFER | (u32)XQSPIPSU_GENFIFO_EXP);
1336         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_MODE_MASK);
1337         GenFifoEntry |= XQSPIPSU_GENFIFO_MODE_SPI;
1338         GenFifoEntry &= (u32)(~XQSPIPSU_GENFIFO_BUS_MASK);
1339         GenFifoEntry |= InstancePtr->GenFifoBus;
1340         GenFifoEntry &= ~(XQSPIPSU_GENFIFO_TX | XQSPIPSU_GENFIFO_RX |
1341                         XQSPIPSU_GENFIFO_STRIPE | XQSPIPSU_GENFIFO_POLL);
1342         GenFifoEntry |= XQSPIPSU_GENFIFO_CS_HOLD;
1343 #ifdef DEBUG
1344         xil_printf("\nFifoEntry=%08x\r\n",GenFifoEntry);
1345 #endif
1346         XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1347                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1348 }
1349
1350 /*****************************************************************************/
1351 /**
1352 *
1353 * Read the specified number of bytes from RX FIFO
1354 *
1355 * @param        InstancePtr is a pointer to the XQspiPsu instance.
1356 * @param        Msg is a pointer to the structure containing transfer data.
1357 * @param        Size is the number of bytes to be read.
1358 *
1359 * @return       None
1360 *
1361 * @note         None.
1362 *
1363 ******************************************************************************/
1364 static inline void XQspiPsu_ReadRxFifo(XQspiPsu *InstancePtr,
1365                                         XQspiPsu_Msg *Msg, s32 Size)
1366 {
1367         s32 Count = 0;
1368         u32 Data;
1369
1370 #ifdef DEBUG
1371         xil_printf("\nXQspiPsu_ReadRxFifo\r\n");
1372 #endif
1373
1374         Xil_AssertVoid(InstancePtr != NULL);
1375         Xil_AssertVoid(Msg != NULL);
1376
1377         while ((InstancePtr->RxBytes != 0) && (Count < Size)) {
1378                 Data = XQspiPsu_ReadReg(InstancePtr->
1379                                 Config.BaseAddress, XQSPIPSU_RXD_OFFSET);
1380 #ifdef DEBUG
1381         xil_printf("\nData is %08x\r\n", Data);
1382 #endif
1383                 if (InstancePtr->RxBytes >= 4) {
1384                         (void)memcpy(Msg->RxBfrPtr, &Data, 4);
1385                         InstancePtr->RxBytes -= 4;
1386                         Msg->RxBfrPtr += 4;
1387                         Count += 4;
1388                 } else {
1389                         /* Read unaligned bytes (< 4 bytes) */
1390                         (void)memcpy(Msg->RxBfrPtr, &Data, InstancePtr->RxBytes);
1391                         Msg->RxBfrPtr += InstancePtr->RxBytes;
1392                         Count += InstancePtr->RxBytes;
1393                         InstancePtr->RxBytes = 0;
1394                 }
1395         }
1396 }
1397
1398 /*****************************************************************************/
1399 /**
1400 *
1401 * This function enables the polling functionality of controller
1402 *
1403 * @param        QspiPsuPtr is a pointer to the XQspiPsu instance.
1404 *
1405 * @param        Statuscommand is the status command which send by controller.
1406 *
1407 * @param        FlashMsg is a pointer to the structure containing transfer data
1408 *
1409 * @return       None
1410 *
1411 * @note         None.
1412 *
1413 ******************************************************************************/
1414 void XQspiPsu_PollData(XQspiPsu *QspiPsuPtr, XQspiPsu_Msg *FlashMsg)
1415 {
1416
1417         u32 GenFifoEntry ;
1418         u32 Value;
1419
1420         Xil_AssertVoid(QspiPsuPtr != NULL);
1421         Xil_AssertVoid(FlashMsg != NULL );
1422
1423         Value = XQspiPsu_Create_PollConfigData(QspiPsuPtr, FlashMsg);
1424         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress,
1425                         XQSPIPSU_POLL_CFG_OFFSET, Value);
1426         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress,
1427                         XQSPIPSU_P_TO_OFFSET, FlashMsg->PollTimeout);
1428
1429         XQspiPsu_Enable(QspiPsuPtr);
1430
1431         GenFifoEntry = (u32)0;
1432         GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_TX;
1433         GenFifoEntry |= QspiPsuPtr->GenFifoBus;
1434         GenFifoEntry |= QspiPsuPtr->GenFifoCS;
1435         GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI;
1436         GenFifoEntry |= (u32)FlashMsg->PollStatusCmd;
1437
1438         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress,
1439                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1440         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
1441                                 (XQSPIPSU_CFG_START_GEN_FIFO_MASK
1442                                 | XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK));
1443
1444         GenFifoEntry = (u32)0;
1445         GenFifoEntry = (u32)XQSPIPSU_GENFIFO_POLL;
1446         GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_RX;
1447         GenFifoEntry |= QspiPsuPtr->GenFifoBus;
1448         GenFifoEntry |= QspiPsuPtr->GenFifoCS;
1449         GenFifoEntry |= (u32)XQSPIPSU_GENFIFO_MODE_SPI;
1450         if (((FlashMsg->Flags) & XQSPIPSU_MSG_FLAG_STRIPE) != FALSE)
1451                 GenFifoEntry |= XQSPIPSU_GENFIFO_STRIPE;
1452         else
1453                 GenFifoEntry &= ~XQSPIPSU_GENFIFO_STRIPE;
1454
1455         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress,
1456                 XQSPIPSU_GEN_FIFO_OFFSET, GenFifoEntry);
1457
1458         QspiPsuPtr->Msg = FlashMsg;
1459         QspiPsuPtr->NumMsg = (s32)1;
1460         QspiPsuPtr->MsgCnt = 0;
1461
1462         Value = XQspiPsu_ReadReg(QspiPsuPtr->Config.BaseAddress,
1463                         XQSPIPSU_CFG_OFFSET);
1464         Value |= (XQSPIPSU_CFG_START_GEN_FIFO_MASK |
1465                         XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK |
1466                         XQSPIPSU_CFG_EN_POLL_TO_MASK);
1467         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
1468                         Value);
1469
1470         /* Enable interrupts */
1471         Value = ((u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
1472                 (u32)XQSPIPSU_IER_TXEMPTY_MASK |
1473                 (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
1474                 (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
1475                 (u32)XQSPIPSU_IER_RXEMPTY_MASK |
1476                 (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK);
1477         XQspiPsu_WriteReg(QspiPsuPtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET,
1478                         Value);
1479 }
1480
1481 /*****************************************************************************/
1482 /**
1483 *
1484 * This function creates Poll config register data to write
1485 *
1486 * @param        BusMask is mask to enable/disable upper/lower data bus masks.
1487 *
1488 * @param        DataBusMask is Data bus mask value during poll operation.
1489 *
1490 * @param        Data is the poll data value to write into config regsiter.
1491 *
1492 * @return       None
1493 *
1494 * @note         None.
1495 *
1496 ******************************************************************************/
1497 static inline u32 XQspiPsu_Create_PollConfigData(XQspiPsu *QspiPsuPtr,
1498                 XQspiPsu_Msg *FlashMsg)
1499 {
1500         u32 ConfigData = 0;
1501
1502         if (QspiPsuPtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_UPPER)
1503                 ConfigData = XQSPIPSU_SELECT_FLASH_BUS_LOWER <<
1504                                    XQSPIPSU_POLL_CFG_EN_MASK_UPPER_SHIFT;
1505         if (QspiPsuPtr->GenFifoBus & XQSPIPSU_GENFIFO_BUS_LOWER)
1506                 ConfigData |= XQSPIPSU_SELECT_FLASH_BUS_LOWER <<
1507                                    XQSPIPSU_POLL_CFG_EN_MASK_LOWER_SHIFT;
1508         ConfigData |= ((FlashMsg->PollBusMask << XQSPIPSU_POLL_CFG_MASK_EN_SHIFT)
1509                         & XQSPIPSU_POLL_CFG_MASK_EN_MASK);
1510         ConfigData |= ((FlashMsg->PollData << XQSPIPSU_POLL_CFG_DATA_VALUE_SHIFT)
1511                           & XQSPIPSU_POLL_CFG_DATA_VALUE_MASK);
1512         return ConfigData;
1513 }
1514 /** @} */