This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 07fd1cac48c5411fb98cd7ebb21af109ddb2fa21 Author: alexcekay <[email protected]> AuthorDate: Mon Nov 2 10:54:22 2026 +0100 arch/arm/imx9: Add FlexSPI controller driver Copy of arch/arm64/src/imx9/imx9_flexspi.{c,h} and hardware/imx9_flexspi.h for the i.MX9 Cortex-M cores, so the i.MX95 M7 can use the FlexSPI controller. The only changes are arm_internal.h instead of arm64_internal.h and the clock setup in imx9_flexspi_initialize(). The arm64 driver programs the CCM directly with i.MX93 clock IDs, which do not exist for the i.MX95 M7, where the clock root is set over SCMI. Like the other arm/imx9 drivers, it now calls imx9_configure_clock() with FLEXSPI1_CLK, which the board defines in board.h. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: alexcekay <[email protected]> --- arch/arm/src/imx9/CMakeLists.txt | 4 + arch/arm/src/imx9/Kconfig | 4 + arch/arm/src/imx9/Make.defs | 4 + arch/arm/src/imx9/hardware/imx9_flexspi.h | 600 ++++++++++++++ arch/arm/src/imx9/imx9_flexspi.c | 1259 +++++++++++++++++++++++++++++ arch/arm/src/imx9/imx9_flexspi.h | 570 +++++++++++++ 6 files changed, 2441 insertions(+) diff --git a/arch/arm/src/imx9/CMakeLists.txt b/arch/arm/src/imx9/CMakeLists.txt index 5db7dae1a4f..a8cf0a64d85 100644 --- a/arch/arm/src/imx9/CMakeLists.txt +++ b/arch/arm/src/imx9/CMakeLists.txt @@ -73,6 +73,10 @@ if(CONFIG_IMX9_FLEXIO) list(APPEND SRCS imx9_flexio.c) endif() +if(CONFIG_IMX9_FLEXSPI) + list(APPEND SRCS imx9_flexspi.c) +endif() + if(CONFIG_IMX9_TPM_PWM) list(APPEND SRCS imx9_tpm_pwm.c) endif() diff --git a/arch/arm/src/imx9/Kconfig b/arch/arm/src/imx9/Kconfig index 897dfa913f7..cc0a1da71c9 100644 --- a/arch/arm/src/imx9/Kconfig +++ b/arch/arm/src/imx9/Kconfig @@ -340,6 +340,10 @@ config FLEXCAN5_DATA_SAMPLEP endmenu # IMX9_FLEXCAN5 +config IMX9_FLEXSPI + bool "FlexSPI1" + default n + config IMX9_SAR_ADC bool "SAR ADC" default n diff --git a/arch/arm/src/imx9/Make.defs b/arch/arm/src/imx9/Make.defs index bb330b7f1ad..400e82df5cb 100644 --- a/arch/arm/src/imx9/Make.defs +++ b/arch/arm/src/imx9/Make.defs @@ -74,6 +74,10 @@ ifeq ($(CONFIG_IMX9_FLEXIO),y) CHIP_CSRCS += imx9_flexio.c endif +ifeq ($(CONFIG_IMX9_FLEXSPI),y) + CHIP_CSRCS += imx9_flexspi.c +endif + ifeq ($(CONFIG_IMX9_TPM_PWM),y) CHIP_CSRCS += imx9_tpm_pwm.c endif diff --git a/arch/arm/src/imx9/hardware/imx9_flexspi.h b/arch/arm/src/imx9/hardware/imx9_flexspi.h new file mode 100644 index 00000000000..5f2fd757ddd --- /dev/null +++ b/arch/arm/src/imx9/hardware/imx9_flexspi.h @@ -0,0 +1,600 @@ +/**************************************************************************** + * arch/arm/src/imx9/hardware/imx9_flexspi.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX9_HARDWARE_IMX9_FLEXSPI_H +#define __ARCH_ARM_SRC_IMX9_HARDWARE_IMX9_FLEXSPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include "hardware/imx9_memorymap.h" + +/* FLEXSPI - Register Layout Typedef */ + +struct flexspi_type_s +{ + volatile uint32_t MCR0; /* Module Control Register 0, offset: 0x0 */ + volatile uint32_t MCR1; /* Module Control Register 1, offset: 0x4 */ + volatile uint32_t MCR2; /* Module Control Register 2, offset: 0x8 */ + volatile uint32_t AHBCR; /* AHB Bus Control Register, offset: 0xc */ + volatile uint32_t INTEN; /* Interrupt Enable Register, offset: 0x10 */ + volatile uint32_t INTR; /* Interrupt Register, offset: 0x14 */ + volatile uint32_t LUTKEY; /* LUT Key Register, offset: 0x18 */ + volatile uint32_t LUTCR; /* LUT Control Register, offset: 0x1c */ + volatile uint32_t AHBRXBUFCR0[8]; /* AHB RX Buffer 0 Control Register 0..AHB RX Buffer 7 Control Register 0, array offset: 0x20, array step: 0x4 */ + volatile uint8_t RESERVED_0[32]; + volatile uint32_t FLSHCR0[4]; /* Flash A1 Control Register 0..Flash B2 Control Register 0, array offset: 0x60, array step: 0x4 */ + volatile uint32_t FLSHCR1[4]; /* Flash A1 Control Register 1..Flash B2 Control Register 1, array offset: 0x70, array step: 0x4 */ + volatile uint32_t FLSHCR2[4]; /* Flash A1 Control Register 2..Flash B2 Control Register 2, array offset: 0x80, array step: 0x4 */ + uint8_t RESERVED_1[4]; + volatile uint32_t FLSHCR4; /* Flash Control Register 4, offset: 0x94 */ + uint8_t RESERVED_2[8]; + volatile uint32_t IPCR0; /* IP Control Register 0, offset: 0xa0 */ + volatile uint32_t IPCR1; /* IP Control Register 1, offset: 0xa4 */ + uint8_t RESERVED_3[8]; + volatile uint32_t IPCMD; /* IP Command Register, offset: 0xb0 */ + uint8_t RESERVED_4[4]; + volatile uint32_t IPRXFCR; /* IP RX FIFO Control Register, offset: 0xb8 */ + volatile uint32_t IPTXFCR; /* IP TX FIFO Control Register, offset: 0xbc */ + volatile uint32_t DLLCR[2]; /* DLL Control Register 0, array offset: 0xc0, array step: 0x4 */ + uint8_t RESERVED_5[24]; + volatile uint32_t STS0; /* Status Register 0, offset: 0xe0 */ + volatile uint32_t STS1; /* Status Register 1, offset: 0xe4 */ + volatile uint32_t STS2; /* Status Register 2, offset: 0xe8 */ + volatile uint32_t AHBSPNDSTS; /* AHB Suspend Status Register, offset: 0xec */ + volatile uint32_t IPRXFSTS; /* IP RX FIFO Status Register, offset: 0xf0 */ + volatile uint32_t IPTXFSTS; /* IP TX FIFO Status Register, offset: 0xf4 */ + uint8_t RESERVED_6[8]; + volatile uint32_t RFDR[32]; /* IP RX FIFO Data Register 0..IP RX FIFO Data Register 31, array offset: 0x100, array step: 0x4 */ + volatile uint32_t TFDR[32]; /* IP TX FIFO Data Register 0..IP TX FIFO Data Register 31, array offset: 0x180, array step: 0x4 */ + volatile uint32_t LUT[128]; /* LUT 0..LUT 127, array offset: 0x200, array step: 0x4 */ +}; + +#define IMX9_FLEXSPI_AHBBUFREGIONSTART0_OFFSET 0x440 +#define IMX9_FLEXSPI_AHBBUFREGIONEND0_OFFSET 0x444 +#define IMX9_FLEXSPI_AHBBUFREGIONSTART1_OFFSET 0x448 +#define IMX9_FLEXSPI_AHBBUFREGIONEND1_OFFSET 0x44C +#define IMX9_FLEXSPI_AHBBUFREGIONSTART2_OFFSET 0x450 +#define IMX9_FLEXSPI_AHBBUFREGIONEND2_OFFSET 0x454 +#define IMX9_FLEXSPI_AHBBUFREGIONSTART3_OFFSET 0x458 +#define IMX9_FLEXSPI_AHBBUFREGIONEND3_OFFSET 0x45C + +#define IMX9_FLEXSPI1_AHBBUFREGIONSTART0 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONSTART0_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONEND0 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONEND0_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONSTART1 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONSTART1_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONEND1 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONEND1_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONSTART2 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONSTART2_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONEND2 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONEND2_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONSTART3 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONSTART3_OFFSET) +#define IMX9_FLEXSPI1_AHBBUFREGIONEND3 (IMX9_FLEXSPI_BASE + IMX9_FLEXSPI_AHBBUFREGIONEND3_OFFSET) + +/* MCR0 - Module Control Register 0 */ + +#define FLEXSPI_MCR0_SWRESET_MASK (0x1u) +#define FLEXSPI_MCR0_SWRESET_SHIFT (0u) + +/* SWRESET - Software Reset */ + +#define FLEXSPI_MCR0_SWRESET(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_SWRESET_SHIFT)) & FLEXSPI_MCR0_SWRESET_MASK) +#define FLEXSPI_MCR0_MDIS_MASK (0x2u) +#define FLEXSPI_MCR0_MDIS_SHIFT (1u) + +/* MDIS - Module Disable */ + +#define FLEXSPI_MCR0_MDIS(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_MDIS_SHIFT)) & FLEXSPI_MCR0_MDIS_MASK) +#define FLEXSPI_MCR0_RXCLKSRC_MASK (0x30u) +#define FLEXSPI_MCR0_RXCLKSRC_SHIFT (4u) + +#define FLEXSPI_MCR0_RXCLKSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_RXCLKSRC_SHIFT)) & FLEXSPI_MCR0_RXCLKSRC_MASK) +#define FLEXSPI_MCR0_ARDFEN_MASK (0x40u) +#define FLEXSPI_MCR0_ARDFEN_SHIFT (6u) + +#define FLEXSPI_MCR0_ARDFEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_ARDFEN_SHIFT)) & FLEXSPI_MCR0_ARDFEN_MASK) +#define FLEXSPI_MCR0_ATDFEN_MASK (0x80u) +#define FLEXSPI_MCR0_ATDFEN_SHIFT (7u) + +#define FLEXSPI_MCR0_ATDFEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_ATDFEN_SHIFT)) & FLEXSPI_MCR0_ATDFEN_MASK) +#define FLEXSPI_MCR0_HSEN_MASK (0x800u) +#define FLEXSPI_MCR0_HSEN_SHIFT (11u) + +#define FLEXSPI_MCR0_HSEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_HSEN_SHIFT)) & FLEXSPI_MCR0_HSEN_MASK) +#define FLEXSPI_MCR0_DOZEEN_MASK (0x1000u) +#define FLEXSPI_MCR0_DOZEEN_SHIFT (12u) + +#define FLEXSPI_MCR0_DOZEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_DOZEEN_SHIFT)) & FLEXSPI_MCR0_DOZEEN_MASK) +#define FLEXSPI_MCR0_COMBINATIONEN_MASK (0x2000u) +#define FLEXSPI_MCR0_COMBINATIONEN_SHIFT (13u) + +#define FLEXSPI_MCR0_COMBINATIONEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_COMBINATIONEN_SHIFT)) & FLEXSPI_MCR0_COMBINATIONEN_MASK) +#define FLEXSPI_MCR0_SCKFREERUNEN_MASK (0x4000u) +#define FLEXSPI_MCR0_SCKFREERUNEN_SHIFT (14u) + +#define FLEXSPI_MCR0_SCKFREERUNEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_SCKFREERUNEN_SHIFT)) & FLEXSPI_MCR0_SCKFREERUNEN_MASK) +#define FLEXSPI_MCR0_IPGRANTWAIT_MASK (0xff0000u) +#define FLEXSPI_MCR0_IPGRANTWAIT_SHIFT (16u) + +#define FLEXSPI_MCR0_IPGRANTWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_IPGRANTWAIT_SHIFT)) & FLEXSPI_MCR0_IPGRANTWAIT_MASK) +#define FLEXSPI_MCR0_AHBGRANTWAIT_MASK (0xff000000u) +#define FLEXSPI_MCR0_AHBGRANTWAIT_SHIFT (24u) + +#define FLEXSPI_MCR0_AHBGRANTWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR0_AHBGRANTWAIT_SHIFT)) & FLEXSPI_MCR0_AHBGRANTWAIT_MASK) + +#define FLEXSPI_MCR1_AHBBUSWAIT_MASK (0xffffu) +#define FLEXSPI_MCR1_AHBBUSWAIT_SHIFT (0u) +#define FLEXSPI_MCR1_AHBBUSWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR1_AHBBUSWAIT_SHIFT)) & FLEXSPI_MCR1_AHBBUSWAIT_MASK) +#define FLEXSPI_MCR1_SEQWAIT_MASK (0xffff0000u) +#define FLEXSPI_MCR1_SEQWAIT_SHIFT (16u) +#define FLEXSPI_MCR1_SEQWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR1_SEQWAIT_SHIFT)) & FLEXSPI_MCR1_SEQWAIT_MASK) + +#define FLEXSPI_MCR2_CLRAHBBUFOPT_MASK (0x800u) +#define FLEXSPI_MCR2_CLRAHBBUFOPT_SHIFT (11u) + +#define FLEXSPI_MCR2_CLRAHBBUFOPT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR2_CLRAHBBUFOPT_SHIFT)) & FLEXSPI_MCR2_CLRAHBBUFOPT_MASK) +#define FLEXSPI_MCR2_CLRLEARNPHASE_MASK (0x4000u) +#define FLEXSPI_MCR2_CLRLEARNPHASE_SHIFT (14u) + +#define FLEXSPI_MCR2_CLRLEARNPHASE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR2_CLRLEARNPHASE_SHIFT)) & FLEXSPI_MCR2_CLRLEARNPHASE_MASK) +#define FLEXSPI_MCR2_SAMEDEVICEEN_MASK (0x8000u) +#define FLEXSPI_MCR2_SAMEDEVICEEN_SHIFT (15u) + +#define FLEXSPI_MCR2_SAMEDEVICEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR2_SAMEDEVICEEN_SHIFT)) & FLEXSPI_MCR2_SAMEDEVICEEN_MASK) +#define FLEXSPI_MCR2_SCKBDIFFOPT_MASK (0x80000u) +#define FLEXSPI_MCR2_SCKBDIFFOPT_SHIFT (19u) + +#define FLEXSPI_MCR2_SCKBDIFFOPT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR2_SCKBDIFFOPT_SHIFT)) & FLEXSPI_MCR2_SCKBDIFFOPT_MASK) +#define FLEXSPI_MCR2_RESUMEWAIT_MASK (0xff000000u) +#define FLEXSPI_MCR2_RESUMEWAIT_SHIFT (24u) + +#define FLEXSPI_MCR2_RESUMEWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_MCR2_RESUMEWAIT_SHIFT)) & FLEXSPI_MCR2_RESUMEWAIT_MASK) + +#define FLEXSPI_AHBCR_APAREN_MASK (0x1u) +#define FLEXSPI_AHBCR_APAREN_SHIFT (0u) + +#define FLEXSPI_AHBCR_APAREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBCR_APAREN_SHIFT)) & FLEXSPI_AHBCR_APAREN_MASK) +#define FLEXSPI_AHBCR_CACHABLEEN_MASK (0x8u) +#define FLEXSPI_AHBCR_CACHABLEEN_SHIFT (3u) + +#define FLEXSPI_AHBCR_CACHABLEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBCR_CACHABLEEN_SHIFT)) & FLEXSPI_AHBCR_CACHABLEEN_MASK) +#define FLEXSPI_AHBCR_BUFFERABLEEN_MASK (0x10u) +#define FLEXSPI_AHBCR_BUFFERABLEEN_SHIFT (4u) + +#define FLEXSPI_AHBCR_BUFFERABLEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBCR_BUFFERABLEEN_SHIFT)) & FLEXSPI_AHBCR_BUFFERABLEEN_MASK) +#define FLEXSPI_AHBCR_PREFETCHEN_MASK (0x20u) +#define FLEXSPI_AHBCR_PREFETCHEN_SHIFT (5u) + +#define FLEXSPI_AHBCR_PREFETCHEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBCR_PREFETCHEN_SHIFT)) & FLEXSPI_AHBCR_PREFETCHEN_MASK) +#define FLEXSPI_AHBCR_READADDROPT_MASK (0x40u) +#define FLEXSPI_AHBCR_READADDROPT_SHIFT (6u) + +#define FLEXSPI_AHBCR_READADDROPT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBCR_READADDROPT_SHIFT)) & FLEXSPI_AHBCR_READADDROPT_MASK) + +#define FLEXSPI_INTEN_IPCMDDONEEN_MASK (0x1u) +#define FLEXSPI_INTEN_IPCMDDONEEN_SHIFT (0u) + +#define FLEXSPI_INTEN_IPCMDDONEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_IPCMDDONEEN_SHIFT)) & FLEXSPI_INTEN_IPCMDDONEEN_MASK) +#define FLEXSPI_INTEN_IPCMDGEEN_MASK (0x2u) +#define FLEXSPI_INTEN_IPCMDGEEN_SHIFT (1u) + +#define FLEXSPI_INTEN_IPCMDGEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_IPCMDGEEN_SHIFT)) & FLEXSPI_INTEN_IPCMDGEEN_MASK) +#define FLEXSPI_INTEN_AHBCMDGEEN_MASK (0x4u) +#define FLEXSPI_INTEN_AHBCMDGEEN_SHIFT (2u) + +#define FLEXSPI_INTEN_AHBCMDGEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_AHBCMDGEEN_SHIFT)) & FLEXSPI_INTEN_AHBCMDGEEN_MASK) +#define FLEXSPI_INTEN_IPCMDERREN_MASK (0x8u) +#define FLEXSPI_INTEN_IPCMDERREN_SHIFT (3u) + +#define FLEXSPI_INTEN_IPCMDERREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_IPCMDERREN_SHIFT)) & FLEXSPI_INTEN_IPCMDERREN_MASK) +#define FLEXSPI_INTEN_AHBCMDERREN_MASK (0x10u) +#define FLEXSPI_INTEN_AHBCMDERREN_SHIFT (4u) + +#define FLEXSPI_INTEN_AHBCMDERREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_AHBCMDERREN_SHIFT)) & FLEXSPI_INTEN_AHBCMDERREN_MASK) +#define FLEXSPI_INTEN_IPRXWAEN_MASK (0x20u) +#define FLEXSPI_INTEN_IPRXWAEN_SHIFT (5u) + +#define FLEXSPI_INTEN_IPRXWAEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_IPRXWAEN_SHIFT)) & FLEXSPI_INTEN_IPRXWAEN_MASK) +#define FLEXSPI_INTEN_IPTXWEEN_MASK (0x40u) +#define FLEXSPI_INTEN_IPTXWEEN_SHIFT (6u) + +#define FLEXSPI_INTEN_IPTXWEEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_IPTXWEEN_SHIFT)) & FLEXSPI_INTEN_IPTXWEEN_MASK) +#define FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK (0x100u) +#define FLEXSPI_INTEN_SCKSTOPBYRDEN_SHIFT (8u) + +#define FLEXSPI_INTEN_SCKSTOPBYRDEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_SCKSTOPBYRDEN_SHIFT)) & FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK) +#define FLEXSPI_INTEN_SCKSTOPBYWREN_MASK (0x200u) +#define FLEXSPI_INTEN_SCKSTOPBYWREN_SHIFT (9u) +#define FLEXSPI_INTEN_SCKSTOPBYWREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_SCKSTOPBYWREN_SHIFT)) & FLEXSPI_INTEN_SCKSTOPBYWREN_MASK) + +#define FLEXSPI_INTEN_AHBBUSERROREN_MASK (0x400u) +#define FLEXSPI_INTEN_AHBBUSERROREN_SHIFT (10u) +#define FLEXSPI_INTEN_AHBBUSERROREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_AHBBUSERROREN_SHIFT)) & FLEXSPI_INTEN_AHBBUSERROREN_MASK) + +#define FLEXSPI_INTEN_SEQTIMEOUTEN_MASK (0x800u) +#define FLEXSPI_INTEN_SEQTIMEOUTEN_SHIFT (11u) +#define FLEXSPI_INTEN_SEQTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_SEQTIMEOUTEN_SHIFT)) & FLEXSPI_INTEN_SEQTIMEOUTEN_MASK) + +#define FLEXSPI_INTEN_KEYDONE_MASK (0x1000u) +#define FLEXSPI_INTEN_KEYDONE_SHIFT (12u) +#define FLEXSPI_INTEN_KEYDONE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_KEYDONE_SHIFT)) & FLEXSPI_INTEN_KEYDONE_MASK) + +#define FLEXSPI_INTEN_KEYERROR_MASK (0x2000u) +#define FLEXSPI_INTEN_KEYERROR_SHIFT (13u) +#define FLEXSPI_INTEN_KEYERROR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTEN_KEYERROR_SHIFT)) & FLEXSPI_INTEN_KEYERROR_MASK) + +#define FLEXSPI_INTR_IPCMDDONE_MASK (0x1u) +#define FLEXSPI_INTR_IPCMDDONE_SHIFT (0u) + +#define FLEXSPI_INTR_IPCMDDONE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_IPCMDDONE_SHIFT)) & FLEXSPI_INTR_IPCMDDONE_MASK) +#define FLEXSPI_INTR_IPCMDGE_MASK (0x2u) +#define FLEXSPI_INTR_IPCMDGE_SHIFT (1u) + +#define FLEXSPI_INTR_IPCMDGE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_IPCMDGE_SHIFT)) & FLEXSPI_INTR_IPCMDGE_MASK) +#define FLEXSPI_INTR_AHBCMDGE_MASK (0x4u) +#define FLEXSPI_INTR_AHBCMDGE_SHIFT (2u) + +#define FLEXSPI_INTR_AHBCMDGE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_AHBCMDGE_SHIFT)) & FLEXSPI_INTR_AHBCMDGE_MASK) +#define FLEXSPI_INTR_IPCMDERR_MASK (0x8u) +#define FLEXSPI_INTR_IPCMDERR_SHIFT (3u) + +#define FLEXSPI_INTR_IPCMDERR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_IPCMDERR_SHIFT)) & FLEXSPI_INTR_IPCMDERR_MASK) +#define FLEXSPI_INTR_AHBCMDERR_MASK (0x10u) +#define FLEXSPI_INTR_AHBCMDERR_SHIFT (4u) + +#define FLEXSPI_INTR_AHBCMDERR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_AHBCMDERR_SHIFT)) & FLEXSPI_INTR_AHBCMDERR_MASK) +#define FLEXSPI_INTR_IPRXWA_MASK (0x20u) +#define FLEXSPI_INTR_IPRXWA_SHIFT (5u) + +#define FLEXSPI_INTR_IPRXWA(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_IPRXWA_SHIFT)) & FLEXSPI_INTR_IPRXWA_MASK) +#define FLEXSPI_INTR_IPTXWE_MASK (0x40u) +#define FLEXSPI_INTR_IPTXWE_SHIFT (6u) + +#define FLEXSPI_INTR_IPTXWE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_IPTXWE_SHIFT)) & FLEXSPI_INTR_IPTXWE_MASK) +#define FLEXSPI_INTR_SCKSTOPBYRD_MASK (0x100u) +#define FLEXSPI_INTR_SCKSTOPBYRD_SHIFT (8u) + +#define FLEXSPI_INTR_SCKSTOPBYRD(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_SCKSTOPBYRD_SHIFT)) & FLEXSPI_INTR_SCKSTOPBYRD_MASK) +#define FLEXSPI_INTR_SCKSTOPBYWR_MASK (0x200u) +#define FLEXSPI_INTR_SCKSTOPBYWR_SHIFT (9u) + +#define FLEXSPI_INTR_SCKSTOPBYWR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_SCKSTOPBYWR_SHIFT)) & FLEXSPI_INTR_SCKSTOPBYWR_MASK) +#define FLEXSPI_INTR_AHBBUSTIMEOUT_MASK (0x400u) +#define FLEXSPI_INTR_AHBBUSTIMEOUT_SHIFT (10u) + +#define FLEXSPI_INTR_AHBBUSTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_AHBBUSTIMEOUT_SHIFT)) & FLEXSPI_INTR_AHBBUSTIMEOUT_MASK) +#define FLEXSPI_INTR_SEQTIMEOUT_MASK (0x800u) +#define FLEXSPI_INTR_SEQTIMEOUT_SHIFT (11u) + +#define FLEXSPI_INTR_SEQTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_SEQTIMEOUT_SHIFT)) & FLEXSPI_INTR_SEQTIMEOUT_MASK) + +#define FLEXSPI_INTR_KEYDONE_MASK (0x1000u) +#define FLEXSPI_INTR_KEYDONE_SHIFT (12u) +#define FLEXSPI_INTR_KEYDONE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_KEYDONE_SHIFT)) & FLEXSPI_INTR_KEYDONE_MASK) + +#define FLEXSPI_INTR_KEYERROR_MASK (0x2000u) +#define FLEXSPI_INTR_KEYERROR_SHIFT (13u) +#define FLEXSPI_INTR_KEYERROR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_INTR_KEYERROR_SHIFT)) & FLEXSPI_INTR_KEYERROR_MASK) + +#define FLEXSPI_LUTKEY_KEY_MASK (0xffffffffu) +#define FLEXSPI_LUTKEY_KEY_SHIFT (0u) + +#define FLEXSPI_LUTKEY_KEY(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUTKEY_KEY_SHIFT)) & FLEXSPI_LUTKEY_KEY_MASK) + +#define FLEXSPI_LUTCR_LOCK_MASK (0x1u) +#define FLEXSPI_LUTCR_LOCK_SHIFT (0u) + +#define FLEXSPI_LUTCR_LOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUTCR_LOCK_SHIFT)) & FLEXSPI_LUTCR_LOCK_MASK) +#define FLEXSPI_LUTCR_UNLOCK_MASK (0x2u) +#define FLEXSPI_LUTCR_UNLOCK_SHIFT (1u) + +#define FLEXSPI_LUTCR_UNLOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUTCR_UNLOCK_SHIFT)) & FLEXSPI_LUTCR_UNLOCK_MASK) + +#define FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK (0x1ffu) + +#define FLEXSPI_AHBRXBUFCR0_BUFSZ_SHIFT (0u) + +#define FLEXSPI_AHBRXBUFCR0_BUFSZ(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBRXBUFCR0_BUFSZ_SHIFT)) & FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK) +#define FLEXSPI_AHBRXBUFCR0_MSTRID_MASK (0xf0000u) +#define FLEXSPI_AHBRXBUFCR0_MSTRID_SHIFT (16u) + +#define FLEXSPI_AHBRXBUFCR0_MSTRID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBRXBUFCR0_MSTRID_SHIFT)) & FLEXSPI_AHBRXBUFCR0_MSTRID_MASK) +#define FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK (0x7000000u) +#define FLEXSPI_AHBRXBUFCR0_PRIORITY_SHIFT (24u) + +#define FLEXSPI_AHBRXBUFCR0_PRIORITY(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBRXBUFCR0_PRIORITY_SHIFT)) & FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK) + +#define FLEXSPI_AHBRXBUFCR0_REGIONEN_MASK (0x40000000u) +#define FLEXSPI_AHBRXBUFCR0_REGIONEN_SHIFT (30u) + +#define FLEXSPI_AHBRXBUFCR0_REGIONEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBRXBUFCR0_REGIONEN_SHIFT)) & FLEXSPI_AHBRXBUFCR0_REGIONEN_MASK) + +#define FLEXSPI_AHBRXBUFCR0_PREFETCHEN_MASK (0x80000000u) +#define FLEXSPI_AHBRXBUFCR0_PREFETCHEN_SHIFT (31u) + +#define FLEXSPI_AHBRXBUFCR0_PREFETCHEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBRXBUFCR0_PREFETCHEN_SHIFT)) & FLEXSPI_AHBRXBUFCR0_PREFETCHEN_MASK) + +#define FLEXSPI_AHBRXBUFCR0_COUNT (4u) + +#define FLEXSPI_FLSHCR0_FLSHSZ_MASK (0x7fffffu) +#define FLEXSPI_FLSHCR0_FLSHSZ_SHIFT (0u) + +#define FLEXSPI_FLSHCR0_FLSHSZ(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR0_FLSHSZ_SHIFT)) & FLEXSPI_FLSHCR0_FLSHSZ_MASK) + +#define FLEXSPI_FLSHCR0_COUNT (4u) + +#define FLEXSPI_FLSHCR1_TCSS_MASK (0x1fu) +#define FLEXSPI_FLSHCR1_TCSS_SHIFT (0u) + +#define FLEXSPI_FLSHCR1_TCSS(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_TCSS_SHIFT)) & FLEXSPI_FLSHCR1_TCSS_MASK) +#define FLEXSPI_FLSHCR1_TCSH_MASK (0x3e0u) +#define FLEXSPI_FLSHCR1_TCSH_SHIFT (5u) + +#define FLEXSPI_FLSHCR1_TCSH(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_TCSH_SHIFT)) & FLEXSPI_FLSHCR1_TCSH_MASK) +#define FLEXSPI_FLSHCR1_WA_MASK (0x400u) +#define FLEXSPI_FLSHCR1_WA_SHIFT (10u) + +#define FLEXSPI_FLSHCR1_WA(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_WA_SHIFT)) & FLEXSPI_FLSHCR1_WA_MASK) +#define FLEXSPI_FLSHCR1_CAS_MASK (0x7800u) +#define FLEXSPI_FLSHCR1_CAS_SHIFT (11u) + +#define FLEXSPI_FLSHCR1_CAS(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_CAS_SHIFT)) & FLEXSPI_FLSHCR1_CAS_MASK) +#define FLEXSPI_FLSHCR1_CSINTERVALUNIT_MASK (0x8000u) +#define FLEXSPI_FLSHCR1_CSINTERVALUNIT_SHIFT (15u) + +#define FLEXSPI_FLSHCR1_CSINTERVALUNIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_CSINTERVALUNIT_SHIFT)) & FLEXSPI_FLSHCR1_CSINTERVALUNIT_MASK) +#define FLEXSPI_FLSHCR1_CSINTERVAL_MASK (0xffff0000u) +#define FLEXSPI_FLSHCR1_CSINTERVAL_SHIFT (16u) + +#define FLEXSPI_FLSHCR1_CSINTERVAL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR1_CSINTERVAL_SHIFT)) & FLEXSPI_FLSHCR1_CSINTERVAL_MASK) + +#define FLEXSPI_FLSHCR1_COUNT (4u) + +#define FLEXSPI_FLSHCR2_ARDSEQID_MASK (0xfu) +#define FLEXSPI_FLSHCR2_ARDSEQID_SHIFT (0u) + +#define FLEXSPI_FLSHCR2_ARDSEQID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_ARDSEQID_SHIFT)) & FLEXSPI_FLSHCR2_ARDSEQID_MASK) +#define FLEXSPI_FLSHCR2_ARDSEQNUM_MASK (0xe0u) +#define FLEXSPI_FLSHCR2_ARDSEQNUM_SHIFT (5u) + +#define FLEXSPI_FLSHCR2_ARDSEQNUM(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_ARDSEQNUM_SHIFT)) & FLEXSPI_FLSHCR2_ARDSEQNUM_MASK) +#define FLEXSPI_FLSHCR2_AWRSEQID_MASK (0xf00u) +#define FLEXSPI_FLSHCR2_AWRSEQID_SHIFT (8u) + +#define FLEXSPI_FLSHCR2_AWRSEQID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_AWRSEQID_SHIFT)) & FLEXSPI_FLSHCR2_AWRSEQID_MASK) +#define FLEXSPI_FLSHCR2_AWRSEQNUM_MASK (0xe000u) +#define FLEXSPI_FLSHCR2_AWRSEQNUM_SHIFT (13u) + +#define FLEXSPI_FLSHCR2_AWRSEQNUM(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_AWRSEQNUM_SHIFT)) & FLEXSPI_FLSHCR2_AWRSEQNUM_MASK) +#define FLEXSPI_FLSHCR2_AWRWAIT_MASK (0xfff0000u) +#define FLEXSPI_FLSHCR2_AWRWAIT_SHIFT (16u) +#define FLEXSPI_FLSHCR2_AWRWAIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_AWRWAIT_SHIFT)) & FLEXSPI_FLSHCR2_AWRWAIT_MASK) +#define FLEXSPI_FLSHCR2_AWRWAITUNIT_MASK (0x70000000u) +#define FLEXSPI_FLSHCR2_AWRWAITUNIT_SHIFT (28u) + +#define FLEXSPI_FLSHCR2_AWRWAITUNIT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_AWRWAITUNIT_SHIFT)) & FLEXSPI_FLSHCR2_AWRWAITUNIT_MASK) +#define FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK (0x80000000u) +#define FLEXSPI_FLSHCR2_CLRINSTRPTR_SHIFT (31u) + +#define FLEXSPI_FLSHCR2_CLRINSTRPTR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR2_CLRINSTRPTR_SHIFT)) & FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK) + +#define FLEXSPI_FLSHCR2_COUNT (4u) + +#define FLEXSPI_FLSHCR4_WMOPT1_MASK (0x1u) +#define FLEXSPI_FLSHCR4_WMOPT1_SHIFT (0u) + +#define FLEXSPI_FLSHCR4_WMOPT1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR4_WMOPT1_SHIFT)) & FLEXSPI_FLSHCR4_WMOPT1_MASK) +#define FLEXSPI_FLSHCR4_WMENA_MASK (0x4u) +#define FLEXSPI_FLSHCR4_WMENA_SHIFT (2u) + +#define FLEXSPI_FLSHCR4_WMENA(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR4_WMENA_SHIFT)) & FLEXSPI_FLSHCR4_WMENA_MASK) +#define FLEXSPI_FLSHCR4_WMENB_MASK (0x8u) +#define FLEXSPI_FLSHCR4_WMENB_SHIFT (3u) + +#define FLEXSPI_FLSHCR4_WMENB(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_FLSHCR4_WMENB_SHIFT)) & FLEXSPI_FLSHCR4_WMENB_MASK) + +#define FLEXSPI_IPCR0_SFAR_MASK (0xffffffffu) +#define FLEXSPI_IPCR0_SFAR_SHIFT (0u) + +#define FLEXSPI_IPCR0_SFAR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCR0_SFAR_SHIFT)) & FLEXSPI_IPCR0_SFAR_MASK) + +#define FLEXSPI_IPCR1_IDATSZ_MASK (0xffffu) +#define FLEXSPI_IPCR1_IDATSZ_SHIFT (0u) + +#define FLEXSPI_IPCR1_IDATSZ(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCR1_IDATSZ_SHIFT)) & FLEXSPI_IPCR1_IDATSZ_MASK) +#define FLEXSPI_IPCR1_ISEQID_MASK (0xf0000u) +#define FLEXSPI_IPCR1_ISEQID_SHIFT (16u) + +#define FLEXSPI_IPCR1_ISEQID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCR1_ISEQID_SHIFT)) & FLEXSPI_IPCR1_ISEQID_MASK) +#define FLEXSPI_IPCR1_ISEQNUM_MASK (0x7000000u) +#define FLEXSPI_IPCR1_ISEQNUM_SHIFT (24u) + +#define FLEXSPI_IPCR1_ISEQNUM(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCR1_ISEQNUM_SHIFT)) & FLEXSPI_IPCR1_ISEQNUM_MASK) +#define FLEXSPI_IPCR1_IPAREN_MASK (0x80000000u) +#define FLEXSPI_IPCR1_IPAREN_SHIFT (31u) + +#define FLEXSPI_IPCR1_IPAREN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCR1_IPAREN_SHIFT)) & FLEXSPI_IPCR1_IPAREN_MASK) + +#define FLEXSPI_IPCMD_TRG_MASK (0x1u) +#define FLEXSPI_IPCMD_TRG_SHIFT (0u) + +#define FLEXSPI_IPCMD_TRG(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPCMD_TRG_SHIFT)) & FLEXSPI_IPCMD_TRG_MASK) + +#define FLEXSPI_IPRXFCR_CLRIPRXF_MASK (0x1u) +#define FLEXSPI_IPRXFCR_CLRIPRXF_SHIFT (0u) + +#define FLEXSPI_IPRXFCR_CLRIPRXF(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPRXFCR_CLRIPRXF_SHIFT)) & FLEXSPI_IPRXFCR_CLRIPRXF_MASK) +#define FLEXSPI_IPRXFCR_RXDMAEN_MASK (0x2u) +#define FLEXSPI_IPRXFCR_RXDMAEN_SHIFT (1u) + +#define FLEXSPI_IPRXFCR_RXDMAEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPRXFCR_RXDMAEN_SHIFT)) & FLEXSPI_IPRXFCR_RXDMAEN_MASK) +#define FLEXSPI_IPRXFCR_RXWMRK_MASK (0x3cu) +#define FLEXSPI_IPRXFCR_RXWMRK_SHIFT (2u) + +#define FLEXSPI_IPRXFCR_RXWMRK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPRXFCR_RXWMRK_SHIFT)) & FLEXSPI_IPRXFCR_RXWMRK_MASK) + +#define FLEXSPI_IPTXFCR_CLRIPTXF_MASK (0x1u) +#define FLEXSPI_IPTXFCR_CLRIPTXF_SHIFT (0u) + +#define FLEXSPI_IPTXFCR_CLRIPTXF(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPTXFCR_CLRIPTXF_SHIFT)) & FLEXSPI_IPTXFCR_CLRIPTXF_MASK) +#define FLEXSPI_IPTXFCR_TXDMAEN_MASK (0x2u) +#define FLEXSPI_IPTXFCR_TXDMAEN_SHIFT (1u) + +#define FLEXSPI_IPTXFCR_TXDMAEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPTXFCR_TXDMAEN_SHIFT)) & FLEXSPI_IPTXFCR_TXDMAEN_MASK) +#define FLEXSPI_IPTXFCR_TXWMRK_MASK (0x3cu) +#define FLEXSPI_IPTXFCR_TXWMRK_SHIFT (2u) + +#define FLEXSPI_IPTXFCR_TXWMRK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPTXFCR_TXWMRK_SHIFT)) & FLEXSPI_IPTXFCR_TXWMRK_MASK) + +#define FLEXSPI_DLLCR_DLLEN_MASK (0x1u) +#define FLEXSPI_DLLCR_DLLEN_SHIFT (0u) + +#define FLEXSPI_DLLCR_DLLEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_DLLCR_DLLEN_SHIFT)) & FLEXSPI_DLLCR_DLLEN_MASK) +#define FLEXSPI_DLLCR_DLLRESET_MASK (0x2u) +#define FLEXSPI_DLLCR_DLLRESET_SHIFT (1u) + +#define FLEXSPI_DLLCR_DLLRESET(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_DLLCR_DLLRESET_SHIFT)) & FLEXSPI_DLLCR_DLLRESET_MASK) +#define FLEXSPI_DLLCR_SLVDLYTARGET_MASK (0x78u) +#define FLEXSPI_DLLCR_SLVDLYTARGET_SHIFT (3u) + +#define FLEXSPI_DLLCR_SLVDLYTARGET(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_DLLCR_SLVDLYTARGET_SHIFT)) & FLEXSPI_DLLCR_SLVDLYTARGET_MASK) +#define FLEXSPI_DLLCR_OVRDEN_MASK (0x100u) +#define FLEXSPI_DLLCR_OVRDEN_SHIFT (8u) + +#define FLEXSPI_DLLCR_OVRDEN(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_DLLCR_OVRDEN_SHIFT)) & FLEXSPI_DLLCR_OVRDEN_MASK) +#define FLEXSPI_DLLCR_OVRDVAL_MASK (0x7e00u) +#define FLEXSPI_DLLCR_OVRDVAL_SHIFT (9u) + +#define FLEXSPI_DLLCR_OVRDVAL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_DLLCR_OVRDVAL_SHIFT)) & FLEXSPI_DLLCR_OVRDVAL_MASK) + +#define FLEXSPI_DLLCR_COUNT (2u) + +#define FLEXSPI_STS0_SEQIDLE_MASK (0x1u) +#define FLEXSPI_STS0_SEQIDLE_SHIFT (0u) + +#define FLEXSPI_STS0_SEQIDLE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS0_SEQIDLE_SHIFT)) & FLEXSPI_STS0_SEQIDLE_MASK) +#define FLEXSPI_STS0_ARBIDLE_MASK (0x2u) +#define FLEXSPI_STS0_ARBIDLE_SHIFT (1u) + +#define FLEXSPI_STS0_ARBIDLE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS0_ARBIDLE_SHIFT)) & FLEXSPI_STS0_ARBIDLE_MASK) +#define FLEXSPI_STS0_ARBCMDSRC_MASK (0xcu) +#define FLEXSPI_STS0_ARBCMDSRC_SHIFT (2u) + +#define FLEXSPI_STS0_ARBCMDSRC(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS0_ARBCMDSRC_SHIFT)) & FLEXSPI_STS0_ARBCMDSRC_MASK) + +#define FLEXSPI_STS1_AHBCMDERRID_MASK (0xfu) +#define FLEXSPI_STS1_AHBCMDERRID_SHIFT (0u) + +#define FLEXSPI_STS1_AHBCMDERRID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS1_AHBCMDERRID_SHIFT)) & FLEXSPI_STS1_AHBCMDERRID_MASK) +#define FLEXSPI_STS1_AHBCMDERRCODE_MASK (0xf00u) +#define FLEXSPI_STS1_AHBCMDERRCODE_SHIFT (8u) + +#define FLEXSPI_STS1_AHBCMDERRCODE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS1_AHBCMDERRCODE_SHIFT)) & FLEXSPI_STS1_AHBCMDERRCODE_MASK) +#define FLEXSPI_STS1_IPCMDERRID_MASK (0xf0000u) +#define FLEXSPI_STS1_IPCMDERRID_SHIFT (16u) + +#define FLEXSPI_STS1_IPCMDERRID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS1_IPCMDERRID_SHIFT)) & FLEXSPI_STS1_IPCMDERRID_MASK) +#define FLEXSPI_STS1_IPCMDERRCODE_MASK (0xf000000u) +#define FLEXSPI_STS1_IPCMDERRCODE_SHIFT (24u) + +#define FLEXSPI_STS1_IPCMDERRCODE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS1_IPCMDERRCODE_SHIFT)) & FLEXSPI_STS1_IPCMDERRCODE_MASK) + +#define FLEXSPI_STS2_ASLVLOCK_MASK (0x1u) +#define FLEXSPI_STS2_ASLVLOCK_SHIFT (0u) + +#define FLEXSPI_STS2_ASLVLOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_ASLVLOCK_SHIFT)) & FLEXSPI_STS2_ASLVLOCK_MASK) +#define FLEXSPI_STS2_AREFLOCK_MASK (0x2u) +#define FLEXSPI_STS2_AREFLOCK_SHIFT (1u) + +#define FLEXSPI_STS2_AREFLOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_AREFLOCK_SHIFT)) & FLEXSPI_STS2_AREFLOCK_MASK) +#define FLEXSPI_STS2_ASLVSEL_MASK (0xfcu) +#define FLEXSPI_STS2_ASLVSEL_SHIFT (2u) + +#define FLEXSPI_STS2_ASLVSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_ASLVSEL_SHIFT)) & FLEXSPI_STS2_ASLVSEL_MASK) +#define FLEXSPI_STS2_AREFSEL_MASK (0x3f00u) +#define FLEXSPI_STS2_AREFSEL_SHIFT (8u) + +#define FLEXSPI_STS2_AREFSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_AREFSEL_SHIFT)) & FLEXSPI_STS2_AREFSEL_MASK) +#define FLEXSPI_STS2_BSLVLOCK_MASK (0x10000u) +#define FLEXSPI_STS2_BSLVLOCK_SHIFT (16u) + +#define FLEXSPI_STS2_BSLVLOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_BSLVLOCK_SHIFT)) & FLEXSPI_STS2_BSLVLOCK_MASK) +#define FLEXSPI_STS2_BREFLOCK_MASK (0x20000u) +#define FLEXSPI_STS2_BREFLOCK_SHIFT (17u) + +#define FLEXSPI_STS2_BREFLOCK(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_BREFLOCK_SHIFT)) & FLEXSPI_STS2_BREFLOCK_MASK) +#define FLEXSPI_STS2_BSLVSEL_MASK (0xfc0000u) +#define FLEXSPI_STS2_BSLVSEL_SHIFT (18u) + +#define FLEXSPI_STS2_BSLVSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_BSLVSEL_SHIFT)) & FLEXSPI_STS2_BSLVSEL_MASK) +#define FLEXSPI_STS2_BREFSEL_MASK (0x3f000000u) +#define FLEXSPI_STS2_BREFSEL_SHIFT (24u) + +#define FLEXSPI_STS2_BREFSEL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_STS2_BREFSEL_SHIFT)) & FLEXSPI_STS2_BREFSEL_MASK) + +#define FLEXSPI_AHBSPNDSTS_ACTIVE_MASK (0x1u) +#define FLEXSPI_AHBSPNDSTS_ACTIVE_SHIFT (0u) + +#define FLEXSPI_AHBSPNDSTS_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBSPNDSTS_ACTIVE_SHIFT)) & FLEXSPI_AHBSPNDSTS_ACTIVE_MASK) +#define FLEXSPI_AHBSPNDSTS_BUFID_MASK (0xeU) +#define FLEXSPI_AHBSPNDSTS_BUFID_SHIFT (1u) + +#define FLEXSPI_AHBSPNDSTS_BUFID(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBSPNDSTS_BUFID_SHIFT)) & FLEXSPI_AHBSPNDSTS_BUFID_MASK) +#define FLEXSPI_AHBSPNDSTS_DATLFT_MASK (0xffff0000u) +#define FLEXSPI_AHBSPNDSTS_DATLFT_SHIFT (16u) + +#define FLEXSPI_AHBSPNDSTS_DATLFT(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_AHBSPNDSTS_DATLFT_SHIFT)) & FLEXSPI_AHBSPNDSTS_DATLFT_MASK) + +#define FLEXSPI_IPRXFSTS_FILL_MASK (0xffu) +#define FLEXSPI_IPRXFSTS_FILL_SHIFT (0u) + +#define FLEXSPI_IPRXFSTS_FILL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPRXFSTS_FILL_SHIFT)) & FLEXSPI_IPRXFSTS_FILL_MASK) +#define FLEXSPI_IPRXFSTS_RDCNTR_MASK (0xffff0000u) +#define FLEXSPI_IPRXFSTS_RDCNTR_SHIFT (16u) + +#define FLEXSPI_IPRXFSTS_RDCNTR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPRXFSTS_RDCNTR_SHIFT)) & FLEXSPI_IPRXFSTS_RDCNTR_MASK) + +#define FLEXSPI_IPTXFSTS_FILL_MASK (0xffu) +#define FLEXSPI_IPTXFSTS_FILL_SHIFT (0u) + +#define FLEXSPI_IPTXFSTS_FILL(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPTXFSTS_FILL_SHIFT)) & FLEXSPI_IPTXFSTS_FILL_MASK) +#define FLEXSPI_IPTXFSTS_WRCNTR_MASK (0xffff0000u) +#define FLEXSPI_IPTXFSTS_WRCNTR_SHIFT (16u) + +#define FLEXSPI_IPTXFSTS_WRCNTR(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_IPTXFSTS_WRCNTR_SHIFT)) & FLEXSPI_IPTXFSTS_WRCNTR_MASK) + +#define FLEXSPI_RFDR_RXDATA_MASK (0xffffffffu) +#define FLEXSPI_RFDR_RXDATA_SHIFT (0u) + +#define FLEXSPI_RFDR_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_RFDR_RXDATA_SHIFT)) & FLEXSPI_RFDR_RXDATA_MASK) + +#define FLEXSPI_RFDR_COUNT (32u) + +#define FLEXSPI_TFDR_TXDATA_MASK (0xffffffffu) +#define FLEXSPI_TFDR_TXDATA_SHIFT (0u) + +#define FLEXSPI_TFDR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_TFDR_TXDATA_SHIFT)) & FLEXSPI_TFDR_TXDATA_MASK) + +#define FLEXSPI_TFDR_COUNT (32u) + +#define FLEXSPI_LUT_COUNT (128u) + +#endif /* __ARCH_ARM_SRC_IMX9_HARDWARE_IMX9_FLEXSPI_H */ diff --git a/arch/arm/src/imx9/imx9_flexspi.c b/arch/arm/src/imx9/imx9_flexspi.c new file mode 100644 index 00000000000..4022845dd58 --- /dev/null +++ b/arch/arm/src/imx9/imx9_flexspi.c @@ -0,0 +1,1259 @@ +/**************************************************************************** + * arch/arm/src/imx9/imx9_flexspi.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <nuttx/debug.h> + +#include <arch/board/board.h> + +#include <nuttx/arch.h> +#include <nuttx/wdog.h> +#include <nuttx/clock.h> +#include <nuttx/kmalloc.h> +#include <nuttx/mutex.h> + +#include <arch/barriers.h> + +#include "arm_internal.h" + +#include "imx9_gpio.h" +#include "imx9_clockconfig.h" +#include "imx9_flexspi.h" +#include "imx9_iomuxc.h" +#include "hardware/imx9_flexspi.h" +#include "hardware/imx9_pinmux.h" + +#ifdef CONFIG_IMX9_FLEXSPI + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The state of the FlexSPI controller. + * + */ + +struct imx9_flexspidev_s +{ + struct flexspi_dev_s flexspi; /* Externally visible part of the FlexSPI + * interface */ + + struct flexspi_type_s *base; /* FlexSPI controller register base address */ + + uint32_t clk_root; /* FlexSPI clock root */ + + bool initialized; /* TRUE: Controller has been initialized */ + + mutex_t lock; /* Assures mutually exclusive access to + * FlexSPI */ +}; + +/* FlexSPI methods */ + +static int imx9_flexspi_lock(struct flexspi_dev_s *dev, bool lock); +static int imx9_flexspi_transfer_blocking(struct flexspi_dev_s *dev, + struct flexspi_transfer_s *xfer); +static void imx9_flexspi_software_reset(struct flexspi_dev_s *dev); +static void imx9_flexspi_update_lut(struct flexspi_dev_s *dev, + uint32_t index, + const uint32_t *cmd, + uint32_t count); +static void imx9_flexspi_set_device_config(struct flexspi_dev_s *dev, + struct flexspi_device_config_s *config, + enum flexspi_port_e port); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* FlexSPI0 driver operations */ + +static const struct flexspi_ops_s g_flexspi0ops = +{ + .lock = imx9_flexspi_lock, + .transfer_blocking = imx9_flexspi_transfer_blocking, + .software_reset = imx9_flexspi_software_reset, + .update_lut = imx9_flexspi_update_lut, + .set_device_config = imx9_flexspi_set_device_config, +}; + +/* This is the overall state of the FlexSPI0 controller */ + +static struct imx9_flexspidev_s g_flexspi0dev = +{ + .flexspi = + { + .ops = &g_flexspi0ops, + }, + .base = (struct flexspi_type_s *)IMX9_FLEXSPI_BASE, + .clk_root = FLEXSPI1_CLK, + .lock = NXMUTEX_INITIALIZER, +}; + +#define FREQ_1MHz (1000000ul) +#define FLEXSPI_DLLCR_DEFAULT (0x100ul) +#define FLEXSPI_LUT_KEY_VAL (0x5af05af0ul) + +enum +{ + FLEXSPI_DELAY_CELL_UNIT_MIN = 75, /* 75ps */ + + FLEXSPI_DELAY_CELL_UNIT_MAX = 225, /* 225ps */ +}; + +enum +{ + FLEXSPI_FLASH_A_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED = + FLEXSPI_STS2_ASLVLOCK_MASK, /* Flash A sample clock slave delay line locked */ + + FLEXSPI_FLASH_A_SAMPLE_CLOCK_REF_DELAY_LOCKED = + FLEXSPI_STS2_AREFLOCK_MASK, /* Flash A sample clock reference delay line locked */ + + FLEXSPI_FLASH_B_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED = + FLEXSPI_STS2_BSLVLOCK_MASK, /* Flash B sample clock slave delay line locked */ + + FLEXSPI_FLASH_B_SAMPLE_CLOCK_REF_DELAY_LOCKED = + FLEXSPI_STS2_BREFLOCK_MASK, /* Flash B sample clock reference delay line locked */ +}; + +/* FLEXSPI interrupt status flags */ + +enum flexspi_flags_e +{ + FLEXSPI_KEYERROR_FLAG = FLEXSPI_INTEN_KEYERROR_MASK , + + FLEXSPI_KEYDONE_FLAG = FLEXSPI_INTEN_KEYDONE_MASK, + + FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT_FLAG = FLEXSPI_INTEN_SEQTIMEOUTEN_MASK, /* Sequence execution timeout */ + + FLEXSPI_AHB_BUS_ERROR_FLAG = FLEXSPI_INTEN_AHBBUSERROREN_MASK, /* AHB Bus error flag */ + + FLEXSPI_SCK_STOPPED_BECAUSE_TX_EMPTY_FLAG = + FLEXSPI_INTEN_SCKSTOPBYWREN_MASK, /* SCK is stopped during command + * sequence because Async TX FIFO empty */ + + FLEXSPI_SCK_STOPPED_BECAUSE_RX_FULL_FLAG = + FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK, /* SCK is stopped during command + * sequence because Async RX FIFO full */ + + FLEXSPI_IP_TX_FIFO_WATERMARK_EMPTY_FLAG = FLEXSPI_INTEN_IPTXWEEN_MASK, /* IP TX FIFO WaterMark empty */ + + FLEXSPI_IP_RX_FIFO_WATERMARK_AVAILABLE_FLAG = FLEXSPI_INTEN_IPRXWAEN_MASK, /* IP RX FIFO WaterMark available */ + + FLEXSPI_AHB_COMMAND_SEQUENCE_ERROR_FLAG = + FLEXSPI_INTEN_AHBCMDERREN_MASK, /* AHB triggered Command Sequences Error */ + + FLEXSPI_IP_COMMAND_SEQUENCE_ERROR_FLAG = FLEXSPI_INTEN_IPCMDERREN_MASK, /* IP triggered Command Sequences Error */ + + FLEXSPI_AHB_COMMAND_GRANT_TIMEOUT_FLAG = + FLEXSPI_INTEN_AHBCMDGEEN_MASK, /* AHB triggered Command Sequences Grant Timeout */ + + FLEXSPI_IP_COMMAND_GRANT_TIMEOUT_FLAG = + FLEXSPI_INTEN_IPCMDGEEN_MASK, /* IP triggered Command Sequences Grant Timeout */ + + FLEXSPI_IP_COMMAND_EXECUTION_DONE_FLAG = + FLEXSPI_INTEN_IPCMDDONEEN_MASK, /* IP triggered Command Sequences Execution finished */ + + FLEXSPI_ALL_INTERRUPT_FLAGS = 0x3fffu, /* All flags */ +}; + +/* Common sets of flags used by the driver */ + +enum flexspi_flag_constants_e +{ + /* Errors to check for */ + + ERROR_FLAGS = FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT_FLAG | + FLEXSPI_IP_COMMAND_SEQUENCE_ERROR_FLAG | + FLEXSPI_IP_COMMAND_GRANT_TIMEOUT_FLAG, +}; + +#define FLEXSPI_AHB_BUFFER_COUNT (8) + +struct flexspi_ahb_buffer_config_s +{ + uint8_t priority; /* This priority for AHB Master Read which this AHB RX Buffer is assigned */ + + uint8_t master_index; /* AHB Master ID the AHB RX Buffer is assigned */ + + uint16_t buffer_size; /* AHB buffer size in byte */ + + bool enable_prefetch; /* AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master, allows + * prefetch disable/enable separately for each master */ +}; + +/* FLEXSPI configuration structure */ + +struct flexspi_config_s +{ + enum flexspi_read_sample_clock_e rx_sample_clock; /* Sample Clock source selection for Flash Reading */ + + bool enable_sck_free_running; /* Enable/disable SCK output free-running */ + + bool enable_combination; /* Enable/disable combining PORT A and B Data Pins + * (SIOA[3:0] and SIOB[3:0]) to support Flash Octal mode */ + + bool enable_doze; /* Enable/disable doze mode support */ + + bool enable_half_speed_access; /* Enable/disable divide by 2 of the clock for half + * speed commands */ + + bool enable_sckb_diff_opt; /* Enable/disable SCKB pad use as SCKA differential clock + * output, when enable, Port B flash access is not available */ + + bool enable_same_config_for_all; /* Enable/disable same configuration for all connected devices + * when enabled, same configuration in FLASHA1CRx is applied to all */ + + uint16_t seq_timeout_cycle; /* Timeout wait cycle for command sequence execution, + * timeout after ahb_grant_timeout_cyle*1024 serial root clock cycles */ + + uint8_t ip_grant_timeout_cycle; /* Timeout wait cycle for IP command grant, timeout after + * ip_grant_timeout_cycle*1024 AHB clock cycles */ + + uint8_t tx_watermark; /* FLEXSPI IP transmit watermark value */ + + uint8_t rx_watermark; /* FLEXSPI receive watermark value */ + + struct + { + bool enable_ahb_write_ip_tx_fifo; /* Enable AHB bus write access to IP TX FIFO */ + bool enable_ahb_write_ip_rx_fifo; /* Enable AHB bus write access to IP RX FIFO */ + + uint8_t ahb_grant_timeout_cycle; /* Timeout wait cycle for AHB command grant, + * timeout after ahb_grant_timeout_cyle*1024 AHB clock cycles */ + + uint16_t ahb_bus_timeout_cycle; /* Timeout wait cycle for AHB read/write access, + * timeout after ahb_bus_timeout_cycle*1024 AHB clock cycles */ + + uint8_t resume_wait_cycle; /* Wait cycle for idle state before suspended command sequence + * resume, timeout after ahb_bus_timeout_cycle AHB clock cycles */ + + struct flexspi_ahb_buffer_config_s buffer[FLEXSPI_AHB_BUFFER_COUNT]; /* AHB buffer size */ + + bool enable_clear_ahb_buffer_opt; /* Enable/disable automatically clean AHB RX Buffer and TX Buffer + * when FLEXSPI returns STOP mode ACK */ + + bool enable_read_address_opt; /* Enable/disable remove AHB read burst start address alignment limitation. + * when enable, there is no AHB read burst start address alignment limitation */ + + bool enable_ahb_prefetch; /* Enable/disable AHB read prefetch feature, when enabled, FLEXSPI + * will fetch more data than current AHB burst */ + + bool enable_ahb_bufferable; /* Enable/disable AHB bufferable write access support, when enabled, + * FLEXSPI return before waiting for command execution finished */ + + bool enable_ahb_cachable; /* Enable AHB bus cacheable read access support */ + } ahb_config; +}; + +/**************************************************************************** + * Prototypes + ****************************************************************************/ + +/* Check and clear IP command execution errors. + * + * @param base FLEXSPI base pointer. + * @param status interrupt status. + */ + +static int imx9_flexspi_check_and_clear_error(struct flexspi_type_s *base, + uint32_t status); + +/**************************************************************************** + * Variables + ****************************************************************************/ + +/**************************************************************************** + * Code + ****************************************************************************/ + +/* Software reset for the FLEXSPI logic. + * + * This function sets the software reset flags for both AHB and buffer domain + * and resets both AHB buffer and also IP FIFOs. + * + * @param base FLEXSPI peripheral base address. + */ + +static inline void imx9_flexspi_software_reset_private( + struct flexspi_type_s *base) +{ + base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; + while (0u != (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)) + { + } +} + +/* Returns whether the bus is idle. + * + * @param base FLEXSPI peripheral base address. + * @retval true Bus is idle. + * @retval false Bus is busy. + */ + +static inline bool imx9_flexspi_get_bus_idle_status( + struct flexspi_type_s *base) +{ + return (0u != (base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK)) && + (0u != (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK)); +} + +static uint32_t imx9_flexspi_configure_dll(struct flexspi_type_s *base, + struct flexspi_device_config_s *config) +{ + bool is_unified_config = true; + uint32_t flexspi_dll_value; + uint32_t dll_value; + uint32_t temp; + + uint32_t rx_sample_clock = (base->MCR0 & FLEXSPI_MCR0_RXCLKSRC_MASK) >> + FLEXSPI_MCR0_RXCLKSRC_SHIFT; + switch (rx_sample_clock) + { + case (uint32_t)FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_INTERNALLY: + case (uint32_t)FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD: + case (uint32_t)FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_SCK_PAD: + is_unified_config = true; + break; + case (uint32_t)FLEXSPI_READ_SAMPLE_CLK_EXTERNAL_INPUT_FROM_DQS_PAD: + if (config->is_sck2_enabled) + { + is_unified_config = true; + } + else + { + is_unified_config = false; + } + break; + default: + assert(false); + break; + } + + if (is_unified_config) + { + flexspi_dll_value = FLEXSPI_DLLCR_DEFAULT; /* 1 fixed delay cells in DLL delay chain */ + } + else + { + if (config->flexspi_root_clk >= 100u * FREQ_1MHz) + { + /* DLLEN = 1, SLVDLYTARGET = 0xF, */ + + flexspi_dll_value = FLEXSPI_DLLCR_DLLEN(1) | + FLEXSPI_DLLCR_SLVDLYTARGET(0x0f); + } + else + { + temp = (uint32_t)config->data_valid_time * 1000u; /* Convert data valid time in ns to ps */ + + dll_value = temp / (uint32_t)FLEXSPI_DELAY_CELL_UNIT_MIN; + if (dll_value * (uint32_t)FLEXSPI_DELAY_CELL_UNIT_MIN < temp) + { + dll_value++; + } + flexspi_dll_value = FLEXSPI_DLLCR_OVRDEN(1) | + FLEXSPI_DLLCR_OVRDVAL(dll_value); + } + } + return flexspi_dll_value; +} + +static int imx9_flexspi_check_and_clear_error(struct flexspi_type_s *base, + uint32_t status) +{ + int result = 0; + + /* Check for error */ + + status &= (uint32_t)ERROR_FLAGS; + if (0u != status) + { + /* Select the correct error code */ + + if (0u != (status & (uint32_t)FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT_FLAG)) + { + result = STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT; + } + else if (0u != (status & + (uint32_t)FLEXSPI_IP_COMMAND_SEQUENCE_ERROR_FLAG)) + { + result = STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR; + } + else if (0u != (status & + (uint32_t)FLEXSPI_IP_COMMAND_GRANT_TIMEOUT_FLAG)) + { + result = STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT; + } + else + { + assert(false); + } + + /* Clear the flags */ + + base->INTR |= status; + + /* Reset fifos. These flags clear automatically */ + + base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK; + base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK; + } + + return result; +} + +/* Initializes the FLEXSPI module and internal state. + * + * This function enables the clock for FLEXSPI and also configures the + * FLEXSPI with the input configure parameters. Users should call this + * function before any FLEXSPI operations. + * + * param base FLEXSPI peripheral base address. + * param config FLEXSPI configure structure. + */ + +void imx9_flexspi_init(struct flexspi_type_s *base, + const struct flexspi_config_s *config) +{ + uint32_t config_value = 0; + uint8_t i = 0; + + /* Reset peripheral before configuring it */ + + base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; + imx9_flexspi_software_reset_private(base); + + /* Configure MCR0 configuration items */ + + config_value = FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock) | + FLEXSPI_MCR0_DOZEEN(config->enable_doze) | + FLEXSPI_MCR0_IPGRANTWAIT(config->ip_grant_timeout_cycle) | + FLEXSPI_MCR0_AHBGRANTWAIT( + config->ahb_config.ahb_grant_timeout_cycle) | + FLEXSPI_MCR0_SCKFREERUNEN(config->enable_sck_free_running) | + FLEXSPI_MCR0_HSEN(config->enable_half_speed_access) | + FLEXSPI_MCR0_COMBINATIONEN(config->enable_combination) | + FLEXSPI_MCR0_ATDFEN( + config->ahb_config.enable_ahb_write_ip_tx_fifo) | + FLEXSPI_MCR0_ARDFEN( + config->ahb_config.enable_ahb_write_ip_rx_fifo) | + FLEXSPI_MCR0_MDIS_MASK; + base->MCR0 = config_value; + + /* Configure MCR1 configurations */ + + config_value = + FLEXSPI_MCR1_SEQWAIT(config->seq_timeout_cycle) | + FLEXSPI_MCR1_AHBBUSWAIT(config->ahb_config.ahb_bus_timeout_cycle); + + base->MCR1 = config_value; + + /* Configure MCR2 configurations */ + + config_value = base->MCR2; + config_value &= ~(FLEXSPI_MCR2_RESUMEWAIT_MASK | + FLEXSPI_MCR2_SCKBDIFFOPT_MASK | + FLEXSPI_MCR2_SAMEDEVICEEN_MASK | + FLEXSPI_MCR2_CLRAHBBUFOPT_MASK); + + config_value |= FLEXSPI_MCR2_RESUMEWAIT( + config->ahb_config.resume_wait_cycle) | + FLEXSPI_MCR2_SCKBDIFFOPT( + config->enable_sckb_diff_opt) | + FLEXSPI_MCR2_SAMEDEVICEEN( + config->enable_same_config_for_all) | + FLEXSPI_MCR2_CLRAHBBUFOPT( + config->ahb_config.enable_clear_ahb_buffer_opt); + + base->MCR2 = config_value; + + /* Configure AHB control items */ + + config_value = base->AHBCR; + config_value &= ~(FLEXSPI_AHBCR_READADDROPT_MASK | + FLEXSPI_AHBCR_PREFETCHEN_MASK | + FLEXSPI_AHBCR_BUFFERABLEEN_MASK | + FLEXSPI_AHBCR_CACHABLEEN_MASK); + + config_value |= FLEXSPI_AHBCR_READADDROPT( + config->ahb_config.enable_read_address_opt) | + FLEXSPI_AHBCR_PREFETCHEN( + config->ahb_config.enable_ahb_prefetch) | + FLEXSPI_AHBCR_BUFFERABLEEN( + config->ahb_config.enable_ahb_bufferable) | + FLEXSPI_AHBCR_CACHABLEEN( + config->ahb_config.enable_ahb_cachable); + + base->AHBCR = config_value; + + /* Configure AHB rx buffers */ + + for (i = 0; i < (uint32_t)FLEXSPI_AHB_BUFFER_COUNT; i++) + { + config_value = base->AHBRXBUFCR0[i]; + + config_value &= ~(FLEXSPI_AHBRXBUFCR0_PREFETCHEN_MASK | + FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK | + FLEXSPI_AHBRXBUFCR0_MSTRID_MASK | + FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK); + + config_value |= FLEXSPI_AHBRXBUFCR0_PREFETCHEN( + config->ahb_config.buffer[i].enable_prefetch) | + FLEXSPI_AHBRXBUFCR0_PRIORITY( + config->ahb_config.buffer[i].priority) | + FLEXSPI_AHBRXBUFCR0_MSTRID( + config->ahb_config.buffer[i].master_index) | + FLEXSPI_AHBRXBUFCR0_BUFSZ((uint32_t) + config->ahb_config.buffer[i].buffer_size / 8u); + + base->AHBRXBUFCR0[i] = config_value; + } + + /* Configure IP FIFO watermarks */ + + base->IPRXFCR &= ~FLEXSPI_IPRXFCR_RXWMRK_MASK; + base->IPRXFCR |= + FLEXSPI_IPRXFCR_RXWMRK((uint32_t)config->rx_watermark / 8u - 1u); + base->IPTXFCR &= ~FLEXSPI_IPTXFCR_TXWMRK_MASK; + base->IPTXFCR |= + FLEXSPI_IPTXFCR_TXWMRK((uint32_t)config->tx_watermark / 8u - 1u); + + /* Reset flash size on all ports */ + + for (i = 0; i < (uint32_t)FLEXSPI_PORT_COUNT; i++) + { + base->FLSHCR0[i] = 0; + } +} + +/* Gets default settings for FLEXSPI. + * + * param config FLEXSPI configuration structure. + */ + +void imx9_flexspi_get_default_config(struct flexspi_config_s *config) +{ + int i; + + /* Initializes the configure structure to zero */ + + memset(config, 0, sizeof(*config)); + + config->rx_sample_clock = FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD; + config->enable_sck_free_running = false; + config->enable_combination = false; + config->enable_doze = true; + config->enable_half_speed_access = false; + config->enable_sckb_diff_opt = false; + config->enable_same_config_for_all = false; + config->seq_timeout_cycle = 0xffff; + config->ip_grant_timeout_cycle = 0xff; + config->tx_watermark = 8; + config->rx_watermark = 8; + config->ahb_config.enable_ahb_write_ip_tx_fifo = false; + config->ahb_config.enable_ahb_write_ip_rx_fifo = false; + config->ahb_config.ahb_grant_timeout_cycle = 0xff; + config->ahb_config.ahb_bus_timeout_cycle = 0xffff; + config->ahb_config.resume_wait_cycle = 0x20; + memset(config->ahb_config.buffer, 0, + sizeof(config->ahb_config.buffer)); + + /* Use invalid master ID 0xF and buffer size 0 for the first several + * buffers. + */ + + for (i = 0; i < (FLEXSPI_AHB_BUFFER_COUNT - 2u); i++) + { + /* Default enable AHB prefetch */ + + config->ahb_config.buffer[i].enable_prefetch = true; + + /* Invalid master index which is no used, so will never hit */ + + config->ahb_config.buffer[i].master_index = 0xf; + + /* Default buffer size 0 for buffer0 to + * buffer(FLEXSPI_AHB_BUFFER_COUNT - 3) + */ + + config->ahb_config.buffer[i].buffer_size = 0; + } + + for (; i < FLEXSPI_AHB_BUFFER_COUNT; i++) + { + config->ahb_config.buffer[i].enable_prefetch = true; /* Default enable + * AHB prefetch. + */ + + config->ahb_config.buffer[i].buffer_size = 256u; /* Default buffer + * size 256 bytes. + */ + } + + config->ahb_config.enable_clear_ahb_buffer_opt = false; + config->ahb_config.enable_read_address_opt = true; + config->ahb_config.enable_ahb_prefetch = true; + config->ahb_config.enable_ahb_bufferable = false; + config->ahb_config.enable_ahb_cachable = false; +} + +/* Configures the connected device parameter. + * + * This function configures the connected device relevant parameters, such + * as the size, command, and so on. The flash configuration value cannot have + * a default value. The user needs to configure it according to the connected + * device. + * + * param base FLEXSPI peripheral base address. + * param config Device configuration parameters. + * param port FLEXSPI Operation port. + */ + +void imx9_flexspi_set_device_config_private(struct flexspi_type_s *base, + struct flexspi_device_config_s *config, + enum flexspi_port_e port) +{ + uint32_t config_value = 0; + uint32_t status_value = 0; + uint32_t dll_value = 0; + uint8_t index = (uint8_t)port >> 1u; /* PortA with index 0, PortB with index 1 */ + + /* Wait for bus idle before change flash configuration */ + + while (!imx9_flexspi_get_bus_idle_status(base)) + { + } + + /* Configure flash size */ + + base->FLSHCR0[port] = config->flash_size; + + /* Configure flash parameters */ + + base->FLSHCR1[port] = + FLEXSPI_FLSHCR1_CSINTERVAL(config->cs_interval) | + FLEXSPI_FLSHCR1_CSINTERVALUNIT(config->cs_interval_unit) | + FLEXSPI_FLSHCR1_TCSH(config->cs_hold_time) | + FLEXSPI_FLSHCR1_TCSS(config->cs_setup_time) | + FLEXSPI_FLSHCR1_CAS(config->columnspace) | + FLEXSPI_FLSHCR1_WA(config->enable_word_address); + + /* Configure AHB operation items */ + + config_value = base->FLSHCR2[port]; + + config_value &= ~(FLEXSPI_FLSHCR2_AWRWAITUNIT_MASK | + FLEXSPI_FLSHCR2_AWRWAIT_MASK | + FLEXSPI_FLSHCR2_AWRSEQNUM_MASK | + FLEXSPI_FLSHCR2_AWRSEQID_MASK | + FLEXSPI_FLSHCR2_ARDSEQNUM_MASK | + FLEXSPI_FLSHCR2_ARDSEQID_MASK); + + config_value |= + FLEXSPI_FLSHCR2_AWRWAITUNIT(config->ahb_write_wait_unit) | + FLEXSPI_FLSHCR2_AWRWAIT(config->ahb_write_wait_interval); + + if (config->awr_seq_number > 0u) + { + config_value |= FLEXSPI_FLSHCR2_AWRSEQID( + (uint32_t)config->awr_seq_index) | + FLEXSPI_FLSHCR2_AWRSEQNUM( + (uint32_t)config->awr_seq_number - 1u); + } + + if (config->ard_seq_number > 0u) + { + config_value |= FLEXSPI_FLSHCR2_ARDSEQID( + (uint32_t)config->ard_seq_index) | + FLEXSPI_FLSHCR2_ARDSEQNUM( + (uint32_t)config->ard_seq_number - 1u); + } + + base->FLSHCR2[port] = config_value; + + /* Set RX sample clock, the DLL configuration depends on it */ + + config_value = base->MCR0; + config_value &= ~FLEXSPI_MCR0_RXCLKSRC_MASK; + config_value |= FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock); + base->MCR0 = config_value; + + /* Configure DLL */ + + dll_value = imx9_flexspi_configure_dll(base, config); + base->DLLCR[index] = dll_value; + + /* Configure write mask */ + + if (config->enable_write_mask) + { + base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMOPT1_MASK; + } + else + { + base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMOPT1_MASK; + } + + if (index == 0u) /* Port A */ + { + base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMENA_MASK; + base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENA(config->enable_write_mask); + } + else + { + base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMENB_MASK; + base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENB(config->enable_write_mask); + } + + /* Exit stop mode */ + + base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; + + /* According to ERR011377, need to delay at least 100 NOPs to ensure the + * DLL is locked. + */ + + status_value = + (index == 0u) ? + ((uint32_t)FLEXSPI_FLASH_A_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED | + (uint32_t)FLEXSPI_FLASH_A_SAMPLE_CLOCK_REF_DELAY_LOCKED) : + ((uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED | + (uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_REF_DELAY_LOCKED); + + if (0u != (dll_value & FLEXSPI_DLLCR_DLLEN_MASK)) + { + /* Wait slave delay line locked and slave reference delay line locked */ + + while ((base->STS2 & status_value) != status_value) + { + } + + /* Wait at least 100 NOPs */ + + for (uint8_t delay = 100u; delay > 0u; delay--) + { + asm("NOP"); + } + } +} + +/* Updates the LUT table. + * + * param base FLEXSPI peripheral base address. + * param index From which index start to update. + * It could be any index of the LUT table, which also allows + * user to update command content inside a command. Each command + * consists of up to 8 instructions and occupy 4*32-bit memory. + * param cmd Command sequence array. + * param count Number of sequences. + */ + +void imx9_flexspi_update_lut_private(struct flexspi_type_s *base, + uint32_t index, + const uint32_t *cmd, + uint32_t count) +{ + assert(index < 128u); + + uint32_t i = 0; + volatile uint32_t *lut_base; + + /* Wait for bus idle before change flash configuration */ + + while (!imx9_flexspi_get_bus_idle_status(base)) + { + } + + /* Unlock LUT for update */ + + base->LUTKEY = FLEXSPI_LUT_KEY_VAL; + base->LUTCR = 0x02; + + lut_base = &base->LUT[index]; + for (i = 0; i < count; i++) + { + *lut_base++ = *cmd++; + } + + /* Lock LUT */ + + base->LUTKEY = FLEXSPI_LUT_KEY_VAL; + base->LUTCR = 0x01; +} + +/* Sends a buffer of data bytes using blocking method. + * note This function blocks via polling until all bytes have been sent. + * param base FLEXSPI peripheral base address + * param buffer The data bytes to send + * param size The number of data bytes to send + * retval 0 write success without error + * STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT sequence execution timeout + * STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR IP command sequence error + * detected + * STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT IP command grant + * timeout detected. + */ + +static int imx9_flexspi_write_blocking(struct flexspi_type_s *base, + uint32_t *buffer, size_t size) +{ + uint32_t tx_watermark = ((base->IPTXFCR & FLEXSPI_IPTXFCR_TXWMRK_MASK) >> + FLEXSPI_IPTXFCR_TXWMRK_SHIFT) + 1u; + uint32_t status; + int result = 0; + uint32_t i = 0; + + /* Send data buffer */ + + while (0u != size) + { + /* Wait until there is room in the fifo. This also checks for errors */ + + while (0u == ((status = base->INTR) & + (uint32_t)FLEXSPI_IP_TX_FIFO_WATERMARK_EMPTY_FLAG)) + { + } + + result = imx9_flexspi_check_and_clear_error(base, status); + + if (0 != result) + { + return result; + } + + /* Write watermark level data into tx fifo */ + + if (size >= 8u * tx_watermark) + { + for (i = 0u; i < 2u * tx_watermark; i++) + { + base->TFDR[i] = *buffer++; + } + + size = size - 8u * tx_watermark; + } + else + { + for (i = 0u; i < (size / 4u + 1u); i++) + { + base->TFDR[i] = *buffer++; + } + size = 0u; + } + + /* Push a watermark level data into IP TX FIFO */ + + base->INTR |= (uint32_t)FLEXSPI_IP_TX_FIFO_WATERMARK_EMPTY_FLAG; + } + + return result; +} + +/* Receives a buffer of data bytes using a blocking method. + * note This function blocks via polling until all bytes have been sent. + * param base FLEXSPI peripheral base address + * param buffer The data bytes to send + * param size The number of data bytes to receive + * retval 0 read success without error + * retval STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT sequence execution + * timeout retval STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR IP command + * sequence error detected retval STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT + * IP command grant timeout detected. + */ + +static int imx9_flexspi_read_blocking(struct flexspi_type_s *base, + uint32_t *buffer, size_t size) +{ + uint32_t rx_watermark = ((base->IPRXFCR & FLEXSPI_IPRXFCR_RXWMRK_MASK) >> + FLEXSPI_IPRXFCR_RXWMRK_SHIFT) + 1u; + uint32_t status; + int result = 0; + uint32_t i = 0; + bool is_return = false; + + /* Send data buffer */ + + while (0u != size) + { + if (size >= 8u * rx_watermark) + { + /* Wait until there is room in the fifo. This also checks for + * errors. + */ + + while (0u == ((status = base->INTR) & + (uint32_t)FLEXSPI_IP_RX_FIFO_WATERMARK_AVAILABLE_FLAG)) + { + result = imx9_flexspi_check_and_clear_error(base, status); + + if (0 != result) + { + is_return = true; + break; + } + } + } + else + { + /* Wait fill level. This also checks for errors */ + + while (size > ((((base->IPRXFSTS) & FLEXSPI_IPRXFSTS_FILL_MASK) >> + FLEXSPI_IPRXFSTS_FILL_SHIFT) * 8u)) + { + result = imx9_flexspi_check_and_clear_error(base, base->INTR); + + if (0 != result) + { + is_return = true; + break; + } + } + } + + if (is_return) + { + break; + } + + result = imx9_flexspi_check_and_clear_error(base, base->INTR); + + if (0 != result) + { + break; + } + + /* Read watermark level data from rx fifo */ + + if (size >= 8u * rx_watermark) + { + for (i = 0u; i < 2u * rx_watermark; i++) + { + *buffer++ = base->RFDR[i]; + } + + size = size - 8u * rx_watermark; + } + else + { + for (i = 0u; i < ((size + 3u) / 4u); i++) + { + *buffer++ = base->RFDR[i]; + } + size = 0; + } + + /* Pop out a watermark level data from IP RX FIFO */ + + base->INTR |= (uint32_t)FLEXSPI_IP_RX_FIFO_WATERMARK_AVAILABLE_FLAG; + } + + return result; +} + +/* Brief Execute command to transfer a buffer data bytes using a blocking + * method. param base FLEXSPI peripheral base address param xfer pointer to + * the transfer structure. retval 0 command transfer success without error + * retval STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT sequence execution + * timeout retval STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR IP command + * sequence error detected retval STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT + * IP command grant timeout detected. + */ + +int imx9_flexspi_transfer_blocking_private(struct flexspi_type_s *base, + struct flexspi_transfer_s *xfer) +{ + uint32_t config_value = 0; + int result = 0; + + /* Clear sequence pointer before sending data to external devices */ + + base->FLSHCR2[xfer->port] |= FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK; + + /* Clear former pending status before start this transfer */ + + base->INTR |= FLEXSPI_INTR_AHBCMDERR_MASK | + FLEXSPI_INTR_IPCMDERR_MASK | + FLEXSPI_INTR_AHBCMDGE_MASK | + FLEXSPI_INTR_IPCMDGE_MASK; + + /* Configure base address */ + + base->IPCR0 = xfer->device_address; + + /* Reset fifos */ + + base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK; + base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK; + + /* Configure data size */ + + if ((xfer->cmd_type == FLEXSPI_READ) || + (xfer->cmd_type == FLEXSPI_WRITE) || + (xfer->cmd_type == FLEXSPI_CONFIG)) + { + config_value = FLEXSPI_IPCR1_IDATSZ(xfer->data_size); + } + + /* Configure sequence ID */ + + config_value |= + FLEXSPI_IPCR1_ISEQID((uint32_t)xfer->seq_index) | \ + FLEXSPI_IPCR1_ISEQNUM((uint32_t)xfer->seq_number - 1u); + base->IPCR1 = config_value; + + /* Start Transfer */ + + base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK; + + if ((xfer->cmd_type == FLEXSPI_WRITE) || + (xfer->cmd_type == FLEXSPI_CONFIG)) + { + result = imx9_flexspi_write_blocking(base, xfer->data, + xfer->data_size); + } + else if (xfer->cmd_type == FLEXSPI_READ) + { + result = imx9_flexspi_read_blocking(base, xfer->data, + xfer->data_size); + } + + /* Wait for bus idle */ + + while (!imx9_flexspi_get_bus_idle_status(base)) + { + } + + if (xfer->cmd_type == FLEXSPI_COMMAND) + { + result = imx9_flexspi_check_and_clear_error(base, base->INTR); + } + + return result; +} + +/**************************************************************************** + * Name: imx9_flexspi_lock + * + * Description: + * On FlexSPI buses where there are multiple devices, it will be necessary + * to lock FlexSPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock FlexSPI bus, false: unlock FlexSPI bus + * + * Returned Value: + * Semaphore status + * + ****************************************************************************/ + +static int imx9_flexspi_lock(struct flexspi_dev_s *dev, bool lock) +{ + struct imx9_flexspidev_s *priv = (struct imx9_flexspidev_s *)dev; + int ret; + + spiinfo("lock=%d\n", lock); + if (lock) + { + ret = nxmutex_lock(&priv->lock); + } + else + { + ret = nxmutex_unlock(&priv->lock); + } + + return ret; +} + +/**************************************************************************** + * Name: imx9_flexspi_transfer_blocking + * + * Description: + * Perform one FlexSPI transfer + * + * Input Parameters: + * dev - Device-specific state data + * xfer - Describes the transfer to be performed. + * + * Returned Value: + * 0 on SUCCESS, STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT, + * STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR or + * STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT otherwise + * + ****************************************************************************/ + +static int imx9_flexspi_transfer_blocking(struct flexspi_dev_s *dev, + struct flexspi_transfer_s *xfer) +{ + struct imx9_flexspidev_s *priv = (struct imx9_flexspidev_s *)dev; + + return (int)imx9_flexspi_transfer_blocking_private(priv->base, xfer); +} + +/**************************************************************************** + * Name: imx9_flexspi_software_reset + * + * Description: + * Performs a software reset of FlexSPI + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void imx9_flexspi_software_reset(struct flexspi_dev_s *dev) +{ + struct imx9_flexspidev_s *priv = (struct imx9_flexspidev_s *)dev; + + imx9_flexspi_software_reset_private(priv->base); +} + +/**************************************************************************** + * Name: imx9_flexspi_update_lut + * + * Description: + * Perform FlexSPI LUT table update + * + * Input Parameters: + * dev - Device-specific state data + * index - Index start to update + * cmd - Command array + * count - Size of the array + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void imx9_flexspi_update_lut(struct flexspi_dev_s *dev, + uint32_t index, + const uint32_t *cmd, + uint32_t count) +{ + struct imx9_flexspidev_s *priv = (struct imx9_flexspidev_s *)dev; + + imx9_flexspi_update_lut_private(priv->base, index, cmd, count); +} + +/**************************************************************************** + * Name: imx9_flexspi_set_device_config + * + * Description: + * Perform FlexSPI device config + * + * Input Parameters: + * dev - Device-specific state data + * config - Config data for external device + * port - Port + * + * Returned Value: + * none + * + ****************************************************************************/ + +static void imx9_flexspi_set_device_config(struct flexspi_dev_s *dev, + struct flexspi_device_config_s *config, + enum flexspi_port_e port) +{ + struct imx9_flexspidev_s *priv = (struct imx9_flexspidev_s *)dev; + + imx9_flexspi_set_device_config_private(priv->base, config, port); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_flexspi_initialize + * + * Description: + * Initialize the selected FlexSPI port in master mode + * + * Input Parameters: + * intf - Interface number(must be zero) + * + * Returned Value: + * Valid FlexSPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct flexspi_dev_s *imx9_flexspi_initialize(int intf) +{ + struct imx9_flexspidev_s *priv; + struct flexspi_config_s flexspi_config; + + /* The supported i.MX9 parts have only a single FlexSPI port. */ + + DEBUGASSERT(intf == 0); + + if (intf != 0) + { + return NULL; + } + + /* If this function is called multiple times, the following operations + * will be performed multiple times. + */ + + /* Select FlexSPI */ + + priv = &g_flexspi0dev; + + /* Configure and enable the FlexSPI clock root */ + + imx9_configure_clock(priv->clk_root, true); + + /* Has the FlexSPI hardware been initialized? */ + + if (!priv->initialized) + { + /* Perform hardware initialization. Puts the FlexSPI into an active + * state. + */ + + imx9_flexspi_get_default_config(&flexspi_config); + imx9_flexspi_init(priv->base, &flexspi_config); + priv->initialized = true; + } + + return &priv->flexspi; +} + +#endif /* CONFIG_IMX9_FLEXSPI */ diff --git a/arch/arm/src/imx9/imx9_flexspi.h b/arch/arm/src/imx9/imx9_flexspi.h new file mode 100644 index 00000000000..5bf0ebe156d --- /dev/null +++ b/arch/arm/src/imx9/imx9_flexspi.h @@ -0,0 +1,570 @@ +/**************************************************************************** + * arch/arm/src/imx9/imx9_flexspi.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_IMX9_IMX9_FLEXSPI_H +#define __ARCH_ARM_SRC_IMX9_IMX9_FLEXSPI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "chip.h" + +#ifdef CONFIG_IMX9_FLEXSPI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LUT - LUT 0..LUT 63 */ + +#define FLEXSPI_LUT_OPERAND0_MASK (0xffU) +#define FLEXSPI_LUT_OPERAND0_SHIFT (0U) + +/* OPERAND0 */ + +#define FLEXSPI_LUT_OPERAND0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPERAND0_SHIFT)) & FLEXSPI_LUT_OPERAND0_MASK) +#define FLEXSPI_LUT_NUM_PADS0_MASK (0x300U) +#define FLEXSPI_LUT_NUM_PADS0_SHIFT (8U) + +/* NUM_PADS0 */ + +#define FLEXSPI_LUT_NUM_PADS0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS0_SHIFT)) & FLEXSPI_LUT_NUM_PADS0_MASK) +#define FLEXSPI_LUT_OPCODE0_MASK (0xfc00U) +#define FLEXSPI_LUT_OPCODE0_SHIFT (10U) + +/* OPCODE0 */ + +#define FLEXSPI_LUT_OPCODE0(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE0_SHIFT)) & FLEXSPI_LUT_OPCODE0_MASK) +#define FLEXSPI_LUT_OPERAND1_MASK (0xff0000U) +#define FLEXSPI_LUT_OPERAND1_SHIFT (16U) + +/* OPERAND1 */ + +#define FLEXSPI_LUT_OPERAND1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPERAND1_SHIFT)) & FLEXSPI_LUT_OPERAND1_MASK) +#define FLEXSPI_LUT_NUM_PADS1_MASK (0x3000000U) +#define FLEXSPI_LUT_NUM_PADS1_SHIFT (24U) + +/* NUM_PADS1 - NUM_PADS1 */ + +#define FLEXSPI_LUT_NUM_PADS1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_NUM_PADS1_SHIFT)) & FLEXSPI_LUT_NUM_PADS1_MASK) +#define FLEXSPI_LUT_OPCODE1_MASK (0xfc000000U) +#define FLEXSPI_LUT_OPCODE1_SHIFT (26U) + +/* OPCODE1 */ + +#define FLEXSPI_LUT_OPCODE1(x) (((uint32_t)(((uint32_t)(x)) << FLEXSPI_LUT_OPCODE1_SHIFT)) & FLEXSPI_LUT_OPCODE1_MASK) + +/* Formula to form FLEXSPI instructions in LUT table */ + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | \ + FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +/* Access macros ************************************************************/ + +/**************************************************************************** + * Name: FLEXSPI_LOCK + * + * Description: + * On FlexSPI buses where there are multiple devices, it will be necessary + * to lock FlexSPI to have exclusive access to the buses for a sequence of + * transfers. The bus should be locked before the chip is selected. + * + * Input Parameters: + * dev - Device-specific state data + * lock - true: Lock FlexSPI bus, false: unlock FlexSPI bus + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define FLEXSPI_LOCK(d,l) (d)->ops->lock(d,l) + +/**************************************************************************** + * Name: FLEXSPI_TRANSFER + * + * Description: + * Perform one FlexSPI transfer + * + * Input Parameters: + * dev - Device-specific state data + * xfer - Describes the transfer to be performed. + * + * Returned Value: + * 0 on SUCCESS, STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT, + * STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR or + * STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT otherwise + * + ****************************************************************************/ + +#define FLEXSPI_TRANSFER(d,x) (d)->ops->transfer_blocking(d,x) + +/**************************************************************************** + * Name: FLEXSPI_SOFTWARE_RESET + * + * Description: + * Perform FlexSPI software reset + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define FLEXSPI_SOFTWARE_RESET(d) (d)->ops->software_reset(d) + +/**************************************************************************** + * Name: FLEXSPI_UPDATE_LUT + * + * Description: + * Perform FlexSPI LUT table update + * + * Input Parameters: + * dev - Device-specific state data + * index - Index start to update + * cmd - Command array + * count - Size of the array + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define FLEXSPI_UPDATE_LUT(d,i,c,n) (d)->ops->update_lut(d,i,c,n) + +/**************************************************************************** + * Name: FLEXSPI_SET_DEVICE_CONFIG + * + * Description: + * Perform FlexSPI device config + * + * Input Parameters: + * dev - Device-specific state data + * config - Config data for external device + * port - Port + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define FLEXSPI_SET_DEVICE_CONFIG(d,c,p) (d)->ops->set_device_config(d,c,p) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* CMD definition of FLEXSPI, use to form LUT instruction, flexspi_command */ + +enum +{ + FLEXSPI_COMMAND_STOP = 0x00, /* Stop execution, deassert CS */ + FLEXSPI_COMMAND_SDR = 0x01, /* Transmit Command code to Flash, + * using SDR mode. + */ + + FLEXSPI_COMMAND_RADDR_SDR = 0x02, /* Transmit Row Address to Flash, + * using SDR mode. + */ + + FLEXSPI_COMMAND_CADDR_SDR = 0x03, /* Transmit Column Address to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_MODE1_SDR = 0x04, /* Transmit 1-bit Mode bits to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_MODE2_SDR = 0x05, /* Transmit 2-bit Mode bits to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_MODE4_SDR = 0x06, /* Transmit 4-bit Mode bits to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_MODE8_SDR = 0x07, /* Transmit 8-bit Mode bits to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_WRITE_SDR = 0x08, /* Transmit Programming Data to + * Flash, using SDR mode. + */ + + FLEXSPI_COMMAND_READ_SDR = 0x09, /* Receive Read Data from Flash, + * using SDR mode. + */ + + FLEXSPI_COMMAND_LEARN_SDR = 0x0a, /* Receive Read Data or Preamble + * bit from Flash, SDR mode. + */ + + FLEXSPI_COMMAND_DATSZ_SDR = 0x0b, /* Transmit Read/Program Data size + * (byte) to Flash, SDR mode. + */ + + FLEXSPI_COMMAND_DUMMY_SDR = 0x0c, /* Leave data lines undriven by + * FlexSPI controller. + */ + + FLEXSPI_COMMAND_DUMMY_RWDS_SDR = 0x0d, /* Leave data lines undriven by + * FlexSPI controller, dummy cycles + * decided by RWDS. + */ + + FLEXSPI_COMMAND_DDR = 0x21, /* Transmit Command code to Flash, + * using DDR mode. + */ + + FLEXSPI_COMMAND_RADDR_DDR = 0x22, /* Transmit Row Address to Flash, + * using DDR mode. + */ + + FLEXSPI_COMMAND_CADDR_DDR = 0x23, /* Transmit Column Address to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_MODE1_DDR = 0x24, /* Transmit 1-bit Mode bits to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_MODE2_DDR = 0x25, /* Transmit 2-bit Mode bits to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_MODE4_DDR = 0x26, /* Transmit 4-bit Mode bits to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_MODE8_DDR = 0x27, /* Transmit 8-bit Mode bits to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_WRITE_DDR = 0x28, /* Transmit Programming Data to + * Flash, using DDR mode. + */ + + FLEXSPI_COMMAND_READ_DDR = 0x29, /* Receive Read Data from Flash, + * using DDR mode. + */ + + FLEXSPI_COMMAND_LEARN_DDR = 0x2a, /* Receive Read Data or Preamble + * bit from Flash, DDR mode. + */ + + FLEXSPI_COMMAND_DATSZ_DDR = 0x2b, /* Transmit Read/Program Data size + * (byte) to Flash, DDR mode. + */ + + FLEXSPI_COMMAND_DUMMY_DDR = 0x2c, /* Leave data lines undriven by + * FlexSPI controller. + */ + + FLEXSPI_COMMAND_DUMMY_RWDS_DDR = 0x2d, /* Leave data lines undriven by + * FlexSPI controller, dummy cycles + * decided by RWDS. + */ + + FLEXSPI_COMMAND_JUMP_ON_CS = 0x1f, /* Stop execution, deassert CS and + * save operand[7:0] as the + * instruction start pointer for + * next sequence + */ +}; + +/* Pad definition of FLEXSPI, use to form LUT instruction */ + +enum flexspi_pad_e +{ + FLEXSPI_1PAD = 0x00, /* Transmit command/address and transmit/receive data + * only through DATA0/DATA1. + */ + + FLEXSPI_2PAD = 0x01, /* Transmit command/address and transmit/receive data + * only through DATA[1:0]. + */ + + FLEXSPI_4PAD = 0x02, /* Transmit command/address and transmit/receive data + * only through DATA[3:0]. + */ + + FLEXSPI_8PAD = 0x03, /* Transmit command/address and transmit/receive data + * only through DATA[7:0]. + */ +}; + +/* FLEXSPI operation port select */ + +enum flexspi_port_e +{ + FLEXSPI_PORT_A1 = 0x0, /* Access flash on A1 port */ + FLEXSPI_PORT_A2, /* Access flash on A2 port */ + FLEXSPI_PORT_B1, /* Access flash on B1 port */ + FLEXSPI_PORT_B2, /* Access flash on B2 port */ + FLEXSPI_PORT_COUNT +}; + +/* Command type */ + +enum flexspi_command_type_e +{ + FLEXSPI_COMMAND, /* FlexSPI operation: Only command, both TX and Rx buffer + * are ignored. + */ + + FLEXSPI_CONFIG, /* FlexSPI operation: Configure device mode, the TX fifo + * size is fixed in LUT. + */ + + FLEXSPI_READ, /* FlexSPI operation: Read, only Rx Buffer is + * effective. + */ + + FLEXSPI_WRITE, /* FlexSPI operation: Read, only Tx Buffer is + * effective. + */ +}; + +/* Status structure of FLEXSPI */ + +enum +{ + STATUS_FLEXSPI_BUSY = 0, /* FLEXSPI is busy */ + + STATUS_FLEXSPI_SEQUENCE_EXECUTION_TIMEOUT = 1, /* Sequence execution + * timeout error occurred + * during FLEXSPI transfer. + */ + + STATUS_FLEXSPI_IP_COMMAND_SEQUENCE_ERROR = 2, /* IP command Sequence + * execution timeout error + * occurred during FLEXSPI + * transfer. + */ + + STATUS_FLEXSPI_IP_COMMAND_GRANT_TIMEOUT = 3, /* IP command grant timeout + * error occurred during + * FLEXSPI transfer. + */ +}; + +/* Transfer structure for FLEXSPI */ + +struct flexspi_transfer_s +{ + uint32_t device_address; /* Operation device address */ + enum flexspi_port_e port; /* Operation port */ + enum flexspi_command_type_e cmd_type; /* Execution command type */ + uint8_t seq_index; /* Sequence ID for command */ + uint8_t seq_number; /* Sequence number for command */ + uint32_t *data; /* Data buffer */ + size_t data_size; /* Data size in bytes */ +}; + +/* FLEXSPI interval unit for flash device select */ + +enum flexspi_cs_interval_cycle_unit_e +{ + FLEXSPI_CS_INTERVAL_UNIT1_SCK_CYCLE = 0x0, /* Chip selection interval: + * CSINTERVAL * 1 serial + * clock cycle. + */ + + FLEXSPI_CS_INTERVAL_UNIT256_SCK_CYCLE = 0x1, /* Chip selection interval: + * CSINTERVAL * 256 serial + * clock cycle. + */ +}; + +/* FLEXSPI AHB wait interval unit for writing */ + +enum flexspi_ahb_write_wait_unit_e +{ + FLEXSPI_AHB_WRITE_WAIT_UNIT2_AHB_CYCLE = 0x0, /* AWRWAIT unit is 2 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT8_AHB_CYCLE = 0x1, /* AWRWAIT unit is 8 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT32_AHB_CYCLE = 0x2, /* AWRWAIT unit is 32 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT128_AHB_CYCLE = 0x3, /* AWRWAIT unit is 128 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT512_AHB_CYCLE = 0x4, /* AWRWAIT unit is 512 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT2048_AHB_CYCLE = 0x5, /* AWRWAIT unit is 2048 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT8192_AHB_CYCLE = 0x6, /* AWRWAIT unit is 8192 + * ahb clock cycle. + */ + + FLEXSPI_AHB_WRITE_WAIT_UNIT32768_AHB_CYCLE = 0x7, /* AWRWAIT unit is 32768 + * ahb clock cycle. + */ +}; + +/* FLEXSPI sample clock source selection for Flash Reading */ + +enum flexspi_read_sample_clock_e +{ + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_INTERNALLY = 0x0u, /* Dummy Read strobe generated by FlexSPI Controller + * and loopback internally */ + + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD = 0x1u, /* Dummy Read strobe generated by FlexSPI Controller + * and loopback from DQS pad */ + + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_SCK_PAD = 0x2u, /* SCK output clock and loopback from SCK pad */ + + FLEXSPI_READ_SAMPLE_CLK_EXTERNAL_INPUT_FROM_DQS_PAD = 0x3u, /* Flash provided Read strobe and input from DQS pad */ +}; + +/* External device configuration items */ + +struct flexspi_device_config_s +{ + uint32_t flexspi_root_clk; /* FLEXSPI serial root clock */ + bool is_sck2_enabled; /* FLEXSPI use SCK2 */ + uint32_t flash_size; /* Flash size in KByte */ + + enum flexspi_cs_interval_cycle_unit_e cs_interval_unit; /* CS interval unit, 1 + * or 256 cycle. + */ + + uint16_t cs_interval; /* CS line assert interval, multiply CS + * interval unit to get the CS line assert + * interval cycles. + */ + + uint8_t cs_hold_time; /* CS line hold time */ + uint8_t cs_setup_time; /* CS line setup time */ + uint8_t data_valid_time; /* Data valid time for external device */ + uint8_t columnspace; /* Column space size */ + bool enable_word_address; /* If enable word address */ + uint8_t awr_seq_index; /* Sequence ID for AHB write command */ + uint8_t awr_seq_number; /* Sequence number for AHB write command */ + uint8_t ard_seq_index; /* Sequence ID for AHB read command */ + uint8_t ard_seq_number; /* Sequence number for AHB read command */ + + enum flexspi_ahb_write_wait_unit_e ahb_write_wait_unit; /* AHB write wait unit */ + + uint16_t ahb_write_wait_interval; /* AHB write wait interval, multiply AHB + * write interval unit to get the AHB + * write wait cycles. + */ + + bool enable_write_mask; /* Enable/Disable FLEXSPI drive DQS pin as write mask + * when writing to external device. + */ + + enum flexspi_read_sample_clock_e rx_sample_clock; /* Sample Clock source selection for Flash Reading */ +}; + +/* The FlexSPI vtable */ + +struct flexspi_dev_s; +struct flexspi_ops_s +{ + int (*lock)(struct flexspi_dev_s *dev, bool lock); + int (*transfer_blocking)(struct flexspi_dev_s *dev, + struct flexspi_transfer_s *xfer); + void (*software_reset)(struct flexspi_dev_s *dev); + void (*update_lut)(struct flexspi_dev_s *dev, + uint32_t index, const uint32_t *cmd, + uint32_t count); + void (*set_device_config)(struct flexspi_dev_s *dev, + struct flexspi_device_config_s *config, + enum flexspi_port_e port); +}; + +/* FlexSPI private data. This structure only defines the initial fields of + * the structure visible to the FlexSPI client. The specific implementation + * may add additional, device specific fields + */ + +struct flexspi_dev_s +{ + const struct flexspi_ops_s *ops; +}; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_flexspi_initialize + * + * Description: + * Initialize the selected FlexSPI port in master mode + * + * Input Parameters: + * intf - Interface number(must be zero) + * + * Returned Value: + * Valid FlexSPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct flexspi_dev_s; +struct flexspi_dev_s *imx9_flexspi_initialize(int intf); + +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_IMX9_FLEXSPI */ +#endif /* __ARCH_ARM_SRC_IMX9_IMX9_FLEXSPI_H */
