]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/qspips_v3_3/src/xqspips.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 / qspips_v3_3 / src / xqspips.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 xqspips.c
36 * @addtogroup qspips_v3_2
37 * @{
38 *
39 * Contains implements the interface functions of the XQspiPs driver.
40 * See xqspips.h for a detailed description of the device and driver.
41 *
42 * <pre>
43 * MODIFICATION HISTORY:
44 *
45 * Ver   Who Date     Changes
46 * ----- --- -------- -----------------------------------------------
47 * 1.00  sdm 11/25/10 First release
48 * 2.00a kka 07/25/12 Removed XQspiPs_GetWriteData API.
49 *                    The XQspiPs_SetSlaveSelect has been modified to remove
50 *                    the argument of the slave select as the QSPI controller
51 *                    only supports one slave.
52 *                    XQspiPs_GetSlaveSelect API has been removed
53 *                    Added logic to XQspiPs_GetReadData to handle data
54 *                    shift for normal data reads and instruction/status
55 *                    reads differently based on the ShiftReadData flag.
56 *                    Removed the selection for the following options:
57 *                    Master mode (XQSPIPS_MASTER_OPTION) and
58 *                    Flash interface mode (XQSPIPS_FLASH_MODE_OPTION) option
59 *                    as the QSPI driver supports the Master mode
60 *                    and Flash Interface mode and doesnot support
61 *                    Slave mode or the legacy mode.
62 *                    Modified the XQspiPs_PolledTransfer and XQspiPs_Transfer
63 *                    APIs so that the last argument (IsInst) specifying whether
64 *                    it is instruction or data has been removed. The first byte
65 *                    in the SendBufPtr argument of these APIs specify the
66 *                    instruction to be sent to the Flash Device.
67 *                    The XQspiPs_PolledTransfer function has been updated
68 *                    to fill the data to fifo depth.
69 *                    This version of the driver fixes CRs 670197/663787.
70 * 2.01a sg  02/03/13 Added flash opcodes for DUAL_IO_READ,QUAD_IO_READ.
71 *                    Created macros XQspiPs_IsManualStart and
72 *                    XQspiPs_IsManualChipSelect.
73 *                    Changed QSPI transfer logic for polled and interrupt
74 *                    modes to be based on filled tx fifo count and receive
75 *                    based on it. RXNEMPTY interrupt is not used.
76 *                    Added assertions to XQspiPs_LqspiRead function.
77 *
78 * 2.02a hk  05/14/13 Added enable and disable to the XQspiPs_LqspiRead()
79 *                        function
80 *            Added instructions for bank selection, die erase and
81 *            flag status register to the flash instruction table
82 *            Handling for instructions not in flash instruction
83 *                        table added. Checking for Tx FIFO empty when switching from
84 *                        TXD1/2/3 to TXD0 added. If WRSR instruction is sent with
85 *            byte count 3 (spansion), instruction size and TXD register
86 *                        changed accordingly. CR# 712502 and 703869.
87 *            Added (#ifdef linear base address) in the Linear read function.
88 *            Changed  XPAR_XQSPIPS_0_LINEAR_BASEADDR to
89 *            XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR in
90 *            XQspiPs_LqspiRead function. Fix for CR#718141
91 *
92 * 2.03a hk  09/05/13 Modified polled and interrupt transfers to make use of
93 *                    thresholds. This is to improve performance.
94 *                    Added RX and TX threshold reset to one in XQspiPs_Abort.
95 *                    Added RX threshold reset(1) after transfer in polled and
96 *                    interrupt transfers. Made changes to make sure threshold
97 *                    change is done only when no transfer is in progress.
98 * 3.1   hk  08/13/14 When writing to the configuration register, set/reset
99 *                    required bits leaving reserved bits untouched. CR# 796813.
100 * 3.2   sk      02/05/15 Add SLCR reset in abort function as a workaround because
101 *                                        controller does not update FIFO status flags as expected
102 *                                        when thresholds are used.
103 * 3.3   sk  11/07/15 Modified the API prototypes according to MISRAC standards
104 *                    to remove compilation warnings. CR# 868893.
105 *
106 * </pre>
107 *
108 ******************************************************************************/
109
110 /***************************** Include Files *********************************/
111
112 #include "xqspips.h"
113
114 /************************** Constant Definitions *****************************/
115
116
117 /**************************** Type Definitions *******************************/
118
119 /**
120  * This typedef defines qspi flash instruction format
121  */
122 typedef struct {
123         u8 OpCode;      /**< Operational code of the instruction */
124         u8 InstSize;    /**< Size of the instruction including address bytes */
125         u8 TxOffset;    /**< Register address where instruction has to be
126                              written */
127 } XQspiPsInstFormat;
128
129 /***************** Macros (Inline Functions) Definitions *********************/
130
131 #define ARRAY_SIZE(Array)               (sizeof(Array) / sizeof((Array)[0]))
132
133 /************************** Function Prototypes ******************************/
134 static void XQspiPs_GetReadData(XQspiPs *InstancePtr, u32 Data, u8 Size);
135 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
136                                 unsigned ByteCount);
137
138 /************************** Variable Definitions *****************************/
139
140 /*
141  * List of all the QSPI instructions and its format
142  */
143 static XQspiPsInstFormat FlashInst[] = {
144         { XQSPIPS_FLASH_OPCODE_WREN, 1, XQSPIPS_TXD_01_OFFSET },
145         { XQSPIPS_FLASH_OPCODE_WRDS, 1, XQSPIPS_TXD_01_OFFSET },
146         { XQSPIPS_FLASH_OPCODE_RDSR1, 2, XQSPIPS_TXD_10_OFFSET },
147         { XQSPIPS_FLASH_OPCODE_RDSR2, 2, XQSPIPS_TXD_10_OFFSET },
148         { XQSPIPS_FLASH_OPCODE_WRSR, 2, XQSPIPS_TXD_10_OFFSET },
149         { XQSPIPS_FLASH_OPCODE_PP, 4, XQSPIPS_TXD_00_OFFSET },
150         { XQSPIPS_FLASH_OPCODE_SE, 4, XQSPIPS_TXD_00_OFFSET },
151         { XQSPIPS_FLASH_OPCODE_BE_32K, 4, XQSPIPS_TXD_00_OFFSET },
152         { XQSPIPS_FLASH_OPCODE_BE_4K, 4, XQSPIPS_TXD_00_OFFSET },
153         { XQSPIPS_FLASH_OPCODE_BE, 1, XQSPIPS_TXD_01_OFFSET },
154         { XQSPIPS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPS_TXD_01_OFFSET },
155         { XQSPIPS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPS_TXD_01_OFFSET },
156         { XQSPIPS_FLASH_OPCODE_RDID, 4, XQSPIPS_TXD_00_OFFSET },
157         { XQSPIPS_FLASH_OPCODE_NORM_READ, 4, XQSPIPS_TXD_00_OFFSET },
158         { XQSPIPS_FLASH_OPCODE_FAST_READ, 4, XQSPIPS_TXD_00_OFFSET },
159         { XQSPIPS_FLASH_OPCODE_DUAL_READ, 4, XQSPIPS_TXD_00_OFFSET },
160         { XQSPIPS_FLASH_OPCODE_QUAD_READ, 4, XQSPIPS_TXD_00_OFFSET },
161         { XQSPIPS_FLASH_OPCODE_DUAL_IO_READ, 4, XQSPIPS_TXD_00_OFFSET },
162         { XQSPIPS_FLASH_OPCODE_QUAD_IO_READ, 4, XQSPIPS_TXD_00_OFFSET },
163         { XQSPIPS_FLASH_OPCODE_BRWR, 2, XQSPIPS_TXD_10_OFFSET },
164         { XQSPIPS_FLASH_OPCODE_BRRD, 2, XQSPIPS_TXD_10_OFFSET },
165         { XQSPIPS_FLASH_OPCODE_EARWR, 2, XQSPIPS_TXD_10_OFFSET },
166         { XQSPIPS_FLASH_OPCODE_EARRD, 2, XQSPIPS_TXD_10_OFFSET },
167         { XQSPIPS_FLASH_OPCODE_DIE_ERASE, 4, XQSPIPS_TXD_00_OFFSET },
168         { XQSPIPS_FLASH_OPCODE_READ_FLAG_SR, 2, XQSPIPS_TXD_10_OFFSET },
169         { XQSPIPS_FLASH_OPCODE_CLEAR_FLAG_SR, 1, XQSPIPS_TXD_01_OFFSET },
170         /* Add all the instructions supported by the flash device */
171 };
172
173 /*****************************************************************************/
174 /**
175 *
176 * Initializes a specific XQspiPs instance such that the driver is ready to use.
177 *
178 * The state of the device after initialization is:
179 *   - Master mode
180 *   - Active high clock polarity
181 *   - Clock phase 0
182 *   - Baud rate divisor 2
183 *   - Transfer width 32
184 *   - Master reference clock = pclk
185 *   - No chip select active
186 *   - Manual CS and Manual Start disabled
187 *
188 * @param        InstancePtr is a pointer to the XQspiPs instance.
189 * @param        ConfigPtr is a reference to a structure containing information
190 *               about a specific QSPI device. This function initializes an
191 *               InstancePtr object for a specific device specified by the
192 *               contents of Config.
193 * @param        EffectiveAddr is the device base address in the virtual memory
194 *               address space. The caller is responsible for keeping the address
195 *               mapping from EffectiveAddr to the device physical base address
196 *               unchanged once this function is invoked. Unexpected errors may
197 *               occur if the address mapping changes after this function is
198 *               called. If address translation is not used, use
199 *               ConfigPtr->Config.BaseAddress for this device.
200 *
201 * @return
202 *               - XST_SUCCESS if successful.
203 *               - XST_DEVICE_IS_STARTED if the device is already started.
204 *               It must be stopped to re-initialize.
205 *
206 * @note         None.
207 *
208 ******************************************************************************/
209 int XQspiPs_CfgInitialize(XQspiPs *InstancePtr, XQspiPs_Config *ConfigPtr,
210                                 u32 EffectiveAddr)
211 {
212         Xil_AssertNonvoid(InstancePtr != NULL);
213         Xil_AssertNonvoid(ConfigPtr != NULL);
214
215         /*
216          * If the device is busy, disallow the initialize and return a status
217          * indicating it is already started. This allows the user to stop the
218          * device and re-initialize, but prevents a user from inadvertently
219          * initializing. This assumes the busy flag is cleared at startup.
220          */
221         if (InstancePtr->IsBusy == TRUE) {
222                 return XST_DEVICE_IS_STARTED;
223         }
224
225         /*
226          * Set some default values.
227          */
228         InstancePtr->IsBusy = FALSE;
229
230         InstancePtr->Config.BaseAddress = EffectiveAddr;
231         InstancePtr->StatusHandler = StubStatusHandler;
232
233         InstancePtr->SendBufferPtr = NULL;
234         InstancePtr->RecvBufferPtr = NULL;
235         InstancePtr->RequestedBytes = 0;
236         InstancePtr->RemainingBytes = 0;
237         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
238
239         InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode;
240
241         /*
242          * Reset the QSPI device to get it into its initial state. It is
243          * expected that device configuration will take place after this
244          * initialization is done, but before the device is started.
245          */
246         XQspiPs_Reset(InstancePtr);
247
248         return XST_SUCCESS;
249 }
250
251 /*****************************************************************************/
252 /**
253 *
254 * Resets the QSPI device. Reset must only be called after the driver has been
255 * initialized. Any data transfer that is in progress is aborted.
256 *
257 * The upper layer software is responsible for re-configuring (if necessary)
258 * and restarting the QSPI device after the reset.
259 *
260 * @param        InstancePtr is a pointer to the XQspiPs instance.
261 *
262 * @return       None.
263 *
264 * @note         None.
265 *
266 ******************************************************************************/
267 void XQspiPs_Reset(XQspiPs *InstancePtr)
268 {
269         u32 ConfigReg;
270
271         Xil_AssertVoid(InstancePtr != NULL);
272         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
273
274         /*
275          * Abort any transfer that is in progress
276          */
277         XQspiPs_Abort(InstancePtr);
278
279         /*
280          * Write default value to configuration register.
281          * Do not modify reserved bits.
282          */
283         ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
284                          XQSPIPS_CR_OFFSET);
285         ConfigReg |= XQSPIPS_CR_RESET_MASK_SET;
286         ConfigReg &= ~XQSPIPS_CR_RESET_MASK_CLR;
287         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_CR_OFFSET,
288                           ConfigReg);
289 }
290
291 /*****************************************************************************/
292 /**
293 *
294 * Aborts a transfer in progress by disabling the device and flush the RxFIFO.
295 * The byte counts are cleared, the busy flag is cleared.
296 *
297 * @param        InstancePtr is a pointer to the XQspiPs instance.
298 *
299 * @return       None.
300 *
301 * @note
302 *
303 * This function does a read/modify/write of the config register. The user of
304 * this function needs to take care of critical sections.
305 *
306 ******************************************************************************/
307 void XQspiPs_Abort(XQspiPs *InstancePtr)
308 {
309         u32 ConfigReg;
310         u32 IsLock;
311
312         XQspiPs_Disable(InstancePtr);
313
314         /*
315          * De-assert slave select lines.
316          */
317         ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
318                          XQSPIPS_CR_OFFSET);
319         ConfigReg |= (XQSPIPS_CR_SSCTRL_MASK | XQSPIPS_CR_SSFORCE_MASK);
320         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
321                          XQSPIPS_CR_OFFSET, ConfigReg);
322
323         /*
324          * QSPI Software Reset
325          */
326         IsLock = XQspiPs_ReadReg(XPAR_XSLCR_0_BASEADDR, SLCR_LOCKSTA);
327         if (IsLock) {
328                 XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, SLCR_UNLOCK,
329                                 SLCR_UNLOCK_MASK);
330         }
331         XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, LQSPI_RST_CTRL,
332                         LQSPI_RST_CTRL_MASK);
333         XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, LQSPI_RST_CTRL, 0x0);
334         if (IsLock) {
335                 XQspiPs_WriteReg(XPAR_XSLCR_0_BASEADDR, SLCR_LOCK,
336                                 SLCR_LOCK_MASK);
337         }
338
339         /*
340          * Set the RX and TX FIFO threshold to reset value (one)
341          */
342         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
343                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE);
344
345         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
346                         XQSPIPS_TXWR_OFFSET, XQSPIPS_TXWR_RESET_VALUE);
347
348         InstancePtr->RemainingBytes = 0;
349         InstancePtr->RequestedBytes = 0;
350         InstancePtr->IsBusy = FALSE;
351 }
352
353 /*****************************************************************************/
354 /**
355 *
356 * Transfers specified data on the QSPI bus. Initiates bus communication and
357 * sends/receives data to/from the selected QSPI slave. For every byte sent,
358 * a byte is received.
359 *
360 * The caller has the option of providing two different buffers for send and
361 * receive, or one buffer for both send and receive, or no buffer for receive.
362 * The receive buffer must be at least as big as the send buffer to prevent
363 * unwanted memory writes. This implies that the byte count passed in as an
364 * argument must be the smaller of the two buffers if they differ in size.
365 * Here are some sample usages:
366 * <pre>
367 *   XQspiPs_Transfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
368 *       The caller wishes to send and receive, and provides two different
369 *       buffers for send and receive.
370 *
371 *   XQspiPs_Transfer(InstancePtr, SendBuf, NULL, ByteCount)
372 *       The caller wishes only to send and does not care about the received
373 *       data. The driver ignores the received data in this case.
374 *
375 *   XQspiPs_Transfer(InstancePtr, SendBuf, SendBuf, ByteCount)
376 *       The caller wishes to send and receive, but provides the same buffer
377 *       for doing both. The driver sends the data and overwrites the send
378 *       buffer with received data as it transfers the data.
379 *
380 *   XQspiPs_Transfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
381 *       The caller wishes to only receive and does not care about sending
382 *       data.  In this case, the caller must still provide a send buffer, but
383 *       it can be the same as the receive buffer if the caller does not care
384 *       what it sends.  The device must send N bytes of data if it wishes to
385 *       receive N bytes of data.
386 * </pre>
387 * Although this function takes entire buffers as arguments, the driver can only
388 * transfer a limited number of bytes at a time, limited by the size of the
389 * FIFO. A call to this function only starts the transfer, then subsequent
390 * transfers of the data is performed by the interrupt service routine until
391 * the entire buffer has been transferred. The status callback function is
392 * called when the entire buffer has been sent/received.
393 *
394 * This function is non-blocking. The SetSlaveSelect function must be called
395 * prior to this function.
396 *
397 * @param        InstancePtr is a pointer to the XQspiPs instance.
398 * @param        SendBufPtr is a pointer to a data buffer that needs to be
399 *               transmitted. This buffer must not be NULL.
400 * @param        RecvBufPtr is a pointer to a buffer for received data.
401 *               This argument can be NULL if do not care about receiving.
402 * @param        ByteCount contains the number of bytes to send/receive.
403 *               The number of bytes received always equals the number of bytes
404 *               sent.
405 *
406 * @return
407 *               - XST_SUCCESS if the buffers are successfully handed off to the
408 *                 device for transfer.
409 *               - XST_DEVICE_BUSY indicates that a data transfer is already in
410 *                 progress. This is determined by the driver.
411 *
412 * @note
413 *
414 * This function is not thread-safe.  The higher layer software must ensure that
415 * no two threads are transferring data on the QSPI bus at the same time.
416 *
417 ******************************************************************************/
418 s32 XQspiPs_Transfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr,
419                         u32 ByteCount)
420 {
421         u32 StatusReg;
422         u32 ConfigReg;
423         u8 Instruction;
424         u32 Data;
425         unsigned int Index;
426         u8 TransCount = 0;
427         XQspiPsInstFormat *CurrInst;
428         XQspiPsInstFormat NewInst[2];
429         u8 SwitchFlag  = 0;
430
431         CurrInst = &NewInst[0];
432
433         /*
434          * The RecvBufPtr argument can be null
435          */
436         Xil_AssertNonvoid(InstancePtr != NULL);
437         Xil_AssertNonvoid(SendBufPtr != NULL);
438         Xil_AssertNonvoid(ByteCount > 0);
439         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
440
441         /*
442          * Check whether there is another transfer in progress. Not thread-safe.
443          */
444         if (InstancePtr->IsBusy) {
445                 return XST_DEVICE_BUSY;
446         }
447
448         /*
449          * Set the busy flag, which will be cleared in the ISR when the
450          * transfer is entirely done.
451          */
452         InstancePtr->IsBusy = TRUE;
453
454         /*
455          * Set up buffer pointers.
456          */
457         InstancePtr->SendBufferPtr = SendBufPtr;
458         InstancePtr->RecvBufferPtr = RecvBufPtr;
459
460         InstancePtr->RequestedBytes = ByteCount;
461         InstancePtr->RemainingBytes = ByteCount;
462
463         /*
464          * The first byte with every chip-select assertion is always
465          * expected to be an instruction for flash interface mode
466          */
467         Instruction = *InstancePtr->SendBufferPtr;
468
469         for (Index = 0 ; Index < ARRAY_SIZE(FlashInst); Index++) {
470                 if (Instruction == FlashInst[Index].OpCode) {
471                         break;
472                 }
473         }
474
475         /*
476          * Set the RX FIFO threshold
477          */
478         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
479                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXFIFO_THRESHOLD_OPT);
480
481         /*
482          * If the slave select is "Forced" or under manual control,
483          * set the slave select now, before beginning the transfer.
484          */
485         if (XQspiPs_IsManualChipSelect(InstancePtr)) {
486                 ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
487                                  XQSPIPS_CR_OFFSET);
488                 ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK;
489                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
490                                   XQSPIPS_CR_OFFSET,
491                                   ConfigReg);
492         }
493
494         /*
495          * Enable the device.
496          */
497         XQspiPs_Enable(InstancePtr);
498
499         /*
500          * Clear all the interrrupts.
501          */
502         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPS_SR_OFFSET,
503                         XQSPIPS_IXR_WR_TO_CLR_MASK);
504
505         if (Index < ARRAY_SIZE(FlashInst)) {
506                 CurrInst = &FlashInst[Index];
507                 /*
508                  * Check for WRSR instruction which has different size for
509                  * Spansion (3 bytes) and Micron (2 bytes)
510                  */
511                 if( (CurrInst->OpCode == XQSPIPS_FLASH_OPCODE_WRSR) &&
512                         (ByteCount == 3) ) {
513                         CurrInst->InstSize = 3;
514                         CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET;
515                 }
516         }
517
518         /*
519          * If instruction not present in table
520          */
521         if (Index == ARRAY_SIZE(FlashInst)) {
522                 /*
523                  * Assign current instruction, size and TXD register to be used
524                  * The InstSize mentioned in case of instructions greater than
525                  * 4 bytes is not the actual size, but is indicative of
526                  * the TXD register used.
527                  * The remaining bytes of the instruction will be transmitted
528                  * through TXD0 below.
529                  */
530                 switch(ByteCount%4)
531                 {
532                         case XQSPIPS_SIZE_ONE:
533                                 CurrInst->OpCode = Instruction;
534                                 CurrInst->InstSize = XQSPIPS_SIZE_ONE;
535                                 CurrInst->TxOffset = XQSPIPS_TXD_01_OFFSET;
536                                 if(ByteCount > 4) {
537                                         SwitchFlag = 1;
538                                 }
539                                 break;
540                         case XQSPIPS_SIZE_TWO:
541                                 CurrInst->OpCode = Instruction;
542                                 CurrInst->InstSize = XQSPIPS_SIZE_TWO;
543                                 CurrInst->TxOffset = XQSPIPS_TXD_10_OFFSET;
544                                 if(ByteCount > 4) {
545                                         SwitchFlag = 1;
546                                 }
547                                 break;
548                         case XQSPIPS_SIZE_THREE:
549                                 CurrInst->OpCode = Instruction;
550                                 CurrInst->InstSize = XQSPIPS_SIZE_THREE;
551                                 CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET;
552                                 if(ByteCount > 4) {
553                                         SwitchFlag = 1;
554                                 }
555                                 break;
556                         default:
557                                 CurrInst->OpCode = Instruction;
558                                 CurrInst->InstSize = XQSPIPS_SIZE_FOUR;
559                                 CurrInst->TxOffset = XQSPIPS_TXD_00_OFFSET;
560                                 break;
561                 }
562         }
563
564         /*
565          * If the instruction size in not 4 bytes then the data received needs
566          * to be shifted
567          */
568         if( CurrInst->InstSize != 4 ) {
569                 InstancePtr->ShiftReadData = 1;
570         } else {
571                 InstancePtr->ShiftReadData = 0;
572         }
573
574         /* Get the complete command (flash inst + address/data) */
575         Data = *((u32 *)InstancePtr->SendBufferPtr);
576         InstancePtr->SendBufferPtr += CurrInst->InstSize;
577         InstancePtr->RemainingBytes -= CurrInst->InstSize;
578         if (InstancePtr->RemainingBytes < 0) {
579                 InstancePtr->RemainingBytes = 0;
580         }
581
582         /* Write the command to the FIFO */
583         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
584                          CurrInst->TxOffset, Data);
585         TransCount++;
586
587         /*
588          * If switching from TXD1/2/3 to TXD0, then start transfer and
589          * check for FIFO empty
590          */
591         if(SwitchFlag == 1) {
592                 SwitchFlag = 0;
593                 /*
594                  * If, in Manual Start mode, start the transfer.
595                  */
596                 if (XQspiPs_IsManualStart(InstancePtr)) {
597                         ConfigReg = XQspiPs_ReadReg(
598                                         InstancePtr->Config.BaseAddress,
599                                          XQSPIPS_CR_OFFSET);
600                         ConfigReg |= XQSPIPS_CR_MANSTRT_MASK;
601                         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
602                                          XQSPIPS_CR_OFFSET, ConfigReg);
603                 }
604                 /*
605                  * Wait for the transfer to finish by polling Tx fifo status.
606                  */
607                 do {
608                         StatusReg = XQspiPs_ReadReg(
609                                         InstancePtr->Config.BaseAddress,
610                                         XQSPIPS_SR_OFFSET);
611                 } while ((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0);
612
613         }
614
615         /*
616          * Fill the Tx FIFO with as many bytes as it takes (or as many as
617          * we have to send).
618          */
619         while ((InstancePtr->RemainingBytes > 0) &&
620                 (TransCount < XQSPIPS_FIFO_DEPTH)) {
621                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
622                                   XQSPIPS_TXD_00_OFFSET,
623                                   *((u32 *)InstancePtr->SendBufferPtr));
624                 InstancePtr->SendBufferPtr += 4;
625                 InstancePtr->RemainingBytes -= 4;
626                 if (InstancePtr->RemainingBytes < 0) {
627                         InstancePtr->RemainingBytes = 0;
628                 }
629                 TransCount++;
630         }
631
632         /*
633          * Enable QSPI interrupts (connecting to the interrupt controller and
634          * enabling interrupts should have been done by the caller).
635          */
636         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
637                           XQSPIPS_IER_OFFSET, XQSPIPS_IXR_RXNEMPTY_MASK |
638                           XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_RXOVR_MASK |
639                           XQSPIPS_IXR_TXUF_MASK);
640
641         /*
642          * If, in Manual Start mode, Start the transfer.
643          */
644         if (XQspiPs_IsManualStart(InstancePtr)) {
645                 ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
646                                 XQSPIPS_CR_OFFSET);
647                 ConfigReg |= XQSPIPS_CR_MANSTRT_MASK;
648                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
649                                   XQSPIPS_CR_OFFSET, ConfigReg);
650         }
651
652         return XST_SUCCESS;
653 }
654
655 /*****************************************************************************/
656 /**
657 * Transfers specified data on the QSPI bus in polled mode.
658 *
659 * The caller has the option of providing two different buffers for send and
660 * receive, or one buffer for both send and receive, or no buffer for receive.
661 * The receive buffer must be at least as big as the send buffer to prevent
662 * unwanted memory writes. This implies that the byte count passed in as an
663 * argument must be the smaller of the two buffers if they differ in size.
664 * Here are some sample usages:
665 * <pre>
666 *   XQspiPs_PolledTransfer(InstancePtr, SendBuf, RecvBuf, ByteCount)
667 *       The caller wishes to send and receive, and provides two different
668 *       buffers for send and receive.
669 *
670 *   XQspiPs_PolledTransfer(InstancePtr, SendBuf, NULL, ByteCount)
671 *       The caller wishes only to send and does not care about the received
672 *       data. The driver ignores the received data in this case.
673 *
674 *   XQspiPs_PolledTransfer(InstancePtr, SendBuf, SendBuf, ByteCount)
675 *       The caller wishes to send and receive, but provides the same buffer
676 *       for doing both. The driver sends the data and overwrites the send
677 *       buffer with received data as it transfers the data.
678 *
679 *   XQspiPs_PolledTransfer(InstancePtr, RecvBuf, RecvBuf, ByteCount)
680 *       The caller wishes to only receive and does not care about sending
681 *       data.  In this case, the caller must still provide a send buffer, but
682 *       it can be the same as the receive buffer if the caller does not care
683 *       what it sends.  The device must send N bytes of data if it wishes to
684 *       receive N bytes of data.
685 *
686 * </pre>
687 *
688 * @param        InstancePtr is a pointer to the XQspiPs instance.
689 * @param        SendBufPtr is a pointer to a data buffer that needs to be
690 *               transmitted. This buffer must not be NULL.
691 * @param        RecvBufPtr is a pointer to a buffer for received data.
692 *               This argument can be NULL if do not care about receiving.
693 * @param        ByteCount contains the number of bytes to send/receive.
694 *               The number of bytes received always equals the number of bytes
695 *               sent.
696 * @return
697 *               - XST_SUCCESS if the buffers are successfully handed off to the
698 *                 device for transfer.
699 *               - XST_DEVICE_BUSY indicates that a data transfer is already in
700 *                 progress. This is determined by the driver.
701 *
702 * @note
703 *
704 * This function is not thread-safe.  The higher layer software must ensure that
705 * no two threads are transferring data on the QSPI bus at the same time.
706 *
707 ******************************************************************************/
708 s32 XQspiPs_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr,
709                             u8 *RecvBufPtr, u32 ByteCount)
710 {
711         u32 StatusReg;
712         u32 ConfigReg;
713         u8 Instruction;
714         u32 Data;
715         u8 TransCount;
716         unsigned int Index;
717         XQspiPsInstFormat *CurrInst;
718         XQspiPsInstFormat NewInst[2];
719         u8 SwitchFlag  = 0;
720         u8 IsManualStart = FALSE;
721         u32 RxCount = 0;
722
723         CurrInst = &NewInst[0];
724         /*
725          * The RecvBufPtr argument can be NULL.
726          */
727         Xil_AssertNonvoid(InstancePtr != NULL);
728         Xil_AssertNonvoid(SendBufPtr != NULL);
729         Xil_AssertNonvoid(ByteCount > 0);
730         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
731
732         /*
733          * Check whether there is another transfer in progress. Not thread-safe.
734          */
735         if (InstancePtr->IsBusy) {
736                 return XST_DEVICE_BUSY;
737         }
738
739         /*
740          * Set the busy flag, which will be cleared when the transfer is
741          * entirely done.
742          */
743         InstancePtr->IsBusy = TRUE;
744
745         /*
746          * Set up buffer pointers.
747          */
748         InstancePtr->SendBufferPtr = SendBufPtr;
749         InstancePtr->RecvBufferPtr = RecvBufPtr;
750
751         InstancePtr->RequestedBytes = ByteCount;
752         InstancePtr->RemainingBytes = ByteCount;
753
754         /*
755          * The first byte with every chip-select assertion is always
756          * expected to be an instruction for flash interface mode
757          */
758         Instruction = *InstancePtr->SendBufferPtr;
759
760         for (Index = 0 ; Index < ARRAY_SIZE(FlashInst); Index++) {
761                 if (Instruction == FlashInst[Index].OpCode) {
762                         break;
763                 }
764         }
765
766         /*
767          * Set the RX FIFO threshold
768          */
769         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
770                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXFIFO_THRESHOLD_OPT);
771
772         /*
773          * If the slave select is "Forced" or under manual control,
774          * set the slave select now, before beginning the transfer.
775          */
776         if (XQspiPs_IsManualChipSelect(InstancePtr)) {
777                 ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
778                                  XQSPIPS_CR_OFFSET);
779                 ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK;
780                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
781                                   XQSPIPS_CR_OFFSET,
782                                   ConfigReg);
783         }
784
785         /*
786          * Enable the device.
787          */
788         XQspiPs_Enable(InstancePtr);
789
790         if (Index < ARRAY_SIZE(FlashInst)) {
791
792                 CurrInst = &FlashInst[Index];
793                 /*
794                  * Check for WRSR instruction which has different size for
795                  * Spansion (3 bytes) and Micron (2 bytes)
796                  */
797                 if( (CurrInst->OpCode == XQSPIPS_FLASH_OPCODE_WRSR) &&
798                         (ByteCount == 3) ) {
799                         CurrInst->InstSize = 3;
800                         CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET;
801                 }
802         }
803
804         /*
805          * If instruction not present in table
806          */
807         if (Index == ARRAY_SIZE(FlashInst)) {
808                 /*
809                  * Assign current instruction, size and TXD register to be used.
810                  * The InstSize mentioned in case of instructions greater than 4 bytes
811                  * is not the actual size, but is indicative of the TXD register used.
812                  * The remaining bytes of the instruction will be transmitted
813                  * through TXD0 below.
814                  */
815                 switch(ByteCount%4)
816                 {
817                         case XQSPIPS_SIZE_ONE:
818                                 CurrInst->OpCode = Instruction;
819                                 CurrInst->InstSize = XQSPIPS_SIZE_ONE;
820                                 CurrInst->TxOffset = XQSPIPS_TXD_01_OFFSET;
821                                 if(ByteCount > 4) {
822                                         SwitchFlag = 1;
823                                 }
824                                 break;
825                         case XQSPIPS_SIZE_TWO:
826                                 CurrInst->OpCode = Instruction;
827                                 CurrInst->InstSize = XQSPIPS_SIZE_TWO;
828                                 CurrInst->TxOffset = XQSPIPS_TXD_10_OFFSET;
829                                 if(ByteCount > 4) {
830                                         SwitchFlag = 1;
831                                 }
832                                 break;
833                         case XQSPIPS_SIZE_THREE:
834                                 CurrInst->OpCode = Instruction;
835                                 CurrInst->InstSize = XQSPIPS_SIZE_THREE;
836                                 CurrInst->TxOffset = XQSPIPS_TXD_11_OFFSET;
837                                 if(ByteCount > 4) {
838                                         SwitchFlag = 1;
839                                 }
840                                 break;
841                         default:
842                                 CurrInst->OpCode = Instruction;
843                                 CurrInst->InstSize = XQSPIPS_SIZE_FOUR;
844                                 CurrInst->TxOffset = XQSPIPS_TXD_00_OFFSET;
845                                 break;
846                 }
847         }
848
849         /*
850          * If the instruction size in not 4 bytes then the data received needs
851          * to be shifted
852          */
853         if( CurrInst->InstSize != 4 ) {
854                 InstancePtr->ShiftReadData = 1;
855         } else {
856                 InstancePtr->ShiftReadData = 0;
857         }
858         TransCount = 0;
859         /* Get the complete command (flash inst + address/data) */
860         Data = *((u32 *)InstancePtr->SendBufferPtr);
861         InstancePtr->SendBufferPtr += CurrInst->InstSize;
862         InstancePtr->RemainingBytes -= CurrInst->InstSize;
863         if (InstancePtr->RemainingBytes < 0) {
864                 InstancePtr->RemainingBytes = 0;
865         }
866
867         /* Write the command to the FIFO */
868         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
869                                         CurrInst->TxOffset, Data);
870         ++TransCount;
871
872         /*
873          * If switching from TXD1/2/3 to TXD0, then start transfer and
874          * check for FIFO empty
875          */
876         if(SwitchFlag == 1) {
877                 SwitchFlag = 0;
878                 /*
879                  * If, in Manual Start mode, start the transfer.
880                  */
881                 if (XQspiPs_IsManualStart(InstancePtr)) {
882                         ConfigReg = XQspiPs_ReadReg(
883                                         InstancePtr->Config.BaseAddress,
884                                          XQSPIPS_CR_OFFSET);
885                         ConfigReg |= XQSPIPS_CR_MANSTRT_MASK;
886                         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
887                                          XQSPIPS_CR_OFFSET, ConfigReg);
888                 }
889                 /*
890                  * Wait for the transfer to finish by polling Tx fifo status.
891                  */
892                 do {
893                         StatusReg = XQspiPs_ReadReg(
894                                         InstancePtr->Config.BaseAddress,
895                                         XQSPIPS_SR_OFFSET);
896                 } while ((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0);
897
898         }
899
900         /*
901          * Check if manual start is selected and store it in a
902          * local varibale for reference. This is to avoid reading
903          * the config register everytime.
904          */
905         IsManualStart = XQspiPs_IsManualStart(InstancePtr);
906
907         /*
908          * Fill the DTR/FIFO with as many bytes as it will take (or as
909          * many as we have to send).
910          */
911         while ((InstancePtr->RemainingBytes > 0) &&
912                 (TransCount < XQSPIPS_FIFO_DEPTH)) {
913                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
914                                  XQSPIPS_TXD_00_OFFSET,
915                                  *((u32 *)InstancePtr->SendBufferPtr));
916                 InstancePtr->SendBufferPtr += 4;
917                 InstancePtr->RemainingBytes -= 4;
918                 if (InstancePtr->RemainingBytes < 0) {
919                         InstancePtr->RemainingBytes = 0;
920                 }
921                 ++TransCount;
922         }
923
924         while((InstancePtr->RemainingBytes > 0) ||
925               (InstancePtr->RequestedBytes > 0)) {
926
927                 /*
928                  * Fill the TX FIFO with RX threshold no. of entries (or as
929                  * many as we have to send, in case that's less).
930                  */
931                 while ((InstancePtr->RemainingBytes > 0) &&
932                         (TransCount < XQSPIPS_RXFIFO_THRESHOLD_OPT)) {
933                         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
934                                          XQSPIPS_TXD_00_OFFSET,
935                                          *((u32 *)InstancePtr->SendBufferPtr));
936                         InstancePtr->SendBufferPtr += 4;
937                         InstancePtr->RemainingBytes -= 4;
938                         if (InstancePtr->RemainingBytes < 0) {
939                                 InstancePtr->RemainingBytes = 0;
940                         }
941                         ++TransCount;
942                 }
943
944                 /*
945                  * If, in Manual Start mode, start the transfer.
946                  */
947                 if (IsManualStart == TRUE) {
948                         ConfigReg = XQspiPs_ReadReg(
949                                         InstancePtr->Config.BaseAddress,
950                                          XQSPIPS_CR_OFFSET);
951                         ConfigReg |= XQSPIPS_CR_MANSTRT_MASK;
952                         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
953                                          XQSPIPS_CR_OFFSET, ConfigReg);
954                 }
955
956                 /*
957                  * Reset TransCount - this is only used to fill TX FIFO
958                  * in the above loop;
959                  * RxCount is used to keep track of data received
960                  */
961                 TransCount = 0;
962
963                 /*
964                  * Wait for RX FIFO to reach threshold (or)
965                  * TX FIFO to become empty.
966                  * The latter check is required for
967                  * small transfers (<32 words) and
968                  * when the last chunk in a large data transfer is < 32 words.
969                  */
970
971                 do {
972                         StatusReg = XQspiPs_ReadReg(
973                                         InstancePtr->Config.BaseAddress,
974                                         XQSPIPS_SR_OFFSET);
975                 } while ( ((StatusReg & XQSPIPS_IXR_TXOW_MASK) == 0) &&
976                         ((StatusReg & XQSPIPS_IXR_RXNEMPTY_MASK) == 0) );
977
978                 /*
979                  * A transmit has just completed. Process received data
980                  * and check for more data to transmit.
981                  * First get the data received as a result of the
982                  * transmit that just completed. Receive data based on the
983                  * count obtained while filling tx fifo. Always get
984                  * the received data, but only fill the receive
985                  * buffer if it points to something (the upper layer
986                  * software may not care to receive data).
987                  */
988                 while ((InstancePtr->RequestedBytes > 0) &&
989                         (RxCount < XQSPIPS_RXFIFO_THRESHOLD_OPT )) {
990                         u32 Data;
991
992                         RxCount++;
993
994                         if (InstancePtr->RecvBufferPtr != NULL) {
995                                 if (InstancePtr->RequestedBytes < 4) {
996                                         Data = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
997                                                 XQSPIPS_RXD_OFFSET);
998                                         XQspiPs_GetReadData(InstancePtr, Data,
999                                                 InstancePtr->RequestedBytes);
1000                                 } else {
1001                                         (*(u32 *)InstancePtr->RecvBufferPtr) =
1002                                                 XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
1003                                                 XQSPIPS_RXD_OFFSET);
1004                                         InstancePtr->RecvBufferPtr += 4;
1005                                         InstancePtr->RequestedBytes -= 4;
1006                                         if (InstancePtr->RequestedBytes < 0) {
1007                                                 InstancePtr->RequestedBytes = 0;
1008                                         }
1009                                 }
1010                         } else {
1011                                 Data = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
1012                                                 XQSPIPS_RXD_OFFSET);
1013                                 InstancePtr->RequestedBytes -= 4;
1014                         }
1015                 }
1016                 RxCount = 0;
1017         }
1018
1019         /*
1020          * If the Slave select lines are being manually controlled, disable
1021          * them because the transfer is complete.
1022          */
1023         if (XQspiPs_IsManualChipSelect(InstancePtr)) {
1024                 ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
1025                                  XQSPIPS_CR_OFFSET);
1026                 ConfigReg |= XQSPIPS_CR_SSCTRL_MASK;
1027                 XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
1028                                   XQSPIPS_CR_OFFSET, ConfigReg);
1029         }
1030
1031         /*
1032          * Clear the busy flag.
1033          */
1034         InstancePtr->IsBusy = FALSE;
1035
1036         /*
1037          * Disable the device.
1038          */
1039         XQspiPs_Disable(InstancePtr);
1040
1041         /*
1042          * Reset the RX FIFO threshold to one
1043          */
1044         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
1045                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE);
1046
1047         return XST_SUCCESS;
1048 }
1049
1050 /*****************************************************************************/
1051 /**
1052 *
1053 * Read the flash in Linear QSPI mode.
1054 *
1055 * @param        InstancePtr is a pointer to the XQspiPs instance.
1056 * @param        RecvBufPtr is a pointer to a buffer for received data.
1057 * @param        Address is the starting address within the flash from
1058 *               from where data needs to be read.
1059 * @param        ByteCount contains the number of bytes to receive.
1060 *
1061 * @return
1062 *               - XST_SUCCESS if read is performed
1063 *               - XST_FAILURE if Linear mode is not set
1064 *
1065 * @note         None.
1066 *
1067 *
1068 ******************************************************************************/
1069 int XQspiPs_LqspiRead(XQspiPs *InstancePtr, u8 *RecvBufPtr,
1070                         u32 Address, unsigned ByteCount)
1071 {
1072         Xil_AssertNonvoid(InstancePtr != NULL);
1073         Xil_AssertNonvoid(RecvBufPtr != NULL);
1074         Xil_AssertNonvoid(ByteCount > 0);
1075         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1076
1077 #ifndef XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR
1078 #define XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR 0xFC000000
1079 #endif
1080         /*
1081          * Enable the controller
1082          */
1083         XQspiPs_Enable(InstancePtr);
1084
1085         if (XQspiPs_GetLqspiConfigReg(InstancePtr) &
1086                 XQSPIPS_LQSPI_CR_LINEAR_MASK) {
1087                 memcpy((void*)RecvBufPtr,
1088                       (const void*)(XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR +
1089                        Address),
1090                       (size_t)ByteCount);
1091                 return XST_SUCCESS;
1092         } else {
1093                 return XST_FAILURE;
1094         }
1095
1096         /*
1097          * Disable the controller
1098          */
1099         XQspiPs_Disable(InstancePtr);
1100
1101 }
1102
1103 /*****************************************************************************/
1104 /**
1105 *
1106 * Selects the slave with which the master communicates.
1107 *
1108 * The user is not allowed to select the slave while a transfer is in progress.
1109 *
1110 * @param        InstancePtr is a pointer to the XQspiPs instance.
1111 *
1112 * @return
1113 *               - XST_SUCCESS if the slave is selected or deselected
1114 *                 successfully.
1115 *               - XST_DEVICE_BUSY if a transfer is in progress, slave cannot be
1116 *                 changed.
1117 *
1118 * @note
1119 *
1120 * This function only sets the slave which will be selected when a transfer
1121 * occurs. The slave is not selected when the QSPI is idle.
1122 *
1123 ******************************************************************************/
1124 int XQspiPs_SetSlaveSelect(XQspiPs *InstancePtr)
1125 {
1126         u32 ConfigReg;
1127
1128         Xil_AssertNonvoid(InstancePtr != NULL);
1129         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1130
1131         /*
1132          * Do not allow the slave select to change while a transfer is in
1133          * progress. Not thread-safe.
1134          */
1135         if (InstancePtr->IsBusy) {
1136                 return XST_DEVICE_BUSY;
1137         }
1138
1139         /*
1140          * Select the slave
1141          */
1142         ConfigReg = XQspiPs_ReadReg(InstancePtr->Config.BaseAddress,
1143                                       XQSPIPS_CR_OFFSET);
1144         ConfigReg &= ~XQSPIPS_CR_SSCTRL_MASK;
1145         XQspiPs_WriteReg(InstancePtr->Config.BaseAddress,
1146                           XQSPIPS_CR_OFFSET, ConfigReg);
1147
1148         return XST_SUCCESS;
1149 }
1150
1151 /*****************************************************************************/
1152 /**
1153 *
1154 * Sets the status callback function, the status handler, which the driver
1155 * calls when it encounters conditions that should be reported to upper
1156 * layer software. The handler executes in an interrupt context, so it must
1157 * minimize the amount of processing performed. One of the following status
1158 * events is passed to the status handler.
1159 *
1160 * <pre>
1161 *
1162 * XST_SPI_TRANSFER_DONE         The requested data transfer is done
1163 *
1164 * XST_SPI_TRANSMIT_UNDERRUN     As a slave device, the master clocked data
1165 *                               but there were none available in the transmit
1166 *                               register/FIFO. This typically means the slave
1167 *                               application did not issue a transfer request
1168 *                               fast enough, or the processor/driver could not
1169 *                               fill the transmit register/FIFO fast enough.
1170 *
1171 * XST_SPI_RECEIVE_OVERRUN       The QSPI device lost data. Data was received
1172 *                               but the receive data register/FIFO was full.
1173 *
1174 * </pre>
1175 * @param        InstancePtr is a pointer to the XQspiPs instance.
1176 * @param        CallBackRef is the upper layer callback reference passed back
1177 *               when the callback function is invoked.
1178 * @param        FuncPtr is the pointer to the callback function.
1179 *
1180 * @return       None.
1181 *
1182 * @note
1183 *
1184 * The handler is called within interrupt context, so it should do its work
1185 * quickly and queue potentially time-consuming work to a task-level thread.
1186 *
1187 ******************************************************************************/
1188 void XQspiPs_SetStatusHandler(XQspiPs *InstancePtr, void *CallBackRef,
1189                                 XQspiPs_StatusHandler FuncPtr)
1190 {
1191         Xil_AssertVoid(InstancePtr != NULL);
1192         Xil_AssertVoid(FuncPtr != NULL);
1193         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1194
1195         InstancePtr->StatusHandler = FuncPtr;
1196         InstancePtr->StatusRef = CallBackRef;
1197 }
1198
1199 /*****************************************************************************/
1200 /**
1201 *
1202 * This is a stub for the status callback. The stub is here in case the upper
1203 * layers forget to set the handler.
1204 *
1205 * @param        CallBackRef is a pointer to the upper layer callback reference
1206 * @param        StatusEvent is the event that just occurred.
1207 * @param        ByteCount is the number of bytes transferred up until the event
1208 *               occurred.
1209 *
1210 * @return       None.
1211 *
1212 * @note         None.
1213 *
1214 ******************************************************************************/
1215 static void StubStatusHandler(void *CallBackRef, u32 StatusEvent,
1216                                 unsigned ByteCount)
1217 {
1218         (void) CallBackRef;
1219         (void) StatusEvent;
1220         (void) ByteCount;
1221
1222         Xil_AssertVoidAlways();
1223 }
1224
1225 /*****************************************************************************/
1226 /**
1227 *
1228 * The interrupt handler for QSPI interrupts. This function must be connected
1229 * by the user to an interrupt controller.
1230 *
1231 * The interrupts that are handled are:
1232 *
1233 *
1234 * - Data Transmit Register (FIFO) Empty. This interrupt is generated when the
1235 *   transmit register or FIFO is empty. The driver uses this interrupt during a
1236 *   transmission to continually send/receive data until the transfer is done.
1237 *
1238 * - Data Transmit Register (FIFO) Underflow. This interrupt is generated when
1239 *   the QSPI device, when configured as a slave, attempts to read an empty
1240 *   DTR/FIFO.  An empty DTR/FIFO usually means that software is not giving the
1241 *   device data in a timely manner. No action is taken by the driver other than
1242 *   to inform the upper layer software of the error.
1243 *
1244 * - Data Receive Register (FIFO) Overflow. This interrupt is generated when the
1245 *   QSPI device attempts to write a received byte to an already full DRR/FIFO.
1246 *   A full DRR/FIFO usually means software is not emptying the data in a timely
1247 *   manner.  No action is taken by the driver other than to inform the upper
1248 *   layer software of the error.
1249 *
1250 * @param        InstancePtr is a pointer to the XQspiPs instance.
1251 *
1252 * @return       None.
1253 *
1254 * @note
1255 *
1256 * The slave select register is being set to deselect the slave when a transfer
1257 * is complete.
1258 *
1259 ******************************************************************************/
1260 void XQspiPs_InterruptHandler(void *InstancePtr)
1261 {
1262         XQspiPs *QspiPtr = (XQspiPs *)InstancePtr;
1263         u32 IntrStatus;
1264         u32 ConfigReg;
1265         u32 Data;
1266         u32 TransCount;
1267         u32 Count = 0;
1268         unsigned BytesDone; /* Number of bytes done so far. */
1269
1270         Xil_AssertVoid(InstancePtr != NULL);
1271         Xil_AssertVoid(QspiPtr->IsReady == XIL_COMPONENT_IS_READY);
1272
1273         /*
1274          * Immediately clear the interrupts in case the ISR causes another
1275          * interrupt to be generated. If we clear at the end of the ISR,
1276          * we may miss newly generated interrupts. This occurs because we
1277          * transmit from within the ISR, which could potentially cause another
1278          * TX_EMPTY interrupt.
1279          */
1280         IntrStatus = XQspiPs_ReadReg(QspiPtr->Config.BaseAddress,
1281                                       XQSPIPS_SR_OFFSET);
1282         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, XQSPIPS_SR_OFFSET,
1283                           (IntrStatus & XQSPIPS_IXR_WR_TO_CLR_MASK));
1284         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress, XQSPIPS_IDR_OFFSET,
1285                         XQSPIPS_IXR_TXOW_MASK | XQSPIPS_IXR_RXNEMPTY_MASK |
1286                         XQSPIPS_IXR_RXOVR_MASK | XQSPIPS_IXR_TXUF_MASK);
1287
1288         if ((IntrStatus & XQSPIPS_IXR_TXOW_MASK) ||
1289                 (IntrStatus & XQSPIPS_IXR_RXNEMPTY_MASK)) {
1290
1291                 /*
1292                  * Rx FIFO has just reached threshold no. of entries.
1293                  * Read threshold no. of entries from RX FIFO
1294                  * Another possiblity of entering this loop is when
1295                  * the last byte has been transmitted and TX FIFO is empty,
1296                  * in which case, read all the data from RX FIFO.
1297                  * Always get the received data, but only fill the
1298                  * receive buffer if it is not null (it can be null when
1299                  * the device does not care to receive data).
1300                  */
1301                 TransCount = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes;
1302                 if (TransCount % 4) {
1303                         TransCount = TransCount/4 + 1;
1304                 } else {
1305                         TransCount = TransCount/4;
1306                 }
1307
1308                 while ((Count < TransCount) &&
1309                         (Count < XQSPIPS_RXFIFO_THRESHOLD_OPT)) {
1310
1311                         if (QspiPtr->RecvBufferPtr != NULL) {
1312                                 if (QspiPtr->RequestedBytes < 4) {
1313                                         Data = XQspiPs_ReadReg(QspiPtr->Config.BaseAddress,
1314                                                 XQSPIPS_RXD_OFFSET);
1315                                         XQspiPs_GetReadData(QspiPtr, Data,
1316                                                 QspiPtr->RequestedBytes);
1317                                 } else {
1318                                         (*(u32 *)QspiPtr->RecvBufferPtr) =
1319                                                 XQspiPs_ReadReg(QspiPtr->Config.BaseAddress,
1320                                                 XQSPIPS_RXD_OFFSET);
1321                                         QspiPtr->RecvBufferPtr += 4;
1322                                         QspiPtr->RequestedBytes -= 4;
1323                                         if (QspiPtr->RequestedBytes < 0) {
1324                                                 QspiPtr->RequestedBytes = 0;
1325                                         }
1326                                 }
1327                         } else {
1328                                 XQspiPs_ReadReg(QspiPtr->Config.BaseAddress,
1329                                                 XQSPIPS_RXD_OFFSET);
1330                                 QspiPtr->RequestedBytes -= 4;
1331                                 if (QspiPtr->RequestedBytes < 0) {
1332                                         QspiPtr->RequestedBytes = 0;
1333                                 }
1334
1335                         }
1336                         Count++;
1337                 }
1338                 Count = 0;
1339                 /*
1340                  * Interrupt asserted as TX_OW got asserted
1341                  * See if there is more data to send.
1342                  * Fill TX FIFO with RX threshold no. of entries or
1343                  * remaining entries (in case that is less than threshold)
1344                  */
1345                 while ((QspiPtr->RemainingBytes > 0) &&
1346                         (Count < XQSPIPS_RXFIFO_THRESHOLD_OPT)) {
1347                         /*
1348                          * Send more data.
1349                          */
1350                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1351                                 XQSPIPS_TXD_00_OFFSET,
1352                                 *((u32 *)QspiPtr->SendBufferPtr));
1353                         QspiPtr->SendBufferPtr += 4;
1354                         QspiPtr->RemainingBytes -= 4;
1355                         if (QspiPtr->RemainingBytes < 0) {
1356                                 QspiPtr->RemainingBytes = 0;
1357                         }
1358
1359                         Count++;
1360                 }
1361
1362                 if ((QspiPtr->RemainingBytes == 0) &&
1363                         (QspiPtr->RequestedBytes == 0)) {
1364                         /*
1365                          * No more data to send.  Disable the interrupt
1366                          * and inform the upper layer software that the
1367                          * transfer is done. The interrupt will be re-enabled
1368                          * when another transfer is initiated.
1369                          */
1370                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1371                                           XQSPIPS_IDR_OFFSET,
1372                                           XQSPIPS_IXR_RXNEMPTY_MASK |
1373                                           XQSPIPS_IXR_TXOW_MASK |
1374                                           XQSPIPS_IXR_RXOVR_MASK |
1375                                           XQSPIPS_IXR_TXUF_MASK);
1376
1377                         /*
1378                          * If the Slave select is being manually controlled,
1379                          * disable it because the transfer is complete.
1380                          */
1381                         if (XQspiPs_IsManualChipSelect(InstancePtr)) {
1382                                 ConfigReg = XQspiPs_ReadReg(
1383                                                 QspiPtr->Config.BaseAddress,
1384                                                 XQSPIPS_CR_OFFSET);
1385                                 ConfigReg |= XQSPIPS_CR_SSCTRL_MASK;
1386                                 XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1387                                                   XQSPIPS_CR_OFFSET,
1388                                                    ConfigReg);
1389                         }
1390
1391                         /*
1392                          * Clear the busy flag.
1393                          */
1394                         QspiPtr->IsBusy = FALSE;
1395
1396                         /*
1397                          * Disable the device.
1398                          */
1399                         XQspiPs_Disable(QspiPtr);
1400
1401                         /*
1402                          * Reset the RX FIFO threshold to one
1403                          */
1404                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1405                                 XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE);
1406
1407                         QspiPtr->StatusHandler(QspiPtr->StatusRef,
1408                                                 XST_SPI_TRANSFER_DONE,
1409                                                 QspiPtr->RequestedBytes);
1410                 } else {
1411                         /*
1412                          * Enable the TXOW interrupt.
1413                          */
1414                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1415                                          XQSPIPS_IER_OFFSET,
1416                                          XQSPIPS_IXR_RXNEMPTY_MASK |
1417                                          XQSPIPS_IXR_TXOW_MASK |
1418                                          XQSPIPS_IXR_RXOVR_MASK |
1419                                          XQSPIPS_IXR_TXUF_MASK);
1420                         /*
1421                          * If, in Manual Start mode, start the transfer.
1422                          */
1423                         if (XQspiPs_IsManualStart(QspiPtr)) {
1424                                 ConfigReg = XQspiPs_ReadReg(
1425                                         QspiPtr->Config.BaseAddress,
1426                                          XQSPIPS_CR_OFFSET);
1427                                 ConfigReg |= XQSPIPS_CR_MANSTRT_MASK;
1428                                 XQspiPs_WriteReg(
1429                                         QspiPtr->Config.BaseAddress,
1430                                          XQSPIPS_CR_OFFSET, ConfigReg);
1431                         }
1432                 }
1433         }
1434
1435         /*
1436          * Check for overflow and underflow errors.
1437          */
1438         if (IntrStatus & XQSPIPS_IXR_RXOVR_MASK) {
1439                 BytesDone = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes;
1440                 QspiPtr->IsBusy = FALSE;
1441
1442                 /*
1443                  * If the Slave select lines is being manually controlled,
1444                  * disable it because the transfer is complete.
1445                  */
1446                 if (XQspiPs_IsManualChipSelect(InstancePtr)) {
1447                         ConfigReg = XQspiPs_ReadReg(
1448                                         QspiPtr->Config.BaseAddress,
1449                                         XQSPIPS_CR_OFFSET);
1450                         ConfigReg |= XQSPIPS_CR_SSCTRL_MASK;
1451                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1452                                 XQSPIPS_CR_OFFSET, ConfigReg);
1453                 }
1454
1455                 /*
1456                  * Disable the device.
1457                  */
1458                 XQspiPs_Disable(QspiPtr);
1459
1460                 /*
1461                  * Reset the RX FIFO threshold to one
1462                  */
1463                 XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1464                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE);
1465
1466                 QspiPtr->StatusHandler(QspiPtr->StatusRef,
1467                         XST_SPI_RECEIVE_OVERRUN, BytesDone);
1468         }
1469
1470         if (IntrStatus & XQSPIPS_IXR_TXUF_MASK) {
1471                 BytesDone = QspiPtr->RequestedBytes - QspiPtr->RemainingBytes;
1472
1473                 QspiPtr->IsBusy = FALSE;
1474                 /*
1475                  * If the Slave select lines is being manually controlled,
1476                  * disable it because the transfer is complete.
1477                  */
1478                 if (XQspiPs_IsManualChipSelect(InstancePtr)) {
1479                         ConfigReg = XQspiPs_ReadReg(
1480                                         QspiPtr->Config.BaseAddress,
1481                                         XQSPIPS_CR_OFFSET);
1482                         ConfigReg |= XQSPIPS_CR_SSCTRL_MASK;
1483                         XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1484                                           XQSPIPS_CR_OFFSET, ConfigReg);
1485                 }
1486
1487                 /*
1488                  * Disable the device.
1489                  */
1490                 XQspiPs_Disable(QspiPtr);
1491
1492                 /*
1493                  * Reset the RX FIFO threshold to one
1494                  */
1495                 XQspiPs_WriteReg(QspiPtr->Config.BaseAddress,
1496                         XQSPIPS_RXWR_OFFSET, XQSPIPS_RXWR_RESET_VALUE);
1497
1498                 QspiPtr->StatusHandler(QspiPtr->StatusRef,
1499                                       XST_SPI_TRANSMIT_UNDERRUN, BytesDone);
1500         }
1501 }
1502
1503
1504 /*****************************************************************************/
1505 /**
1506 *
1507 * Copies data from Data to the Receive buffer.
1508 *
1509 * @param        InstancePtr is a pointer to the XQspiPs instance.
1510 * @param        Data is the data which needs to be copied to the Rx buffer.
1511 * @param        Size is the number of bytes to be copied to the Receive buffer.
1512 *
1513 * @return       None.
1514 *
1515 * @note         None.
1516 *
1517 ******************************************************************************/
1518 static void XQspiPs_GetReadData(XQspiPs *InstancePtr, u32 Data, u8 Size)
1519 {
1520         u8 DataByte3;
1521
1522         if (InstancePtr->RecvBufferPtr) {
1523                 switch (Size) {
1524                 case 1:
1525                         if (InstancePtr->ShiftReadData == 1) {
1526                                 *((u8 *)InstancePtr->RecvBufferPtr) =
1527                                         ((Data & 0xFF000000) >> 24);
1528                         } else {
1529                                 *((u8 *)InstancePtr->RecvBufferPtr) =
1530                                         (Data & 0xFF);
1531                         }
1532                         InstancePtr->RecvBufferPtr += 1;
1533                         break;
1534                 case 2:
1535                         if (InstancePtr->ShiftReadData == 1) {
1536                                 *((u16 *)InstancePtr->RecvBufferPtr) =
1537                                         ((Data & 0xFFFF0000) >> 16);
1538                         } else  {
1539                                 *((u16 *)InstancePtr->RecvBufferPtr) =
1540                                         (Data & 0xFFFF);
1541                         }
1542                         InstancePtr->RecvBufferPtr += 2;
1543                         break;
1544                 case 3:
1545                         if (InstancePtr->ShiftReadData == 1) {
1546                                 *((u16 *)InstancePtr->RecvBufferPtr) =
1547                                         ((Data & 0x00FFFF00) >> 8);
1548                                 InstancePtr->RecvBufferPtr += 2;
1549                                 DataByte3 = ((Data & 0xFF000000) >> 24);
1550                                 *((u8 *)InstancePtr->RecvBufferPtr) = DataByte3;
1551                         } else {
1552                                 *((u16 *)InstancePtr->RecvBufferPtr) =
1553                                         (Data & 0xFFFF);
1554                                 InstancePtr->RecvBufferPtr += 2;
1555                                 DataByte3 = ((Data & 0x00FF0000) >> 16);
1556                                 *((u8 *)InstancePtr->RecvBufferPtr) = DataByte3;
1557                         }
1558                         InstancePtr->RecvBufferPtr += 1;
1559                         break;
1560                 default:
1561                         /* This will never execute */
1562                         break;
1563                 }
1564         }
1565         InstancePtr->ShiftReadData  = 0;
1566         InstancePtr->RequestedBytes -= Size;
1567         if (InstancePtr->RequestedBytes < 0) {
1568                 InstancePtr->RequestedBytes = 0;
1569         }
1570 }
1571 /** @} */