1 /******************************************************************************
3 * Copyright (C) 2014 Xilinx, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
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
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.
31 ******************************************************************************/
32 /*****************************************************************************/
35 * @file xqspipsu_options.c
37 * This file implements funcitons to configure the QSPIPSU component,
38 * specifically some optional settings, clock and flash related information.
41 * MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- --- -------- -----------------------------------------------
45 * 1.0 hk 08/21/14 First release
46 * sk 03/13/15 Added IO mode support.
50 ******************************************************************************/
52 /***************************** Include Files *********************************/
56 /************************** Constant Definitions *****************************/
58 /**************************** Type Definitions *******************************/
60 /***************** Macros (Inline Functions) Definitions *********************/
62 /************************** Function Prototypes ******************************/
64 /************************** Variable Definitions *****************************/
67 * Create the table of options which are processed to get/set the device
68 * options. These options are table driven to allow easy maintenance and
69 * expansion of the options.
76 static OptionsMap OptionsTable[] = {
77 {XQSPIPSU_CLK_ACTIVE_LOW_OPTION, XQSPIPSU_CFG_CLK_POL_MASK},
78 {XQSPIPSU_CLK_PHASE_1_OPTION, XQSPIPSU_CFG_CLK_PHA_MASK},
79 {XQSPIPSU_MANUAL_START_OPTION, XQSPIPSU_CFG_GEN_FIFO_START_MODE_MASK},
82 #define XQSPIPSU_NUM_OPTIONS (sizeof(OptionsTable) / sizeof(OptionsMap))
84 /*****************************************************************************/
87 * This function sets the options for the QSPIPSU device driver.The options
88 * control how the device behaves relative to the QSPIPSU bus. The device must be
89 * idle rather than busy transferring data before setting these device options.
91 * @param InstancePtr is a pointer to the XQspiPsu instance.
92 * @param Options contains the specified options to be set. This is a bit
93 * mask where a 1 indicates the option should be turned ON and
94 * a 0 indicates no action. One or more bit values may be
95 * contained in the mask. See the bit definitions named
96 * XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
99 * - XST_SUCCESS if options are successfully set.
100 * - XST_DEVICE_BUSY if the device is currently transferring data.
101 * The transfer must complete or be aborted before setting options.
104 * This function is not thread-safe.
106 ******************************************************************************/
107 int XQspiPsu_SetOptions(XQspiPsu *InstancePtr, u32 Options)
113 Xil_AssertNonvoid(InstancePtr != NULL);
114 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
117 * Do not allow to modify the Control Register while a transfer is in
118 * progress. Not thread-safe.
120 if (InstancePtr->IsBusy) {
121 return XST_DEVICE_BUSY;
124 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
125 XQSPIPSU_CFG_OFFSET);
128 * Loop through the options table, turning the option on
129 * depending on whether the bit is set in the incoming options flag.
131 for (Index = 0; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
132 if (Options & OptionsTable[Index].Option) {
134 ConfigReg |= OptionsTable[Index].Mask;
139 * Now write the control register. Leave it to the upper layers
140 * to restart the device.
142 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
148 /*****************************************************************************/
151 * This function resets the options for the QSPIPSU device driver.The options
152 * control how the device behaves relative to the QSPIPSU bus. The device must be
153 * idle rather than busy transferring data before setting these device options.
155 * @param InstancePtr is a pointer to the XQspiPsu instance.
156 * @param Options contains the specified options to be set. This is a bit
157 * mask where a 1 indicates the option should be turned OFF and
158 * a 0 indicates no action. One or more bit values may be
159 * contained in the mask. See the bit definitions named
160 * XQSPIPSU_*_OPTIONS in the file xqspipsu.h.
163 * - XST_SUCCESS if options are successfully set.
164 * - XST_DEVICE_BUSY if the device is currently transferring data.
165 * The transfer must complete or be aborted before setting options.
168 * This function is not thread-safe.
170 ******************************************************************************/
171 int XQspiPsu_ClearOptions(XQspiPsu *InstancePtr, u32 Options)
177 Xil_AssertNonvoid(InstancePtr != NULL);
178 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
181 * Do not allow to modify the Control Register while a transfer is in
182 * progress. Not thread-safe.
184 if (InstancePtr->IsBusy) {
185 return XST_DEVICE_BUSY;
188 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
189 XQSPIPSU_CFG_OFFSET);
192 * Loop through the options table, turning the option on
193 * depending on whether the bit is set in the incoming options flag.
195 for (Index = 0; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
196 if (Options & OptionsTable[Index].Option) {
198 ConfigReg &= ~OptionsTable[Index].Mask;
203 * Now write the control register. Leave it to the upper layers
204 * to restart the device.
206 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
212 /*****************************************************************************/
215 * This function gets the options for the QSPIPSU device. The options control how
216 * the device behaves relative to the QSPIPSU bus.
218 * @param InstancePtr is a pointer to the XQspiPsu instance.
222 * Options contains the specified options currently set. This is a bit value
223 * where a 1 means the option is on, and a 0 means the option is off.
224 * See the bit definitions named XQSPIPSU_*_OPTIONS in file xqspipsu.h.
228 ******************************************************************************/
229 u32 XQspiPsu_GetOptions(XQspiPsu *InstancePtr)
235 Xil_AssertNonvoid(InstancePtr != NULL);
236 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
239 * Get the current options from QSPIPSU configuration register.
241 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
242 XQSPIPSU_CFG_OFFSET);
244 /* Loop through the options table to grab options */
245 for (Index = 0; Index < XQSPIPSU_NUM_OPTIONS; Index++) {
246 if (ConfigReg & OptionsTable[Index].Mask) {
247 OptionsFlag |= OptionsTable[Index].Option;
254 /*****************************************************************************/
257 * Configures the clock according to the prescaler passed.
260 * @param InstancePtr is a pointer to the XQspiPsu instance.
261 * @param Prescaler - clock prescaler to be set.
264 * - XST_SUCCESS if successful.
265 * - XST_DEVICE_IS_STARTED if the device is already started.
266 * It must be stopped to re-initialize.
270 ******************************************************************************/
271 int XQspiPsu_SetClkPrescaler(XQspiPsu *InstancePtr, u8 Prescaler)
275 Xil_AssertNonvoid(InstancePtr != NULL);
276 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
277 Xil_AssertNonvoid(Prescaler <= XQSPIPSU_CR_PRESC_MAXIMUM);
280 * Do not allow the slave select to change while a transfer is in
281 * progress. Not thread-safe.
283 if (InstancePtr->IsBusy) {
284 return XST_DEVICE_BUSY;
288 * Read the configuration register, mask out the relevant bits, and set
289 * them with the shifted value passed into the function. Write the
290 * results back to the configuration register.
292 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
293 XQSPIPSU_CFG_OFFSET);
295 ConfigReg &= ~XQSPIPSU_CFG_BAUD_RATE_DIV_MASK;
296 ConfigReg |= (u32) (Prescaler & XQSPIPSU_CR_PRESC_MAXIMUM) <<
297 XQSPIPSU_CFG_BAUD_RATE_DIV_SHIFT;
299 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
300 XQSPIPSU_CFG_OFFSET, ConfigReg);
305 /*****************************************************************************/
308 * This funciton should be used to tell the QSPIPSU driver the HW flash
309 * configuration being used. This API should be called atleast once in the
310 * application. If desired, it can be called multiple times when switching
311 * between communicating to different flahs devices/using different configs.
313 * @param InstancePtr is a pointer to the XQspiPsu instance.
314 * @param FlashCS - Flash Chip Select.
315 * @param FlashBus - Flash Bus (Upper, Lower or Both).
318 * - XST_SUCCESS if successful.
319 * - XST_DEVICE_IS_STARTED if the device is already started.
320 * It must be stopped to re-initialize.
322 * @note If this funciton is not called atleast once in the application,
323 * the driver assumes there is a single flash connected to the
324 * lower bus and CS line.
326 ******************************************************************************/
327 void XQspiPsu_SelectFlash(XQspiPsu *InstancePtr, u8 FlashCS, u8 FlashBus)
329 Xil_AssertVoid(InstancePtr != NULL);
332 * Bus and CS lines selected here will be updated in the instance and
333 * used for subsequent GENFIFO entries during transfer.
336 /* Choose slave select line */
338 case XQSPIPSU_SELECT_FLASH_CS_BOTH:
339 InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER |
340 XQSPIPSU_GENFIFO_CS_UPPER;
342 case XQSPIPSU_SELECT_FLASH_CS_UPPER:
343 InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_UPPER;
345 case XQSPIPSU_SELECT_FLASH_CS_LOWER:
347 InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
352 case XQSPIPSU_SELECT_FLASH_BUS_BOTH:
353 InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER |
354 XQSPIPSU_GENFIFO_BUS_UPPER;
356 case XQSPIPSU_SELECT_FLASH_BUS_UPPER:
357 InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_UPPER;
359 case XQSPIPSU_SELECT_FLASH_BUS_LOWER:
361 InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
365 /*****************************************************************************/
368 * This function sets the Read mode for the QSPIPSU device driver.The device
369 * must be idle rather than busy transferring data before setting Read mode
372 * @param InstancePtr is a pointer to the XQspiPsu instance.
373 * @param Mode contains the specified Mode to be set. See the
374 * bit definitions named XQSPIPSU_READMODE_* in the file xqspipsu.h.
377 * - XST_SUCCESS if options are successfully set.
378 * - XST_DEVICE_BUSY if the device is currently transferring data.
379 * The transfer must complete or be aborted before setting Mode.
382 * This function is not thread-safe.
384 ******************************************************************************/
385 int XQspiPsu_SetReadMode(XQspiPsu *InstancePtr, u32 Mode)
389 Xil_AssertNonvoid(InstancePtr != NULL);
390 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
393 * Do not allow to modify the Control Register while a transfer is in
394 * progress. Not thread-safe.
396 if (InstancePtr->IsBusy) {
397 return XST_DEVICE_BUSY;
400 InstancePtr->ReadMode = Mode;
402 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
403 XQSPIPSU_CFG_OFFSET);
405 if (Mode == XQSPIPSU_READMODE_DMA) {
406 ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
407 ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
409 ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
412 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,