1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes
9  **********************************************************************************************************************/
10 #include "bsp_api.h"
11 #include "r_ospi_b.h"
12 
13 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
14  #include "r_transfer_api.h"
15  #include "r_dmac.h"
16 #endif
17 
18 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
19  #include "hw_sce_ra_private.h"
20 #endif
21 
22 /***********************************************************************************************************************
23  * Macro definitions
24  **********************************************************************************************************************/
25 
26 /* "xSPI" in ASCII.  Used to determine if the control block is open. */
27 #define OSPI_B_PRV_OPEN                                  (0x78535049U)
28 
29 #define OSPI_B_PRV_BMCTL_DEFAULT_VALUE                   (0x0C)
30 
31 #define OSPI_B_PRV_CMCFG_1BYTE_VALUE_MASK                (0xFF00U)
32 #define OSPI_B_PRV_CMCFG_2BYTE_VALUE_MASK                (0xFFFFU)
33 
34 #define OSPI_B_PRV_AUTOCALIBRATION_DATA_SIZE             (0xFU)
35 #define OSPI_B_PRV_AUTOCALIBRATION_LATENCY_CYCLES        (0U)
36 
37 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_0    (0xFFFF0000U)
38 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_1    (0x000800FFU)
39 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_2    (0x00FFF700U)
40 #define OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_3    (0xF700F708U)
41 
42 #define OSPI_B_PRV_ADDRESS_REPLACE_VALUE                 (0xF0U)
43 #define OSPI_B_PRV_ADDRESS_REPLACE_ENABLE_BITS           (OSPI_B_PRV_ADDRESS_REPLACE_VALUE << \
44                                                           R_XSPI_CMCFGCS_CMCFG0_ADDRPEN_Pos)
45 #define OSPI_B_PRV_ADDRESS_REPLACE_MASK                  (~(OSPI_B_PRV_ADDRESS_REPLACE_VALUE << 24))
46 
47 #define OSPI_B_PRV_AUTOCALIBRATION_FRAME_INTERVAL        (0x1FU)
48 #define OSPI_B_PRV_AUTOCALIBRATION_NO_WRITE_CMD          (0x1U)
49 #define OSPI_B_PRV_AUTOCALIBRATION_SHIFT_DS_END_VALUE    (0x1FU)
50 
51 #define OSPI_B_PRV_WORD_ACCESS_SIZE                      (4U)
52 #define OSPI_B_PRV_HALF_WORD_ACCESS_SIZE                 (2U)
53 
54 #define OSPI_B_PRV_DIRECT_ADDR_AND_DATA_MASK             (7U)
55 #define OSPI_B_PRV_PAGE_SIZE_BYTES                       (256U)
56 
57 #define OSPI_B_PRV_DIRECT_CMD_SIZE_MASK                  (0x3U)
58 
59 #define OSPI_B_PRV_CDTBUF_CMD_OFFSET                     (16U)
60 #define OSPI_B_PRV_CDTBUF_CMD_UPPER_OFFSET               (24U)
61 #define OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK              (0xFFU)
62 #define OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT             (8U)
63 #define OSPI_B_PRV_CDTBUF_CMD_2B_VALUE_MASK              (0xFFFFU)
64 
65 #define OSPI_B_PRV_BMCTL0_DISABLED_VALUE                 (0x00) // 0b0000'0000
66 #define OSPI_B_PRV_BMCTL0_READ_ONLY_VALUE                (0x55) // 0b0101'0101
67 #define OSPI_B_PRV_BMCTL0_WRITE_ONLY_VALUE               (0xAA) // 0b1010'1010
68 #define OSPI_B_PRV_BMCTL0_READ_WRITE_VALUE               (0xFF) // 0b1111'1111
69 
70 #define OSPI_B_PRV_BMCTL1_CLEAR_PREFETCH_MASK            (0x03 << R_XSPI_BMCTL1_PBUFCLRCH_Pos)
71 #define OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK    (0x03 << R_XSPI_BMCTL1_MWRPUSHCH_Pos)
72 
73 #define OSPI_B_PRV_COMSTT_MEMACCCH_MASK                  (0x03 << R_XSPI_COMSTT_MEMACCCH_Pos)
74 
75 #define OSPI_B_SOFTWARE_DELAY                            (50U)
76 
77 #define OSPI_B_PRV_DOTF_REG00_RESET_VALUE                (0x22000000)
78 
79 /* These are used as modulus checking, make sure they are powers of 2. */
80 #define OSPI_B_PRV_CPU_ACCESS_LENGTH                     (8U)
81 #define OSPI_B_PRV_CPU_ACCESS_ALIGNMENT                  (8U)
82 
83 #define OSPI_B_PRV_PROTOCOL_USES_DS_MASK                 (0x200U)
84 
85 #define OSPI_B_PRV_UINT32_BITS                           (32)
86 
87 #ifndef OSPI_B_MAX_WRITE_ENABLE_LOOPS
88  #define OSPI_B_MAX_WRITE_ENABLE_LOOPS                   (5)
89 #endif
90 
91 /* Number of address bytes in 4 byte address mode. */
92 #define OSPI_B_4_BYTE_ADDRESS                            (4U)
93 
94 /***********************************************************************************************************************
95  * Typedef definitions
96  **********************************************************************************************************************/
97 
98 /***********************************************************************************************************************
99  * Private function prototypes
100  **********************************************************************************************************************/
101 static bool      r_ospi_b_status_sub(ospi_b_instance_ctrl_t * p_instance_ctrl, uint8_t bit_pos);
102 static fsp_err_t r_ospi_b_protocol_specific_settings(ospi_b_instance_ctrl_t * p_instance_ctrl);
103 static fsp_err_t r_ospi_b_write_enable(ospi_b_instance_ctrl_t * p_instance_ctrl);
104 static void      r_ospi_b_direct_transfer(ospi_b_device_number_t              channel,
105                                           spi_flash_direct_transfer_t * const p_transfer,
106                                           spi_flash_direct_transfer_dir_t     direction);
107 static ospi_b_xspi_command_set_t const * r_ospi_b_command_set_get(ospi_b_instance_ctrl_t * p_instance_ctrl);
108 
109 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
110 static fsp_err_t r_ospi_b_automatic_calibration_seq(ospi_b_instance_ctrl_t * p_instance_ctrl);
111 
112 #endif
113 
114 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
115 static void r_ospi_b_xip(ospi_b_instance_ctrl_t * p_instance_ctrl, bool is_entering);
116 
117 #endif
118 
119 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
120 static fsp_err_t r_ospi_b_dotf_setup(ospi_b_dotf_cfg_t * p_dotf_cfg);
121 
122 #endif
123 
124 /***********************************************************************************************************************
125  * Private global variables
126  **********************************************************************************************************************/
127 
128 /* Bit-flags specifying which channels are open so the module can be stopped when all are closed. */
129 static uint32_t g_ospi_b_channels_open_flags = 0;
130 
131 /*******************************************************************************************************************//**
132  * @addtogroup OSPI_B
133  * @{
134  **********************************************************************************************************************/
135 
136 /***********************************************************************************************************************
137  * Global Variables
138  **********************************************************************************************************************/
139 
140 const spi_flash_api_t g_ospi_b_on_spi_flash =
141 {
142     .open           = R_OSPI_B_Open,
143     .directWrite    = R_OSPI_B_DirectWrite,
144     .directRead     = R_OSPI_B_DirectRead,
145     .directTransfer = R_OSPI_B_DirectTransfer,
146     .spiProtocolSet = R_OSPI_B_SpiProtocolSet,
147     .write          = R_OSPI_B_Write,
148     .erase          = R_OSPI_B_Erase,
149     .statusGet      = R_OSPI_B_StatusGet,
150     .xipEnter       = R_OSPI_B_XipEnter,
151     .xipExit        = R_OSPI_B_XipExit,
152     .bankSet        = R_OSPI_B_BankSet,
153     .close          = R_OSPI_B_Close,
154     .autoCalibrate  = R_OSPI_B_AutoCalibrate,
155 };
156 
157 /***********************************************************************************************************************
158  * Functions
159  **********************************************************************************************************************/
160 
161 /*******************************************************************************************************************//**
162  * Open the xSPI device. After the driver is open, the xSPI device can be accessed like internal flash memory.
163  *
164  * Implements @ref spi_flash_api_t::open.
165  *
166  * @retval FSP_SUCCESS              Configuration was successful.
167  * @retval FSP_ERR_ASSERTION        The parameter p_ctrl or p_cfg is NULL.
168  * @retval FSP_ERR_ALREADY_OPEN     Driver has already been opened with the same p_ctrl.
169  * @retval FSP_ERR_CALIBRATE_FAILED Failed to perform auto-calibrate.
170  **********************************************************************************************************************/
R_OSPI_B_Open(spi_flash_ctrl_t * const p_ctrl,spi_flash_cfg_t const * const p_cfg)171 fsp_err_t R_OSPI_B_Open (spi_flash_ctrl_t * const p_ctrl, spi_flash_cfg_t const * const p_cfg)
172 {
173     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
174 
175 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
176     FSP_ASSERT(NULL != p_instance_ctrl);
177     FSP_ASSERT(NULL != p_cfg);
178     FSP_ASSERT(NULL != p_cfg->p_extend);
179     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
180 #endif
181 
182     ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
183 
184 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
185     FSP_ERROR_RETURN((g_ospi_b_channels_open_flags & (1U << p_cfg_extend->channel)) == 0, FSP_ERR_ALREADY_OPEN);
186 #endif
187 
188     /* Enable clock to the xSPI block */
189     R_BSP_MODULE_START(FSP_IP_OSPI, 0U);
190 
191     /* Initialize control block. */
192     p_instance_ctrl->p_cfg        = p_cfg;
193     p_instance_ctrl->spi_protocol = p_cfg->spi_protocol;
194     p_instance_ctrl->channel      = p_cfg_extend->channel;
195 
196 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
197     if (NULL != p_cfg_extend->p_dotf_cfg)
198     {
199         fsp_err_t dotf_ret = r_ospi_b_dotf_setup((ospi_b_dotf_cfg_t *) p_cfg_extend->p_dotf_cfg);
200         if (FSP_SUCCESS != dotf_ret)
201         {
202             /* If the DOTF initialization fails, stop the module if no other channels are active. */
203             if (g_ospi_b_channels_open_flags == 0)
204             {
205                 R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
206             }
207 
208             return dotf_ret;
209         }
210     }
211 #endif
212 
213 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
214     transfer_instance_t const * p_transfer = p_cfg_extend->p_lower_lvl_transfer;
215  #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
216     FSP_ASSERT(NULL != p_transfer);
217  #endif
218 
219     /* Initialize transfer instance */
220     p_transfer->p_api->open(p_transfer->p_ctrl, p_transfer->p_cfg);
221 #endif
222 
223     /* Disable memory-mapping for this slave. It will be enabled later on after initialization. */
224     if (OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel)
225     {
226         R_XSPI->BMCTL0 &= ~(R_XSPI_BMCTL0_CH0CS0ACC_Msk | R_XSPI_BMCTL0_CH1CS0ACC_Msk);
227     }
228     else
229     {
230         R_XSPI->BMCTL0 &= ~(R_XSPI_BMCTL0_CH0CS1ACC_Msk | R_XSPI_BMCTL0_CH1CS1ACC_Msk);
231     }
232 
233     /* Perform xSPI Initial configuration as described in hardware manual (see Section 37.3.8
234      * 'Flow of Operations' of the RA8M1 manual R01UH0994EJ0100). */
235 
236     /* Set xSPI protocol mode. */
237     uint32_t liocfg = ((uint32_t) p_cfg->spi_protocol) << R_XSPI_LIOCFGCS_PRTMD_Pos;
238     R_XSPI->LIOCFGCS[p_cfg_extend->channel] = liocfg;
239 
240     /* Set xSPI drive/sampling timing. */
241     if (OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel)
242     {
243         R_XSPI->WRAPCFG = ((uint32_t) p_cfg_extend->data_latch_delay_clocks << R_XSPI_WRAPCFG_DSSFTCS0_Pos) &
244                           R_XSPI_WRAPCFG_DSSFTCS0_Msk;
245     }
246     else
247     {
248         R_XSPI->WRAPCFG = ((uint32_t) p_cfg_extend->data_latch_delay_clocks << R_XSPI_WRAPCFG_DSSFTCS1_Pos) &
249                           R_XSPI_WRAPCFG_DSSFTCS1_Msk;
250     }
251 
252     /* Set minimum cycles between xSPI frames. */
253     liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->command_to_command_interval << R_XSPI_LIOCFGCS_CSMIN_Pos) &
254               R_XSPI_LIOCFGCS_CSMIN_Msk;
255 
256     /* Set CS asserting extension in cycles */
257     liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->cs_pulldown_lead << R_XSPI_LIOCFGCS_CSASTEX_Pos) &
258               R_XSPI_LIOCFGCS_CSASTEX_Msk;
259 
260     /* Set CS releasing extension in cycles */
261     liocfg |= ((uint32_t) p_cfg_extend->p_timing_settings->cs_pullup_lag << R_XSPI_LIOCFGCS_CSNEGEX_Pos) &
262               R_XSPI_LIOCFGCS_CSNEGEX_Msk;
263 
264     /* Set xSPI CSn signal timings. */
265     R_XSPI->LIOCFGCS[p_cfg_extend->channel] = liocfg;
266 
267     /* Set xSPI memory-mapping operation. */
268     fsp_err_t ret = r_ospi_b_protocol_specific_settings(p_instance_ctrl);
269 
270     /* Return response after issuing write transaction to xSPI bus, Enable prefetch function and combination if desired. */
271     const uint32_t bmcfgch = (0 << R_XSPI_BMCFGCH_WRMD_Pos) |
272                              ((OSPI_B_CFG_COMBINATION_FUNCTION << R_XSPI_BMCFGCH_MWRCOMB_Pos) &
273                               (R_XSPI_BMCFGCH_MWRCOMB_Msk | R_XSPI_BMCFGCH_MWRSIZE_Msk)) |
274                              ((OSPI_B_CFG_PREFETCH_FUNCTION << R_XSPI_BMCFGCH_PREEN_Pos) &
275                               R_XSPI_BMCFGCH_PREEN_Msk);
276 
277     /* Both of these should have the same configuration and it affects all OSPI slave channels. */
278     R_XSPI->BMCFGCH[0] = bmcfgch;
279     R_XSPI->BMCFGCH[1] = bmcfgch;
280 
281     /* Re-activate memory-mapped mode in Read/Write. */
282     if (p_instance_ctrl->channel == 0)
283     {
284         R_XSPI->BMCTL0 |= R_XSPI_BMCTL0_CH0CS0ACC_Msk | R_XSPI_BMCTL0_CH1CS0ACC_Msk;
285     }
286     else
287     {
288         R_XSPI->BMCTL0 |= R_XSPI_BMCTL0_CH0CS1ACC_Msk | R_XSPI_BMCTL0_CH1CS1ACC_Msk;
289     }
290 
291     if (FSP_SUCCESS == ret)
292     {
293         p_instance_ctrl->open         = OSPI_B_PRV_OPEN;
294         g_ospi_b_channels_open_flags |= (1U << p_instance_ctrl->channel);
295     }
296     else if (g_ospi_b_channels_open_flags == 0)
297     {
298         /* If the open fails and no other channels are open, stop the module. */
299         R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
300     }
301     else
302     {
303         // Do nothing.
304     }
305 
306     return ret;
307 }
308 
309 /*******************************************************************************************************************//**
310  * Writes raw data directly to the OctaFlash. API not supported. Use R_OSPI_B_DirectTransfer
311  *
312  * Implements @ref spi_flash_api_t::directWrite.
313  *
314  * @retval FSP_ERR_UNSUPPORTED         API not supported by OSPI.
315  **********************************************************************************************************************/
R_OSPI_B_DirectWrite(spi_flash_ctrl_t * p_ctrl,uint8_t const * const p_src,uint32_t const bytes,bool const read_after_write)316 fsp_err_t R_OSPI_B_DirectWrite (spi_flash_ctrl_t    * p_ctrl,
317                                 uint8_t const * const p_src,
318                                 uint32_t const        bytes,
319                                 bool const            read_after_write)
320 {
321     FSP_PARAMETER_NOT_USED(p_ctrl);
322     FSP_PARAMETER_NOT_USED(p_src);
323     FSP_PARAMETER_NOT_USED(bytes);
324     FSP_PARAMETER_NOT_USED(read_after_write);
325 
326     FSP_RETURN(FSP_ERR_UNSUPPORTED);
327 }
328 
329 /*******************************************************************************************************************//**
330  * Reads raw data directly from the OctaFlash. API not supported. Use R_OSPI_B_DirectTransfer.
331  *
332  * Implements @ref spi_flash_api_t::directRead.
333  *
334  * @retval FSP_ERR_UNSUPPORTED         API not supported by OSPI.
335  **********************************************************************************************************************/
R_OSPI_B_DirectRead(spi_flash_ctrl_t * p_ctrl,uint8_t * const p_dest,uint32_t const bytes)336 fsp_err_t R_OSPI_B_DirectRead (spi_flash_ctrl_t * p_ctrl, uint8_t * const p_dest, uint32_t const bytes)
337 {
338     FSP_PARAMETER_NOT_USED(p_ctrl);
339     FSP_PARAMETER_NOT_USED(p_dest);
340     FSP_PARAMETER_NOT_USED(bytes);
341 
342     FSP_RETURN(FSP_ERR_UNSUPPORTED);
343 }
344 
345 /*******************************************************************************************************************//**
346  * Read/Write raw data directly with the OctaFlash.
347  *
348  * Implements @ref spi_flash_api_t::directTransfer.
349  *
350  * @retval FSP_SUCCESS                 The flash was programmed successfully.
351  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
352  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
353  **********************************************************************************************************************/
R_OSPI_B_DirectTransfer(spi_flash_ctrl_t * p_ctrl,spi_flash_direct_transfer_t * const p_transfer,spi_flash_direct_transfer_dir_t direction)354 fsp_err_t R_OSPI_B_DirectTransfer (spi_flash_ctrl_t                  * p_ctrl,
355                                    spi_flash_direct_transfer_t * const p_transfer,
356                                    spi_flash_direct_transfer_dir_t     direction)
357 {
358     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
359 
360 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
361     FSP_ASSERT(NULL != p_instance_ctrl);
362     FSP_ASSERT(NULL != p_transfer);
363     FSP_ASSERT(0 != p_transfer->command_length);
364     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
365 #endif
366 
367     r_ospi_b_direct_transfer(p_instance_ctrl->channel, p_transfer, direction);
368 
369     return FSP_SUCCESS;
370 }
371 
372 /*******************************************************************************************************************//**
373  * Enters XIP (execute in place) mode.
374  *
375  * Implements @ref spi_flash_api_t::xipEnter.
376  *
377  * @retval FSP_SUCCESS                 XiP mode was entered successfully.
378  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
379  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
380  * @retval FSP_ERR_UNSUPPORTED         XiP support is not enabled.
381  **********************************************************************************************************************/
R_OSPI_B_XipEnter(spi_flash_ctrl_t * p_ctrl)382 fsp_err_t R_OSPI_B_XipEnter (spi_flash_ctrl_t * p_ctrl)
383 {
384 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
385     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
386 
387  #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
388     FSP_ASSERT(NULL != p_instance_ctrl);
389     FSP_ASSERT(NULL != p_instance_ctrl->p_cfg);
390     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
391  #endif
392 
393     r_ospi_b_xip(p_instance_ctrl, true);
394 
395     return FSP_SUCCESS;
396 #else
397     FSP_PARAMETER_NOT_USED(p_ctrl);
398 
399     return FSP_ERR_UNSUPPORTED;
400 #endif
401 }
402 
403 /*******************************************************************************************************************//**
404  * Exits XIP (execute in place) mode.
405  *
406  * Implements @ref spi_flash_api_t::xipExit.
407  *
408  * @retval FSP_SUCCESS                 XiP mode was entered successfully.
409  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
410  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
411  * @retval FSP_ERR_UNSUPPORTED         XiP support is not enabled.
412  **********************************************************************************************************************/
R_OSPI_B_XipExit(spi_flash_ctrl_t * p_ctrl)413 fsp_err_t R_OSPI_B_XipExit (spi_flash_ctrl_t * p_ctrl)
414 {
415 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
416     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
417 
418  #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
419     FSP_ASSERT(NULL != p_instance_ctrl);
420     FSP_ASSERT(NULL != p_instance_ctrl->p_cfg);
421     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
422  #endif
423 
424     r_ospi_b_xip(p_instance_ctrl, false);
425 
426     return FSP_SUCCESS;
427 #else
428     FSP_PARAMETER_NOT_USED(p_ctrl);
429 
430     return FSP_ERR_UNSUPPORTED;
431 #endif
432 }
433 
434 /*******************************************************************************************************************//**
435  * Program a page of data to the flash.
436  *
437  * Implements @ref spi_flash_api_t::write.
438  *
439  * @retval FSP_SUCCESS                 The flash was programmed successfully.
440  * @retval FSP_ERR_ASSERTION           p_instance_ctrl, p_dest or p_src is NULL, or byte_count crosses a page boundary.
441  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
442  * @retval FSP_ERR_INVALID_SIZE        Insufficient space remaining in page or write length is not a multiple of CPU access size when not using the DMAC.
443  * @retval FSP_ERR_DEVICE_BUSY         Another Write/Erase transaction is in progress.
444  * @retval FSP_ERR_WRITE_FAILED        Write operation failed.
445  * @retval FSP_ERR_INVALID_ADDRESS     Destination or source is not aligned to CPU access alignment when not using the DMAC.
446  **********************************************************************************************************************/
R_OSPI_B_Write(spi_flash_ctrl_t * p_ctrl,uint8_t const * const p_src,uint8_t * const p_dest,uint32_t byte_count)447 fsp_err_t R_OSPI_B_Write (spi_flash_ctrl_t    * p_ctrl,
448                           uint8_t const * const p_src,
449                           uint8_t * const       p_dest,
450                           uint32_t              byte_count)
451 {
452     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
453     fsp_err_t                err             = FSP_SUCCESS;
454 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
455     FSP_ASSERT(NULL != p_instance_ctrl);
456     FSP_ASSERT(NULL != p_src);
457     FSP_ASSERT(NULL != p_dest);
458     FSP_ASSERT(0 != byte_count);
459     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
460 
461     /* Check that space remaining in page is sufficient for requested write size */
462     uint32_t page_size   = p_instance_ctrl->p_cfg->page_size_bytes;
463     uint32_t page_offset = (uint32_t) p_dest & (page_size - 1);
464     FSP_ERROR_RETURN((page_size - page_offset) >= byte_count, FSP_ERR_INVALID_SIZE);
465 
466  #if !OSPI_B_CFG_DMAC_SUPPORT_ENABLE
467     FSP_ERROR_RETURN((byte_count & (OSPI_B_PRV_CPU_ACCESS_LENGTH - 1)) == 0, FSP_ERR_INVALID_SIZE);
468     FSP_ERROR_RETURN(((uint32_t) p_dest & (OSPI_B_PRV_CPU_ACCESS_ALIGNMENT - 1)) == 0, FSP_ERR_INVALID_ADDRESS);
469   #if defined(__llvm__) && !defined(__ARMCC_VERSION)
470 
471     /* LLVM needs 32-bit aligned data. */
472     FSP_ERROR_RETURN(((uint32_t) p_src & (0x3)) == 0, FSP_ERR_INVALID_ADDRESS);
473   #endif
474  #endif
475 #endif
476 
477     FSP_ERROR_RETURN(false == r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_status_bit),
478                      FSP_ERR_DEVICE_BUSY);
479 
480 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
481     spi_flash_cfg_t       * p_cfg        = (spi_flash_cfg_t *) p_instance_ctrl->p_cfg;
482     ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
483 
484     /* Setup and start DMAC transfer. */
485     transfer_instance_t const * p_transfer = p_cfg_extend->p_lower_lvl_transfer;
486 
487     /* Enable Octa-SPI DMA Bufferable Write */
488     dmac_extended_cfg_t const * p_dmac_extend = p_transfer->p_cfg->p_extend;
489     R_DMAC0_Type              * p_dma_reg     = R_DMAC0 + (sizeof(R_DMAC0_Type) * p_dmac_extend->channel);
490     p_dma_reg->DMBWR = R_DMAC0_DMBWR_BWE_Msk;
491 
492     /* Update the block-mode transfer settings */
493     p_transfer->p_cfg->p_info->p_src  = p_src;
494     p_transfer->p_cfg->p_info->p_dest = p_dest;
495     p_transfer->p_cfg->p_info->transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE;
496     p_transfer->p_cfg->p_info->transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL;
497     p_transfer->p_cfg->p_info->length = (uint16_t) byte_count;
498     err = p_transfer->p_api->reconfigure(p_transfer->p_ctrl, p_transfer->p_cfg->p_info);
499     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
500 
501     r_ospi_b_write_enable(p_instance_ctrl);
502 
503     /* Start DMA */
504     err = p_transfer->p_api->softwareStart(p_transfer->p_ctrl, TRANSFER_START_MODE_REPEAT);
505     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
506 
507     /* Wait for DMAC to complete to maintain deterministic processing and backward compatability */
508     volatile transfer_properties_t transfer_properties = {0U};
509     err = p_transfer->p_api->infoGet(p_transfer->p_ctrl, (transfer_properties_t *) &transfer_properties);
510     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
511     while (FSP_SUCCESS == err && transfer_properties.transfer_length_remaining > 0)
512     {
513         err = p_transfer->p_api->infoGet(p_transfer->p_ctrl, (transfer_properties_t *) &transfer_properties);
514         FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
515     }
516 
517     /* Disable Octa-SPI DMA Bufferable Write */
518     p_dma_reg->DMBWR = 0U;
519 
520     /* If this number of bytes is less than the combination count, push the data to force a transaction. */
521     if (OSPI_B_CFG_COMBINATION_FUNCTION != OSPI_B_COMBINATION_FUNCTION_DISABLE)
522     {
523         uint8_t combo_bytes = (uint8_t) (2U * ((uint8_t) OSPI_B_CFG_COMBINATION_FUNCTION + 1U));
524         if (byte_count < combo_bytes)
525         {
526             R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK;;
527         }
528     }
529 
530 #else
531     uint64_t * p_dest64 = (uint64_t *) ((uint32_t) p_dest & ~(OSPI_B_PRV_CPU_ACCESS_ALIGNMENT - 1));
532     uint64_t * p_src64  = (uint64_t *) p_src;
533 
534     err = r_ospi_b_write_enable(p_instance_ctrl);
535     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
536 
537     while (sizeof(uint64_t) <= byte_count)
538     {
539         /* When combination function is enabled, xSPI master transmits a xSPI
540          * frame with the selected size while the sequential address is incremental. Please read Section 37.3.3.3
541          * Combination Function' of the RA8M1 manual R01UH0994EJ0100. So Basically Enable command should be
542          * sent only once for a single burst(incremented addresses up to set combination size.). */
543         *p_dest64 = *p_src64;
544         p_dest64++;
545         p_src64++;
546         byte_count -= sizeof(uint64_t);
547     }
548 
549     __DMB();
550 
551     R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_PUSH_COMBINATION_WRITE_MASK;
552 #endif
553 
554     return FSP_SUCCESS;
555 }
556 
557 /*******************************************************************************************************************//**
558  * Erase a block or sector of flash.  The byte_count must exactly match one of the erase sizes defined in spi_flash_cfg_t.
559  * For chip erase, byte_count must be SPI_FLASH_ERASE_SIZE_CHIP_ERASE.
560  *
561  * Implements @ref spi_flash_api_t::erase.
562  *
563  * @retval FSP_SUCCESS                 The command to erase the flash was executed successfully.
564  * @retval FSP_ERR_ASSERTION           p_instance_ctrl or p_device_address is NULL, byte_count doesn't match an erase
565  *                                     size defined in spi_flash_cfg_t, or byte_count is set to 0.
566  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
567  * @retval FSP_ERR_DEVICE_BUSY         The device is busy.
568  * @retval FSP_ERR_WRITE_FAILED        Write operation failed.
569  **********************************************************************************************************************/
R_OSPI_B_Erase(spi_flash_ctrl_t * p_ctrl,uint8_t * const p_device_address,uint32_t byte_count)570 fsp_err_t R_OSPI_B_Erase (spi_flash_ctrl_t * p_ctrl, uint8_t * const p_device_address, uint32_t byte_count)
571 {
572     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
573 
574 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
575     FSP_ASSERT(NULL != p_instance_ctrl);
576     FSP_ASSERT(NULL != p_device_address);
577     FSP_ASSERT(0 != byte_count);
578     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
579 #endif
580     spi_flash_cfg_t const * p_cfg             = p_instance_ctrl->p_cfg;
581     uint16_t                erase_command     = 0;
582     const uint32_t          chip_address_base = p_instance_ctrl->channel ?
583                                                 BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS :
584                                                 BSP_FEATURE_OSPI_B_DEVICE_0_START_ADDRESS;
585     uint32_t chip_address = (uint32_t) p_device_address - chip_address_base;
586     bool     send_address = true;
587 
588     ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
589 
590     FSP_ERROR_RETURN(false == r_ospi_b_status_sub(p_instance_ctrl, p_cfg->write_status_bit), FSP_ERR_DEVICE_BUSY);
591 
592     /* Select the erase commands from either the default SPI settings or the protocol settings if provided. */
593     spi_flash_erase_command_t const * p_erase_list = ((NULL != p_cmd_set) && p_cmd_set->p_erase_command_list) ?
594                                                      p_cmd_set->p_erase_command_list : p_cfg->p_erase_command_list;
595     const uint8_t erase_list_length = ((NULL != p_cmd_set) && p_cmd_set->p_erase_command_list) ?
596                                       p_cmd_set->erase_command_list_length : p_cfg->erase_command_list_length;
597 
598     for (uint32_t index = 0; index < erase_list_length; index++)
599     {
600         /* If requested byte_count is supported by underlying flash, store the command. */
601         if (byte_count == p_erase_list[index].size)
602         {
603             if (SPI_FLASH_ERASE_SIZE_CHIP_ERASE == byte_count)
604             {
605                 /* Don't send address for chip erase. */
606                 send_address = false;
607             }
608 
609             erase_command = p_erase_list[index].command;
610             break;
611         }
612     }
613 
614 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
615     FSP_ASSERT(0U != erase_command);
616 #endif
617 
618     fsp_err_t err = r_ospi_b_write_enable(p_instance_ctrl);
619     FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
620 
621     spi_flash_direct_transfer_t direct_command = {0};
622     direct_command.command        = erase_command;
623     direct_command.address        = chip_address;
624     direct_command.address_length = (!send_address) ? 0U :
625                                     ((SPI_FLASH_ADDRESS_BYTES_3 == p_instance_ctrl->p_cfg->address_bytes) ? 3U : 4U);
626     direct_command.command_length = (NULL != p_cmd_set) ? (uint8_t) p_cmd_set->command_bytes : 1U;
627 
628     r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
629 
630     /* If prefetch is enabled, make sure the banks aren't being used and flush the prefetch caches after an erase. */
631 #if OSPI_B_CFG_PREFETCH_FUNCTION
632     FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
633     R_XSPI->BMCTL1 = OSPI_B_PRV_BMCTL1_CLEAR_PREFETCH_MASK;
634 #endif
635 
636     return FSP_SUCCESS;
637 }
638 
639 /*******************************************************************************************************************//**
640  * Gets the write or erase status of the flash.
641  *
642  * Implements @ref spi_flash_api_t::statusGet.
643  *
644  * @retval FSP_SUCCESS                 The write status is in p_status.
645  * @retval FSP_ERR_ASSERTION           p_instance_ctrl or p_status is NULL.
646  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
647  **********************************************************************************************************************/
R_OSPI_B_StatusGet(spi_flash_ctrl_t * p_ctrl,spi_flash_status_t * const p_status)648 fsp_err_t R_OSPI_B_StatusGet (spi_flash_ctrl_t * p_ctrl, spi_flash_status_t * const p_status)
649 {
650     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
651 
652 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
653     FSP_ASSERT(NULL != p_instance_ctrl);
654     FSP_ASSERT(NULL != p_status);
655     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
656 #endif
657 
658     /* Read device status. */
659     p_status->write_in_progress = r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_status_bit);
660 
661     return FSP_SUCCESS;
662 }
663 
664 /*******************************************************************************************************************//**
665  * Selects the bank to access. Use ospi_b_bank_select_t as the bank value.
666  *
667  * Implements @ref spi_flash_api_t::bankSet.
668  *
669  * @retval FSP_ERR_UNSUPPORTED           This function is unsupported.
670  **********************************************************************************************************************/
R_OSPI_B_BankSet(spi_flash_ctrl_t * p_ctrl,uint32_t bank)671 fsp_err_t R_OSPI_B_BankSet (spi_flash_ctrl_t * p_ctrl, uint32_t bank)
672 {
673     FSP_PARAMETER_NOT_USED(p_ctrl);
674     FSP_PARAMETER_NOT_USED(bank);
675 
676     FSP_RETURN(FSP_ERR_UNSUPPORTED);
677 }
678 
679 /*******************************************************************************************************************//**
680  * Sets the SPI protocol.
681  *
682  * Implements @ref spi_flash_api_t::spiProtocolSet.
683  *
684  * @retval FSP_SUCCESS                SPI protocol updated on MPU peripheral.
685  * @retval FSP_ERR_ASSERTION          A required pointer is NULL.
686  * @retval FSP_ERR_NOT_OPEN           Driver is not opened.
687  * @retval FSP_ERR_CALIBRATE_FAILED   Failed to perform auto-calibrate.
688  **********************************************************************************************************************/
R_OSPI_B_SpiProtocolSet(spi_flash_ctrl_t * p_ctrl,spi_flash_protocol_t spi_protocol)689 fsp_err_t R_OSPI_B_SpiProtocolSet (spi_flash_ctrl_t * p_ctrl, spi_flash_protocol_t spi_protocol)
690 {
691     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
692 
693 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
694     FSP_ASSERT(NULL != p_instance_ctrl);
695     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
696 #endif
697     p_instance_ctrl->spi_protocol = spi_protocol;
698 
699     /* Update the SPI protocol and its associated registers. */
700     return r_ospi_b_protocol_specific_settings(p_instance_ctrl);
701 }
702 
703 /*******************************************************************************************************************//**
704  * Close the OSPI driver module.
705  *
706  * Implements @ref spi_flash_api_t::close.
707  *
708  * @retval FSP_SUCCESS             Configuration was successful.
709  * @retval FSP_ERR_ASSERTION       p_instance_ctrl is NULL.
710  * @retval FSP_ERR_NOT_OPEN        Driver is not opened.
711  **********************************************************************************************************************/
R_OSPI_B_Close(spi_flash_ctrl_t * p_ctrl)712 fsp_err_t R_OSPI_B_Close (spi_flash_ctrl_t * p_ctrl)
713 {
714     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
715 
716 #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
717     FSP_ASSERT(NULL != p_instance_ctrl);
718     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
719 #endif
720 
721 #if OSPI_B_CFG_DMAC_SUPPORT_ENABLE
722 
723     /* Initialize transfer instance */
724     ospi_b_extended_cfg_t     * p_cfg_extend = (ospi_b_extended_cfg_t *) (p_instance_ctrl->p_cfg->p_extend);
725     transfer_instance_t const * p_transfer   = p_cfg_extend->p_lower_lvl_transfer;
726     p_transfer->p_api->close(p_transfer->p_ctrl);
727 #endif
728 
729     p_instance_ctrl->open         = 0U;
730     g_ospi_b_channels_open_flags &= ~(1U << p_instance_ctrl->channel);
731 
732     /* Disable clock to the OSPI block if all channels are closed. */
733     if (g_ospi_b_channels_open_flags == 0)
734     {
735         R_BSP_MODULE_STOP(FSP_IP_OSPI, 0U);
736     }
737 
738     return FSP_SUCCESS;
739 }
740 
741 /*******************************************************************************************************************//**
742  * AutoCalibrate the OSPI_B DS signal.
743  *
744  * Implements @ref spi_flash_api_t::autoCalibrate.
745  *
746  * @retval FSP_SUCCESS                 Autocalibration completed successfully.
747  * @retval FSP_ERR_ASSERTION           A required pointer is NULL.
748  * @retval FSP_ERR_NOT_OPEN            Driver is not opened.
749  * @retval FSP_ERR_UNSUPPORTED         Autocalibration support is not enabled.
750  * @retval FSP_ERR_CALIBRATE_FAILED    Failed to perform auto-calibrate.
751  **********************************************************************************************************************/
R_OSPI_B_AutoCalibrate(spi_flash_ctrl_t * const p_ctrl)752 fsp_err_t R_OSPI_B_AutoCalibrate (spi_flash_ctrl_t * const p_ctrl)
753 {
754 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
755     ospi_b_instance_ctrl_t * p_instance_ctrl = (ospi_b_instance_ctrl_t *) p_ctrl;
756 
757  #if OSPI_B_CFG_PARAM_CHECKING_ENABLE
758     FSP_ASSERT(NULL != p_instance_ctrl);
759     FSP_ERROR_RETURN(OSPI_B_PRV_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
760  #endif
761 
762     /* Perform Automatic Calibration to appropriately update WRAPCFG DSSFTCSn field. */
763     if (0 != (OSPI_B_PRV_PROTOCOL_USES_DS_MASK & p_instance_ctrl->spi_protocol))
764     {
765         return r_ospi_b_automatic_calibration_seq(p_instance_ctrl);
766     }
767 
768     return FSP_SUCCESS;
769 #else
770     FSP_PARAMETER_NOT_USED(p_ctrl);
771 
772     return FSP_ERR_UNSUPPORTED;
773 #endif
774 }
775 
776 /*******************************************************************************************************************//**
777  * @} (end addtogroup OSPI)
778  **********************************************************************************************************************/
779 
780 /*******************************************************************************************************************//**
781  * Perform initialization based on SPI/OPI protocol
782  *
783  * @param[in]   p_instance_ctrl    Pointer to OSPI specific control structure
784  *
785  * @retval      FSP_SUCCESS                Protocol based settings completed successfully.
786  * @retval      FSP_ERR_CALIBRATE_FAILED   Auto-Calibration failed.
787  **********************************************************************************************************************/
r_ospi_b_protocol_specific_settings(ospi_b_instance_ctrl_t * p_instance_ctrl)788 static fsp_err_t r_ospi_b_protocol_specific_settings (ospi_b_instance_ctrl_t * p_instance_ctrl)
789 {
790     spi_flash_cfg_t const       * p_cfg    = p_instance_ctrl->p_cfg;
791     ospi_b_extended_cfg_t const * p_extend = (ospi_b_extended_cfg_t const *) p_cfg->p_extend;
792     fsp_err_t ret = FSP_SUCCESS;
793 
794     /* Get the command set for the configured protocol and save it to the control struct. */
795     ospi_b_xspi_command_set_t const * p_cmd_set = r_ospi_b_command_set_get(p_instance_ctrl);
796     p_instance_ctrl->p_cmd_set = p_cmd_set;
797 
798     /* Update the SPI protocol. */
799     R_XSPI->LIOCFGCS_b[p_instance_ctrl->channel].PRTMD = p_instance_ctrl->spi_protocol & R_XSPI_LIOCFGCS_PRTMD_Msk;
800 
801     /* Specifies the read/write commands and Read dummy clocks for Device
802      * (see Section 37.3.8.5 'Flow of Memory-mapping' of the RA8M1 manual R01UH0994EJ0100). */
803     uint32_t cmcfg0 = (OSPI_B_PRV_ADDRESS_REPLACE_ENABLE_BITS) |
804                       (((uint32_t) p_cfg->address_bytes << R_XSPI_CMCFGCS_CMCFG0_ADDSIZE_Pos) &
805                        R_XSPI_CMCFGCS_CMCFG0_ADDSIZE_Msk);
806 
807     /* Use profile 1.0 format always for 8D-8D-8D. */
808     if (SPI_FLASH_PROTOCOL_8D_8D_8D == p_instance_ctrl->spi_protocol)
809     {
810         cmcfg0 |= (1U << R_XSPI_CMCFGCS_CMCFG0_FFMT_Pos);
811     }
812 
813     R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG0 = cmcfg0;
814 
815     /* Grab the appropriate command values. */
816     uint16_t read_command  = (NULL != p_cmd_set) ? p_cmd_set->read_command : p_cfg->read_command;
817     uint16_t write_command = (NULL != p_cmd_set) ? p_cmd_set->page_program_command : p_cfg->page_program_command;
818 
819     /* If no length is specified or if the command byte length is 1, move the command to the upper byte. */
820     if ((p_cmd_set == NULL) || (OSPI_B_COMMAND_BYTES_1 == p_cmd_set->command_bytes))
821     {
822         read_command =
823             (uint16_t) ((read_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
824         write_command =
825             (uint16_t) ((write_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
826     }
827 
828     const uint8_t read_dummy_cycles = (NULL != p_cmd_set) ?
829                                       p_cmd_set->read_dummy_cycles : p_extend->read_dummy_cycles;
830     const uint8_t write_dummy_cycles = (NULL != p_cmd_set) ?
831                                        p_cmd_set->program_dummy_cycles : p_extend->program_dummy_cycles;
832 
833     R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG1 =
834         (uint32_t) (((uint32_t) (read_command) << R_XSPI_CMCFGCS_CMCFG1_RDCMD_Pos) |
835                     ((uint32_t) (read_dummy_cycles << R_XSPI_CMCFGCS_CMCFG1_RDLATE_Pos) &
836                      R_XSPI_CMCFGCS_CMCFG1_RDLATE_Msk));
837 
838     R_XSPI->CMCFGCS[p_instance_ctrl->channel].CMCFG2 =
839         (uint32_t) (((uint32_t) (write_command) << R_XSPI_CMCFGCS_CMCFG2_WRCMD_Pos) |
840                     ((uint32_t) (write_dummy_cycles << R_XSPI_CMCFGCS_CMCFG2_WRLATE_Pos) &
841                      R_XSPI_CMCFGCS_CMCFG2_WRLATE_Msk));
842 
843 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
844     ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
845 
846     /* Perform Automatic Calibration to appropriately update WRAPCFG DSSFTCSn field. */
847     if ((0 == p_cfg_extend->data_latch_delay_clocks) &&
848         (0 != (OSPI_B_PRV_PROTOCOL_USES_DS_MASK & p_instance_ctrl->spi_protocol)))
849     {
850         ret = r_ospi_b_automatic_calibration_seq(p_instance_ctrl);
851     }
852 #endif
853 
854     return ret;
855 }
856 
857 /*******************************************************************************************************************//**
858  * Gets device status.
859  *
860  * @param[in]  p_instance_ctrl         Pointer to a driver handle
861  * @param[in]  bit_pos                 Write-in-progress bit position
862  *
863  * @return True if busy, false if not.
864  **********************************************************************************************************************/
r_ospi_b_status_sub(ospi_b_instance_ctrl_t * p_instance_ctrl,uint8_t bit_pos)865 static bool r_ospi_b_status_sub (ospi_b_instance_ctrl_t * p_instance_ctrl, uint8_t bit_pos)
866 {
867     spi_flash_cfg_t const           * p_cfg          = p_instance_ctrl->p_cfg;
868     spi_flash_direct_transfer_t       direct_command = {0};
869     ospi_b_xspi_command_set_t const * p_cmd_set      = p_instance_ctrl->p_cmd_set;
870 
871     if (NULL == p_cmd_set)
872     {
873         direct_command.command        = p_cfg->status_command;
874         direct_command.command_length = 1U;
875         direct_command.dummy_cycles   = ((ospi_b_extended_cfg_t const *) p_cfg->p_extend)->status_dummy_cycles;
876     }
877     else
878     {
879         direct_command.command        = p_cmd_set->status_command;
880         direct_command.command_length = (uint8_t) p_cmd_set->command_bytes;
881         direct_command.dummy_cycles   = p_cmd_set->status_dummy_cycles;
882     }
883 
884     /* Skip status check if no command was specified. */
885     if (0 == direct_command.command)
886     {
887         return false;
888     }
889 
890     /* 8D-8D-8D mode requires an address for any kind of read. */
891     if (SPI_FLASH_PROTOCOL_8D_8D_8D == p_instance_ctrl->spi_protocol)
892     {
893         direct_command.address_length = (p_cfg->address_bytes + 1U) & OSPI_B_PRV_DIRECT_ADDR_AND_DATA_MASK;
894     }
895 
896     direct_command.data_length = 1U;
897     r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_READ);
898 
899     return (direct_command.data >> bit_pos) & 1U;
900 }
901 
902 /*******************************************************************************************************************//**
903  * Send Write enable command to the OctaFlash
904  *
905  * @param[in]   p_instance_ctrl    Pointer to OSPI specific control structure
906  *
907  * @retval      FSP_SUCCESS                Write operation completed.
908  * @retval      FSP_ERR_WRITE_FAILED       Write operation failed.
909  **********************************************************************************************************************/
r_ospi_b_write_enable(ospi_b_instance_ctrl_t * p_instance_ctrl)910 static fsp_err_t r_ospi_b_write_enable (ospi_b_instance_ctrl_t * p_instance_ctrl)
911 {
912     spi_flash_direct_transfer_t       direct_command = {0};
913     spi_flash_cfg_t const           * p_cfg          = p_instance_ctrl->p_cfg;
914     ospi_b_xspi_command_set_t const * p_cmd_set      = p_instance_ctrl->p_cmd_set;
915 
916     if (NULL == p_cmd_set)
917     {
918         direct_command.command        = p_cfg->write_enable_command;
919         direct_command.command_length = 1U;
920     }
921     else
922     {
923         direct_command.command        = p_cmd_set->write_enable_command;
924         direct_command.command_length = (uint8_t) p_cmd_set->command_bytes;
925     }
926 
927     /* If the command is 0x00, then skip sending the write enable. */
928     if (0 == direct_command.command)
929     {
930         return FSP_SUCCESS;
931     }
932 
933     r_ospi_b_direct_transfer(p_instance_ctrl->channel, &direct_command, SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE);
934 
935     /* In case write enable is not checked, assume write is enabled. */
936     bool write_enabled = true;
937 
938 #if OSPI_B_MAX_WRITE_ENABLE_LOOPS > 0U
939 
940     /* Verify write is enabled. */
941     for (uint32_t i = 0U; i < OSPI_B_MAX_WRITE_ENABLE_LOOPS; i++)
942     {
943         write_enabled = r_ospi_b_status_sub(p_instance_ctrl, p_instance_ctrl->p_cfg->write_enable_bit);
944         if (write_enabled)
945         {
946             break;
947         }
948     }
949 #endif
950 
951     FSP_ERROR_RETURN(write_enabled, FSP_ERR_WRITE_FAILED);
952 
953     return FSP_SUCCESS;
954 }
955 
956 #if OSPI_B_CFG_AUTOCALIBRATION_SUPPORT_ENABLE
957 
958 /*******************************************************************************************************************//**
959  * Perform Automatic Calibration
960  *
961  * @param[in]   p_instance_ctrl    Pointer to OSPI specific control structure
962  *
963  * @retval      FSP_SUCCESS                Auto-Calibration completed successfully.
964  * @retval      FSP_ERR_CALIBRATE_FAILED   Auto-Calibration failed.
965  **********************************************************************************************************************/
r_ospi_b_automatic_calibration_seq(ospi_b_instance_ctrl_t * p_instance_ctrl)966 static fsp_err_t r_ospi_b_automatic_calibration_seq (ospi_b_instance_ctrl_t * p_instance_ctrl)
967 {
968     fsp_err_t               ret          = FSP_SUCCESS;
969     spi_flash_cfg_t       * p_cfg        = (spi_flash_cfg_t *) p_instance_ctrl->p_cfg;
970     ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_cfg->p_extend;
971 
972     ospi_b_xspi_command_set_t const * p_cmd_set = p_instance_ctrl->p_cmd_set;
973 
974     ospi_b_device_number_t channel = p_instance_ctrl->channel;
975 
976     /* Check that calibration is not in progress. */
977     if (0 != R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN)
978     {
979         ret = FSP_ERR_CALIBRATE_FAILED;
980     }
981     else
982     {
983         const uint8_t command_bytes     = (NULL != p_cmd_set) ? (uint8_t) p_cmd_set->command_bytes : 1U;
984         uint16_t      read_command      = (NULL != p_cmd_set) ? p_cmd_set->read_command : p_cfg->read_command;
985         const uint8_t read_dummy_cycles = (NULL != p_cmd_set) ? p_cmd_set->read_dummy_cycles : 0U;
986         const uint8_t address_bytes     = (p_cfg->address_bytes == SPI_FLASH_ADDRESS_BYTES_3) ? 3U : 4U;
987 
988         /* If using 1 command byte, shift the read command over as the peripheral expects. */
989         if (1U == command_bytes)
990         {
991             read_command =
992                 (uint16_t) ((read_command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) <<
993                             OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_SHIFT);
994         }
995 
996         R_XSPI->CCCTLCS[channel].CCCTL1 =
997             (((uint32_t) command_bytes << R_XSPI_CCCTLCS_CCCTL1_CACMDSIZE_Pos) &
998              R_XSPI_CCCTLCS_CCCTL1_CACMDSIZE_Msk) |
999             (((uint32_t) address_bytes << R_XSPI_CCCTLCS_CCCTL1_CAADDSIZE_Pos) & R_XSPI_CCCTLCS_CCCTL1_CAADDSIZE_Msk) |
1000             (OSPI_B_PRV_AUTOCALIBRATION_DATA_SIZE << R_XSPI_CCCTLCS_CCCTL1_CADATASIZE_Pos) |
1001             (OSPI_B_PRV_AUTOCALIBRATION_LATENCY_CYCLES << R_XSPI_CCCTLCS_CCCTL1_CAWRLATE_Pos) |
1002             (((uint32_t) read_dummy_cycles << R_XSPI_CCCTLCS_CCCTL1_CARDLATE_Pos) &
1003              R_XSPI_CCCTLCS_CCCTL1_CARDLATE_Msk);
1004 
1005         R_XSPI->CCCTLCS[channel].CCCTL2 =
1006             (((uint32_t) read_command << R_XSPI_CCCTLCS_CCCTL2_CARDCMD_Pos) &
1007              R_XSPI_CCCTLCS_CCCTL2_CARDCMD_Msk);
1008 
1009         R_XSPI->CCCTLCS[channel].CCCTL3 = (uint32_t) p_cfg_extend->p_autocalibration_preamble_pattern_addr &
1010                                           OSPI_B_PRV_ADDRESS_REPLACE_MASK;
1011         R_XSPI->CCCTLCS[channel].CCCTL4 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_0;
1012         R_XSPI->CCCTLCS[channel].CCCTL5 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_1;
1013         R_XSPI->CCCTLCS[channel].CCCTL6 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_2;
1014         R_XSPI->CCCTLCS[channel].CCCTL7 = OSPI_B_PRV_AUTOCALIBRATION_PREAMBLE_PATTERN_3;
1015 
1016         R_XSPI->CCCTLCS[channel].CCCTL0 =
1017             (OSPI_B_PRV_AUTOCALIBRATION_NO_WRITE_CMD << R_XSPI_CCCTLCS_CCCTL0_CANOWR_Pos) |
1018             (OSPI_B_PRV_AUTOCALIBRATION_FRAME_INTERVAL <<
1019                 R_XSPI_CCCTLCS_CCCTL0_CAITV_Pos) |
1020             (OSPI_B_PRV_AUTOCALIBRATION_SHIFT_DS_END_VALUE <<
1021                 R_XSPI_CCCTLCS_CCCTL0_CASFTEND_Pos);
1022 
1023         /* Automatic Calibration Enable */
1024         R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN = 1;
1025 
1026         /* Check calibration success or failure. */
1027         while ((0 == ((R_XSPI->INTS >> (R_XSPI_INTS_CASUCCS_Pos + channel)) & 0x01)) &&
1028                (0 == ((R_XSPI->INTS >> (R_XSPI_INTS_CAFAILCS_Pos + channel)) & 0x01)))
1029         {
1030             /* Do nothing. */
1031         }
1032 
1033         /* Disable automatic calibration */
1034         R_XSPI->CCCTLCS[channel].CCCTL0_b.CAEN = 0;
1035 
1036         if (1 == ((R_XSPI->INTS >> (R_XSPI_INTS_CASUCCS_Pos + channel)) & 0x01))
1037         {
1038             /* Clear automatic calibration success status */
1039             R_XSPI->INTC = (uint32_t) 1 << (R_XSPI_INTS_CASUCCS_Pos + channel);
1040         }
1041         else if (1 == ((R_XSPI->INTS >> (R_XSPI_INTS_CAFAILCS_Pos + channel)) & 0x01))
1042         {
1043             ret = FSP_ERR_CALIBRATE_FAILED;
1044 
1045             /* Clear automatic calibration failure status */
1046             R_XSPI->INTC = (uint32_t) 1 << (R_XSPI_INTS_CAFAILCS_Pos + channel);
1047         }
1048         else
1049         {
1050             /* Do nothing. */
1051         }
1052     }
1053 
1054     return ret;
1055 }
1056 
1057 #endif
1058 
1059 /*******************************************************************************************************************//**
1060  * Performs direct data transfer with the OctaFlash
1061  *
1062  * @param[in]   channel            Device number to send the direct transfer to
1063  * @param[in]   p_transfer         Pointer to transfer parameters
1064  * @param[in]   direction          Read/Write
1065  **********************************************************************************************************************/
r_ospi_b_direct_transfer(ospi_b_device_number_t channel,spi_flash_direct_transfer_t * const p_transfer,spi_flash_direct_transfer_dir_t direction)1066 static void r_ospi_b_direct_transfer (ospi_b_device_number_t              channel,
1067                                       spi_flash_direct_transfer_t * const p_transfer,
1068                                       spi_flash_direct_transfer_dir_t     direction)
1069 {
1070     /* Setup the manual command control. Cancel any ongoing transactions, direct mode, set channel, 1 transaction. */
1071     R_XSPI->CDCTL0 = ((((uint32_t) channel) << R_XSPI_CDCTL0_CSSEL_Pos) & R_XSPI_CDCTL0_CSSEL_Msk);
1072 
1073     /* Direct Read/Write settings
1074      * (see RA8M1 User's Manual section "Flow of Manual-command Procedure"). */
1075     FSP_HARDWARE_REGISTER_WAIT(R_XSPI->CDCTL0_b.TRREQ, 0);
1076 
1077     uint32_t cdtbuf0 =
1078         (((uint32_t) p_transfer->command_length << R_XSPI_CDBUF_CDT_CMDSIZE_Pos) & R_XSPI_CDBUF_CDT_CMDSIZE_Msk) |
1079         (((uint32_t) p_transfer->address_length << R_XSPI_CDBUF_CDT_ADDSIZE_Pos) & R_XSPI_CDBUF_CDT_ADDSIZE_Msk) |
1080         (((uint32_t) p_transfer->data_length << R_XSPI_CDBUF_CDT_DATASIZE_Pos) & R_XSPI_CDBUF_CDT_DATASIZE_Msk) |
1081         (((uint32_t) p_transfer->dummy_cycles << R_XSPI_CDBUF_CDT_LATE_Pos) & R_XSPI_CDBUF_CDT_LATE_Msk) |
1082         (((uint32_t) direction << R_XSPI_CDBUF_CDT_TRTYPE_Pos) & R_XSPI_CDBUF_CDT_TRTYPE_Msk);
1083 
1084     cdtbuf0 |= (1 == p_transfer->command_length) ?
1085                ((p_transfer->command & OSPI_B_PRV_CDTBUF_CMD_1B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_UPPER_OFFSET) :
1086                ((p_transfer->command & OSPI_B_PRV_CDTBUF_CMD_2B_VALUE_MASK) << OSPI_B_PRV_CDTBUF_CMD_OFFSET);
1087 
1088     R_XSPI->CDBUF[0].CDT = cdtbuf0;
1089 
1090     R_XSPI->CDBUF[0].CDA = p_transfer->address;
1091 
1092     if (SPI_FLASH_DIRECT_TRANSFER_DIR_WRITE == direction)
1093     {
1094         R_XSPI->CDBUF[0].CDD0 = (uint32_t) (p_transfer->data_u64 & UINT32_MAX);
1095         if (p_transfer->data_length > sizeof(uint32_t))
1096         {
1097             R_XSPI->CDBUF[0].CDD1 = (uint32_t) (p_transfer->data_u64 >> OSPI_B_PRV_UINT32_BITS);
1098         }
1099     }
1100 
1101     R_XSPI->CDCTL0_b.TRREQ = 1;
1102     FSP_HARDWARE_REGISTER_WAIT(R_XSPI->INTS_b.CMDCMP, 1);
1103 
1104     if (SPI_FLASH_DIRECT_TRANSFER_DIR_READ == direction)
1105     {
1106         p_transfer->data_u64 = R_XSPI->CDBUF[0].CDD0;
1107         if (p_transfer->data_length > sizeof(uint32_t))
1108         {
1109             p_transfer->data_u64 |= (((uint64_t) R_XSPI->CDBUF[0].CDD1) << OSPI_B_PRV_UINT32_BITS);
1110         }
1111     }
1112 
1113     R_XSPI->INTC = 1 << R_XSPI_INTC_CMDCMPC_Pos;
1114 }
1115 
1116 #if OSPI_B_CFG_XIP_SUPPORT_ENABLE
1117 
1118 /*******************************************************************************************************************//**
1119  * Configures the device to enter or exit XiP mode.
1120  *
1121  * @param[in]   p_instance_ctrl    Pointer to the instance ctrl struct.
1122  * @param[in]   is_entering        true if entering XiP mode, false if exiting.
1123  **********************************************************************************************************************/
r_ospi_b_xip(ospi_b_instance_ctrl_t * p_instance_ctrl,bool is_entering)1124 static void r_ospi_b_xip (ospi_b_instance_ctrl_t * p_instance_ctrl, bool is_entering)
1125 {
1126     const spi_flash_cfg_t * p_cfg                = p_instance_ctrl->p_cfg;
1127     volatile uint8_t      * p_dummy_read_address = (volatile uint8_t *)
1128                                                    ((OSPI_B_DEVICE_NUMBER_0 == p_instance_ctrl->channel) ?
1129                                                     BSP_FEATURE_OSPI_B_DEVICE_0_START_ADDRESS :
1130                                                     BSP_FEATURE_OSPI_B_DEVICE_1_START_ADDRESS);
1131     volatile uint8_t dummy_read = 0;
1132 
1133     FSP_PARAMETER_NOT_USED(dummy_read); // Suppress variable not used error.
1134 
1135     /* Clear the pre-fetch buffer for this bank so the next read is guaranteed to use the XiP code. */
1136  #if OSPI_B_CFG_PREFETCH_FUNCTION
1137     R_XSPI->BMCTL1 |= 0x03U << R_XSPI_BMCTL1_PBUFCLRCH_Pos;
1138  #endif
1139 
1140     /* Wait for any on-going access to complete. */
1141     FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1142 
1143     if (is_entering)
1144     {
1145         /* Change memory-mapping to read-only mode. */
1146         R_XSPI->BMCTL0 = OSPI_B_PRV_BMCTL0_READ_ONLY_VALUE;
1147 
1148         /* Configure XiP codes and enable. */
1149         const uint32_t cmctlch = R_XSPI_CMCTLCH_XIPEN_Msk |
1150                                  ((uint32_t) (p_cfg->xip_enter_command << R_XSPI_CMCTLCH_XIPENCODE_Pos)) |
1151                                  ((uint32_t) (p_cfg->xip_exit_command << R_XSPI_CMCTLCH_XIPEXCODE_Pos));
1152 
1153         /* XiP enter/exit codes are configured only for memory mapped operations and affects both OSPI slave channels. */
1154         R_XSPI->CMCTLCH[0] = cmctlch;
1155         R_XSPI->CMCTLCH[1] = cmctlch;
1156 
1157         /* Perform a read to send the enter code. All further reads will use the enter code and will not send a read command code. */
1158         dummy_read = *p_dummy_read_address;
1159 
1160         /* Wait for the read to complete. */
1161         FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1162     }
1163     else
1164     {
1165         /* Disable XiP. */
1166         R_XSPI->CMCTLCH[0] &= ~R_XSPI_CMCTLCH_XIPEN_Msk;
1167         R_XSPI->CMCTLCH[1] &= ~R_XSPI_CMCTLCH_XIPEN_Msk;
1168 
1169         /* Perform a read to send the exit code. All further reads will not send an exit code. */
1170         dummy_read = *p_dummy_read_address;
1171 
1172         /* Wait for the read to complete. */
1173         FSP_HARDWARE_REGISTER_WAIT((R_XSPI->COMSTT & OSPI_B_PRV_COMSTT_MEMACCCH_MASK), 0);
1174 
1175         /* Change memory-mapping back to R/W mode. */
1176         R_XSPI->BMCTL0 = OSPI_B_PRV_BMCTL0_READ_WRITE_VALUE;
1177     }
1178 }
1179 
1180 #endif
1181 
1182 /*******************************************************************************************************************//**
1183  * Gets the xspi command set for a protocol mode if it exists.
1184  *
1185  * @param[in]   p_instance_ctrl    Pointer to the instance ctrl struct.
1186  * @return Pointer to the command set, or NULL if it is normal SPI or has not been configured.
1187  **********************************************************************************************************************/
r_ospi_b_command_set_get(ospi_b_instance_ctrl_t * p_instance_ctrl)1188 static ospi_b_xspi_command_set_t const * r_ospi_b_command_set_get (ospi_b_instance_ctrl_t * p_instance_ctrl)
1189 {
1190     ospi_b_extended_cfg_t * p_cfg_extend = (ospi_b_extended_cfg_t *) p_instance_ctrl->p_cfg->p_extend;
1191 
1192     if ((SPI_FLASH_PROTOCOL_EXTENDED_SPI == p_instance_ctrl->spi_protocol) ||
1193         (0 == p_cfg_extend->xspi_command_set_list_length))
1194     {
1195 
1196         /* Normal SPI and modes not defined fallback to the commands defined in the spi_flash_cfg_t struct. */
1197         return NULL;
1198     }
1199 
1200     for (uint32_t i = 0; i < p_cfg_extend->xspi_command_set_list_length; i++)
1201     {
1202         if (p_cfg_extend->p_xspi_command_set_list[i].protocol == p_instance_ctrl->spi_protocol)
1203         {
1204             return &p_cfg_extend->p_xspi_command_set_list[i];
1205         }
1206     }
1207 
1208     /* If the protocol isn't found, return NULL. */
1209     return NULL;
1210 }
1211 
1212 #if OSPI_B_CFG_DOTF_SUPPORT_ENABLE
1213 
1214 /*******************************************************************************************************************//**
1215  * Configures the device for DOTF operation.
1216  *
1217  * @param[in]   p_dotf_cfg    Pointer to the instance ctrl struct.
1218  * @retval      FSP_SUCCESS                       DOTF configuration completed successfully.
1219  * @retval      FSP_ERR_CRYPTO_SCE_KEY_SET_FAIL   Key initialization failed.
1220  * @retval      FSP_ERR_CRYPTO_SCE_FAIL           Key wrapping failed.
1221  * @retval      FSP_ERR_INVALID_ARGUMENT          Invalid key type argument.
1222  **********************************************************************************************************************/
r_ospi_b_dotf_setup(ospi_b_dotf_cfg_t * p_dotf_cfg)1223 static fsp_err_t r_ospi_b_dotf_setup (ospi_b_dotf_cfg_t * p_dotf_cfg)
1224 {
1225     fsp_err_t     sce_ret = FSP_SUCCESS;
1226     uint32_t      seed[2] = {0};
1227     uint32_t      wrapped_key[HW_SCE_AES256_KEY_INDEX_WORD_SIZE] = {0};
1228     sce_oem_cmd_t key_cmd = SCE_OEM_CMD_AES128;
1229 
1230     if((((uint32_t) &(p_dotf_cfg->p_key[0])) & 0x03) && (((uint32_t) &(p_dotf_cfg->p_iv[0])) & 0x03))
1231     {
1232         return FSP_ERR_INVALID_ARGUMENT;
1233     }
1234 
1235     if (OSPI_B_DOTF_AES_KEY_TYPE_128 == p_dotf_cfg->key_type)
1236     {
1237         key_cmd = SCE_OEM_CMD_AES128;
1238     }
1239     else if (OSPI_B_DOTF_AES_KEY_TYPE_192 == p_dotf_cfg->key_type)
1240     {
1241         key_cmd = SCE_OEM_CMD_AES192;
1242     }
1243     else if (OSPI_B_DOTF_AES_KEY_TYPE_256 == p_dotf_cfg->key_type)
1244     {
1245         key_cmd = SCE_OEM_CMD_AES256;
1246     }
1247     else
1248     {
1249         return FSP_ERR_INVALID_ARGUMENT;
1250     }
1251 
1252     /* Initialize the crypto engine. */
1253     HW_SCE_McuSpecificInit();
1254 
1255     /* Copnvert plaintext key to wrapped form. */
1256     sce_ret =
1257         HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
1258                                           key_cmd,
1259                                           NULL,
1260                                           NULL,
1261                                           (uint8_t *) p_dotf_cfg->p_key,
1262                                           (uint32_t *) wrapped_key);
1263     if (FSP_SUCCESS != sce_ret)
1264     {
1265         return sce_ret;
1266     }
1267 
1268     /* Use wrapped key with DOTF AES Engine. */
1269     if (SCE_OEM_CMD_AES128 == key_cmd)
1270     {
1271         sce_ret = HW_SCE_Aes128OutputKeyForDotfSub(wrapped_key, seed);
1272     }
1273     else if (SCE_OEM_CMD_AES192 == key_cmd)
1274     {
1275         sce_ret = HW_SCE_Aes192OutputKeyForDotfSub(wrapped_key, seed);
1276     }
1277     else
1278     {
1279         sce_ret = HW_SCE_Aes256OutputKeyForDotfSub(wrapped_key, seed);
1280     }
1281 
1282     if (sce_ret == FSP_SUCCESS)
1283     {
1284         /* Disable byte order conversion. */
1285         R_DOTF->REG00 = (OSPI_B_PRV_DOTF_REG00_RESET_VALUE | R_DOTF_REG00_B09_Msk);
1286 
1287         /* Load the IV. */
1288         R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[0]);
1289         R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[1]);
1290         R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[2]);
1291         R_DOTF->REG03 = change_endian_long(p_dotf_cfg->p_iv[3]);
1292     }
1293 
1294     /* Set the start and end area for DOTF conversion. */
1295     R_DOTF->CONVAREAST = (uint32_t) p_dotf_cfg->p_start_addr;
1296     R_DOTF->CONVAREAD  = (uint32_t) p_dotf_cfg->p_end_addr;
1297 
1298     return sce_ret;
1299 }
1300 
1301 #endif
1302