You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/05/25 14:41:40 UTC

[nuttx] branch master updated (8943d528fd -> e06ce27f56)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 8943d528fd arch/nrf52: add an option to configure QSPI sampling delay for RX data
     new 5ff6c8b403 arch/nrf53: add HFCLK192M clock support
     new 8b89730e61 arch/nrf53: add QSPI support
     new e06ce27f56 boards/nrf5340-dk: add mx25 memory support

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/src/nrf53/Kconfig                         |  56 +++++
 arch/arm/src/nrf53/Make.defs                       |   4 +
 arch/arm/src/nrf53/hardware/nrf53_clock.h          | 120 ++++++---
 .../nrf52_qspi.h => nrf53/hardware/nrf53_qspi.h}   |  95 ++++---
 arch/arm/src/nrf53/nrf53_clockconfig.c             |  22 ++
 arch/arm/src/nrf53/nrf53_clockconfig.h             |  16 ++
 .../src/{nrf52/nrf52_qspi.c => nrf53/nrf53_qspi.c} | 278 +++++++++++----------
 .../src/{nrf52/nrf52_qspi.h => nrf53/nrf53_qspi.h} |  12 +-
 .../defconfig => qspi_cpuapp/#defconfig#}          |   7 +-
 .../configs/{nsh_cpuapp => qspi_cpuapp}/defconfig  |  13 +-
 boards/arm/nrf53/nrf5340-dk/include/board.h        |  24 ++
 boards/arm/nrf53/nrf5340-dk/src/Make.defs          |   6 +-
 boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h       |  12 +
 boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c    |  10 +
 .../nrf5340-dk/src/nrf53_mx25.c}                   |  16 +-
 15 files changed, 458 insertions(+), 233 deletions(-)
 copy arch/arm/src/{nrf52/hardware/nrf52_qspi.h => nrf53/hardware/nrf53_qspi.h} (68%)
 copy arch/arm/src/{nrf52/nrf52_qspi.c => nrf53/nrf53_qspi.c} (72%)
 copy arch/arm/src/{nrf52/nrf52_qspi.h => nrf53/nrf53_qspi.h} (87%)
 copy boards/arm/nrf53/nrf5340-dk/configs/{nsh_cpuapp/defconfig => qspi_cpuapp/#defconfig#} (93%)
 copy boards/arm/nrf53/nrf5340-dk/configs/{nsh_cpuapp => qspi_cpuapp}/defconfig (81%)
 copy boards/arm/{nrf52/nrf52840-dk/src/nrf52_mx25.c => nrf53/nrf5340-dk/src/nrf53_mx25.c} (89%)


[nuttx] 01/03: arch/nrf53: add HFCLK192M clock support

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5ff6c8b4032a3b9fcf519dded65bec6672520325
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 11:45:40 2023 +0200

    arch/nrf53: add HFCLK192M clock support
    
    The HFCLK192M clock is required for QSPI to work
---
 arch/arm/src/nrf53/Kconfig                |  29 ++++++++
 arch/arm/src/nrf53/hardware/nrf53_clock.h | 120 ++++++++++++++++++++----------
 arch/arm/src/nrf53/nrf53_clockconfig.c    |  22 ++++++
 arch/arm/src/nrf53/nrf53_clockconfig.h    |  16 ++++
 4 files changed, 148 insertions(+), 39 deletions(-)

diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig
index 3c9976c62d..5f4a831156 100644
--- a/arch/arm/src/nrf53/Kconfig
+++ b/arch/arm/src/nrf53/Kconfig
@@ -28,6 +28,7 @@ config NRF53_APPCORE
 	select NRF53_HAVE_UART1
 	select NRF53_HAVE_I2C123
 	select NRF53_HAVE_SPI1234
+	select NRF53_HAVE_HFCLK192M
 
 config NRF53_NETCORE
 	bool
@@ -98,6 +99,10 @@ config NRF53_HAVE_SPI1234
 	bool
 	default n
 
+config NRF53_HAVE_HFCLK192M
+	bool
+	default n
+
 # Peripheral Selection
 
 config NRF53_I2C_MASTER
@@ -296,6 +301,30 @@ endchoice
 
 endif # NRF53_USE_LFCLK
 
+config NRF53_USE_HFCLK192M
+	bool "Enable HFCLK192M"
+	default n
+	depends on NRF53_HAVE_HFCLK192M
+	---help---
+		Enable HFCLK192M clock.
+
+if NRF53_USE_HFCLK192M
+
+choice
+	prompt "HFCLK192M source"
+	default NRF53_HFCLK192M_192
+
+config NRF53_HFCLK192M_192
+	bool "HFCLK192M is 192MHz"
+
+config NRF53_HFCLK192M_96
+	bool "HFCLK192M is 96MHz"
+
+config NRF53_HFCLK192M_48
+	bool "HFCLK192M is 48MHz"
+
+endchoice
+
 config NRF53_OSCILLATOR_LFXO
 	bool "Configure LFXO oscillator"
 	default y if NRF53_LFCLK_XTAL
diff --git a/arch/arm/src/nrf53/hardware/nrf53_clock.h b/arch/arm/src/nrf53/hardware/nrf53_clock.h
index ed5ae645c2..f52a70a922 100644
--- a/arch/arm/src/nrf53/hardware/nrf53_clock.h
+++ b/arch/arm/src/nrf53/hardware/nrf53_clock.h
@@ -34,51 +34,85 @@
 
 /* Register offsets *********************************************************/
 
-#define NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET    0x0000 /* Start HFCLK crystal oscillator */
-#define NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET     0x0004 /* Stop HFCLK crystal oscillator */
-#define NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET    0x0008 /* Start LFCLK source */
-#define NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET     0x000c /* Stop LFCLK source */
-#define NRF53_CLOCK_TASKS_CAL_OFFSET           0x0010 /* Start calibration of LFRC oscillator */
-                                                      /* TODO: */
-#define NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET 0x0100 /* HFCLK oscillator started */
-#define NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET 0x0104 /* LFCLK started */
-#define NRF53_CLOCK_EVENTS_DONE_OFFSET         0x011c /* Calibration of LFCLK RC oscillator complete event */
-                                                      /* TODO: */
-#define NRF53_CLOCK_INTENSET_OFFSET            0x0304 /* Enable interrupt */
-#define NRF53_CLOCK_INTENCLR_OFFSET            0x0308 /* Disable interrupt */
-                                                      /* TODO: */
-#define NRF53_CLOCK_HFCLKRUN_OFFSET            0x0408 /* Status indicating that HFCLKSTART task has been triggered */
-#define NRF53_CLOCK_HFCLKSTAT_OFFSET           0x040c /* HFCLK status */
-#define NRF53_CLOCK_LFCLKRUN_OFFSET            0x0414 /* Status indicating that LFCLKSTART task has been triggered */
-#define NRF53_CLOCK_LFCLKSTAT_OFFSET           0x0418 /* LFCLK status */
-#define NRF53_CLOCK_LFCLKSRCCOPY_OFFSET        0x041c /* Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */
-                                                      /* TODO: */
-#define NRF53_CLOCK_LFCLKSRC_OFFSET            0x0518 /* Clock source for the LFCLK */
-                                                      /* TODO */
+#define NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET         0x0000 /* Start HFCLK crystal oscillator */
+#define NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET          0x0004 /* Stop HFCLK crystal oscillator */
+#define NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET         0x0008 /* Start LFCLK source */
+#define NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET          0x000c /* Stop LFCLK source */
+#define NRF53_CLOCK_TASKS_CAL_OFFSET                0x0010 /* Start calibration of LFRC oscillator */
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTART_OFFSET    0x0018 /* Start HFCLKAUDIO source */
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP_OFFSET     0x001c /* Stop HFCLKAUDIO source */
+#define NRF53_CLOCK_TASKS_HFCLK192MSTART_OFFSET     0x0020 /* Start HFCLK192M source as selected in HFCLK192MSRC */
+#define NRF53_CLOCK_TASKS_HFCLK192MSTOP_OFFSET      0x0024 /* Stop HFCLK192M source */
+                                                           /* TODO: */
+#define NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET      0x0100 /* HFCLK oscillator started */
+#define NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET      0x0104 /* LFCLK started */
+#define NRF53_CLOCK_EVENTS_DONE_OFFSET              0x011c /* Calibration of LFCLK RC oscillator complete event */
+#define NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED_OFFSET 0x0120 /* HFCLKAUDIO source started */
+#define NRF53_CLOCK_EVENTS_HFCLK192MSTARTED_OFFSET  0x0124 /* HFCLK192M source started */
+                                                           /* TODO: */
+#define NRF53_CLOCK_INTENSET_OFFSET                 0x0304 /* Enable interrupt */
+#define NRF53_CLOCK_INTENCLR_OFFSET                 0x0308 /* Disable interrupt */
+                                                           /* TODO: */
+#define NRF53_CLOCK_HFCLKRUN_OFFSET                 0x0408 /* Status indicating that HFCLKSTART task has been triggered */
+#define NRF53_CLOCK_HFCLKSTAT_OFFSET                0x040c /* HFCLK status */
+#define NRF53_CLOCK_LFCLKRUN_OFFSET                 0x0414 /* Status indicating that LFCLKSTART task has been triggered */
+#define NRF53_CLOCK_LFCLKSTAT_OFFSET                0x0418 /* LFCLK status */
+#define NRF53_CLOCK_LFCLKSRCCOPY_OFFSET             0x041c /* Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */
+#define NRF53_CLOCK_HFCLKAUDIORUN_OFFSET            0x0450 /* Status indicating that HFCLKAUDIOSTART task has been triggered */
+#define NRF53_CLOCK_HFCLKAUDIOSTAT_OFFSET           0x0454 /* Status indicating which HFCLKAUDIO source is running */
+#define NRF53_CLOCK_HFCLK192MRUN_OFFSET             0x0458 /* Status indicating that HFCLK192MSTART task has been triggered */
+#define NRF53_CLOCK_HFCLK192MSTAT_OFFSET            0x045c /* Status indicating which HFCLK192M source is running */
+#define NRF53_CLOCK_HFCLKSRC_OFFSET                 0x0514 /* Clock source for HFCLK128M/HFCLK64M */
+#define NRF53_CLOCK_LFCLKSRC_OFFSET                 0x0518 /* Clock source for the LFCLK */
+#define NRF53_CLOCK_HFCLKCTRL_OFFSET                0x0558 /* HFCLK128M frequency configuration */
+#define NRF53_CLOCK_HFCLKAUDIOFREQUENCY_OFFSET      0x055c /* Audio PLL frequency */
+#define NRF53_CLOCK_HFCLKALWAYSRUN_OFFSET           0x0570 /* Automatic or manual control of HFCLK128M/HFCLK64M */
+#define NRF53_CLOCK_LFCLKALWAYSRUN_OFFSET           0x0574 /* Automatic or manual control of LFCLK */
+#define NRF53_CLOCK_HFCLKAUDIOALWAYSRUN_OFFSET      0x057c /* Automatic or manual control of HFCLKAUDIO */
+#define NRF53_CLOCK_HFCLK192MSRC_OFFSET             0x0580 /* Clock source for HFCLK192M */
+#define NRF53_CLOCK_HFCLK192MALWAYSRUN_OFFSET       0x0584 /* Automatic or manual control of HFCLK192M */
+#define NRF53_CLOCK_HFCLK192MCTRL_OFFSET            0x05b8 /* HFCLK192M frequency configuration */
 
 /* Register definitions *****************************************************/
 
-#define NRF53_CLOCK_TASKS_HFCLKSTART    (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET)
-#define NRF53_CLOCK_TASKS_HFCLKSTOP     (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET)
-#define NRF53_CLOCK_TASKS_LFCLKSTART    (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET)
-#define NRF53_CLOCK_TASKS_LFCLKSTOP     (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET)
-#define NRF53_CLOCK_TASKS_CAL           (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_CAL_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKSTART         (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKSTOP          (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_LFCLKSTART         (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_LFCLKSTOP          (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_LFCLKSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_CAL                (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_CAL_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTART    (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKAUDIOSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP     (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLKAUDIOSTOP_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLK192MSTART     (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLK192MSTART_OFFSET)
+#define NRF53_CLOCK_TASKS_HFCLK192MSTOP      (NRF53_CLOCK_BASE + NRF53_CLOCK_TASKS_HFCLK192MSTOP_OFFSET)
 /* TODO */
-#define NRF53_CLOCK_EVENTS_HFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET)
-#define NRF53_CLOCK_EVENTS_LFCLKSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET)
-#define NRF53_CLOCK_EVENTS_DONE         (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_DONE_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLKSTARTED      (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_LFCLKSTARTED      (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_LFCLKSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_DONE              (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_DONE_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLKAUDIOSTARTED_OFFSET)
+#define NRF53_CLOCK_EVENTS_HFCLK192MSTARTED  (NRF53_CLOCK_BASE + NRF53_CLOCK_EVENTS_HFCLK192MSTARTED_OFFSET)
 /* TODO */
-#define NRF53_CLOCK_INTENSET            (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENSET_OFFSET)
-#define NRF53_CLOCK_INTENCLR            (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENCLR_OFFSET)
-/* TODO */
-#define NRF53_CLOCK_HFCLKRUN            (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKRUN_OFFSET)
-#define NRF53_CLOCK_HFCLKSTAT           (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSTAT_OFFSET)
-#define NRF53_CLOCK_LFCLKRUN            (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKRUN_OFFSET)
-#define NRF53_CLOCK_LFCLKSTAT           (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSTAT_OFFSET)
-#define NRF53_CLOCK_LFCLKSRCCOPY        (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRCCOPY_OFFSET)
-/* TODO */
-#define NRF53_CLOCK_LFCLKSRC            (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRC_OFFSET)
+#define NRF53_CLOCK_INTENSET                 (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENSET_OFFSET)
+#define NRF53_CLOCK_INTENCLR                 (NRF53_CLOCK_BASE + NRF53_CLOCK_INTENCLR_OFFSET)
 /* TODO */
+#define NRF53_CLOCK_HFCLKRUN                 (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKRUN_OFFSET)
+#define NRF53_CLOCK_HFCLKSTAT                (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSTAT_OFFSET)
+#define NRF53_CLOCK_LFCLKRUN                 (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKRUN_OFFSET)
+#define NRF53_CLOCK_LFCLKSTAT                (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSTAT_OFFSET)
+#define NRF53_CLOCK_LFCLKSRCCOPY             (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRCCOPY_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIORUN            (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIORUN_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOSTAT           (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOSTAT_OFFSET)
+#define NRF53_CLOCK_HFCLK192MRUN             (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MSTAT            (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MSTAT_OFFSET)
+#define NRF53_CLOCK_HFCLKSRC                 (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKSRC_OFFSET)
+#define NRF53_CLOCK_LFCLKSRC                 (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKSRC_OFFSET)
+#define NRF53_CLOCK_HFCLKCTRL                (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKCTRL_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOFREQUENCY      (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOFREQUENCY_OFFSET)
+#define NRF53_CLOCK_HFCLKALWAYSRUN           (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_LFCLKALWAYSRUN           (NRF53_CLOCK_BASE + NRF53_CLOCK_LFCLKALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLKAUDIOALWAYSRUN      (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLKAUDIOALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MSRC             (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MSRC_OFFSET)
+#define NRF53_CLOCK_HFCLK192MALWAYSRUN       (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MALWAYSRUN_OFFSET)
+#define NRF53_CLOCK_HFCLK192MCTRL            (NRF53_CLOCK_BASE + NRF53_CLOCK_HFCLK192MCTRL_OFFSET)
 
 /* Register bit definitions *************************************************/
 
@@ -117,4 +151,12 @@
 #  define CLOCK_LFCLKSRC_SRC_LFXO      (2 << CLOCK_LFCLKSTAT_SRC_SHIFT)
 #  define CLOCK_LFCLKSRC_SRC_LFSYNT    (3 << CLOCK_LFCLKSTAT_SRC_SHIFT)
 
+/* HFCLK192MSRC Register */
+
+#define CLOCK_HFCLK192MSRC_SRC_SHIFT       (0)       /* Bits 0-1: HFCLK192M clock source */
+#define CLOCK_HFCLK192MSRC_SRC_MASK        (3 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+#  define CLOCK_HFCLK192MSRC_DIV1          (0 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+#  define CLOCK_HFCLK192MSRC_DIV2          (1 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+#  define CLOCK_HFCLK192MSRC_DIV4          (2 << CLOCK_HFCLK192MSRC_SRC_SHIFT)
+
 #endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_CLOCK_H */
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.c b/arch/arm/src/nrf53/nrf53_clockconfig.c
index 27a6862789..19bb9a346c 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.c
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.c
@@ -106,4 +106,26 @@ void nrf53_clockconfig(void)
   /* TODO: calibrate LFCLK RC oscillator */
 #endif
 #endif
+
+#ifdef CONFIG_NRF53_USE_HFCLK192M
+  /* Initialize HFCLK192M */
+
+#if defined(CONFIG_NRF53_HFCLK192M_192)
+  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV1);
+#elif defined(CONFIG_NRF53_HFCLK192M_96)
+  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV2);
+#elif defined(CONFIG_NRF53_HFCLK192M_48)
+  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV4);
+#endif
+
+  /* Trigger HFCLK192M start */
+
+  putreg32(0x0, NRF53_CLOCK_EVENTS_HFCLK192MSTARTED);
+  putreg32(0x1, NRF53_CLOCK_TASKS_HFCLK192MSTART);
+
+  while (!getreg32(NRF53_CLOCK_EVENTS_HFCLK192MSTARTED))
+    {
+      /* Wait for HFCLK192M to be running */
+    }
+#endif
 }
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.h b/arch/arm/src/nrf53/nrf53_clockconfig.h
index 050fce088b..e368253045 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.h
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.h
@@ -38,6 +38,22 @@
                                           * (32k_clk)
                                           */
 
+/* HFCLK192M configuration */
+
+#ifdef CONFIG_NRF53_USE_HFCLK192M
+#  if defined(CONFIG_NRF53_HFCLK192M_192)
+#    define NRF53_PCLK192M_FREQ    192000000
+#  elif defined(CONFIG_NRF53_HFCLK192M_96)
+#    define NRF53_PCLK192M_FREQ    96000000
+#  elif defined(CONFIG_NRF53_HFCLK192M_48)
+#    define NRF53_PCLK192M_FREQ    48000000
+#  else
+#    error Invalid configuration
+#  endif
+#else
+#  define NRF53_PCLK192M_FREQ    0
+#endif
+
 #ifndef __ASSEMBLY__
 
 /****************************************************************************


[nuttx] 02/03: arch/nrf53: add QSPI support

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 8b89730e61673b2447d4c8514009ad126dae5956
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 11:45:16 2023 +0200

    arch/nrf53: add QSPI support
---
 arch/arm/src/nrf53/Kconfig               |  27 +
 arch/arm/src/nrf53/Make.defs             |   4 +
 arch/arm/src/nrf53/hardware/nrf53_qspi.h | 224 ++++++++
 arch/arm/src/nrf53/nrf53_clockconfig.c   |   6 +-
 arch/arm/src/nrf53/nrf53_qspi.c          | 942 +++++++++++++++++++++++++++++++
 arch/arm/src/nrf53/nrf53_qspi.h          |  52 ++
 6 files changed, 1252 insertions(+), 3 deletions(-)

diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig
index 5f4a831156..fc4a279b2b 100644
--- a/arch/arm/src/nrf53/Kconfig
+++ b/arch/arm/src/nrf53/Kconfig
@@ -29,6 +29,7 @@ config NRF53_APPCORE
 	select NRF53_HAVE_I2C123
 	select NRF53_HAVE_SPI1234
 	select NRF53_HAVE_HFCLK192M
+	select NRF53_HAVE_QSPI
 
 config NRF53_NETCORE
 	bool
@@ -103,6 +104,10 @@ config NRF53_HAVE_HFCLK192M
 	bool
 	default n
 
+config NRF53_HAVE_QSPI
+	bool
+	default n
+
 # Peripheral Selection
 
 config NRF53_I2C_MASTER
@@ -212,6 +217,11 @@ config NRF53_UART1
 	select UART1_SERIALDRIVER
 	select NRF53_UART
 
+config NRF53_QSPI
+	bool "QSPI"
+	default n
+	depends on NRF53_HAVE_QSPI
+
 config NRF53_TIMER0
 	bool "TIMER0"
 	select NRF53_TIMER
@@ -325,6 +335,8 @@ config NRF53_HFCLK192M_48
 
 endchoice
 
+endif # NRF53_USE_HFCLK192M
+
 config NRF53_OSCILLATOR_LFXO
 	bool "Configure LFXO oscillator"
 	default y if NRF53_LFCLK_XTAL
@@ -610,6 +622,21 @@ config NRF53_I2C_MASTER_COPY_BUF_SIZE
 
 endmenu
 
+menu "QSPI Configuration"
+
+if NRF53_QSPI
+
+config NRF53_QSPI_RXDELAY
+	int "QSPI RX delay"
+	default 2
+	range 0 7
+	---help---
+		The input serial data sampling delay.
+
+endif # NRF53_QSPI
+
+endmenu # QSPI Configuration
+
 menuconfig NRF53_SOFTDEVICE_CONTROLLER
 	bool "SoftDevice Controller"
 	depends on ALLOW_BSDNORDIC_COMPONENTS
diff --git a/arch/arm/src/nrf53/Make.defs b/arch/arm/src/nrf53/Make.defs
index b56975db25..faf0f4a698 100644
--- a/arch/arm/src/nrf53/Make.defs
+++ b/arch/arm/src/nrf53/Make.defs
@@ -95,6 +95,10 @@ ifeq ($(CONFIG_USBDEV),y)
 CHIP_CSRCS += nrf53_usbd.c
 endif
 
+ifeq ($(CONFIG_NRF53_QSPI),y)
+CHIP_CSRCS += nrf53_qspi.c
+endif
+
 ifeq ($(CONFIG_NRF53_SOFTDEVICE_CONTROLLER),y)
 
 NRFXLIB_UNPACK  := sdk-nrfxlib
diff --git a/arch/arm/src/nrf53/hardware/nrf53_qspi.h b/arch/arm/src/nrf53/hardware/nrf53_qspi.h
new file mode 100644
index 0000000000..7ac201aa43
--- /dev/null
+++ b/arch/arm/src/nrf53/hardware/nrf53_qspi.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/hardware/nrf53_qspi.h
+ *
+ * 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_NRF53_HARDWARE_NRF53_QSPI_H
+#define __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/nrf53_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register offsets *********************************************************/
+
+#define NRF53_QSPI_TASKS_ACTIVATE_OFFSET    0x0000 /* Activate QSPI interface */
+#define NRF53_QSPI_TASKS_READSTART_OFFSET   0x0004 /* Start transfer from external flash memory to internal RAM */
+#define NRF53_QSPI_TASKS_WRITESTART_OFFSET  0x0008 /* Start transfer from internal RAM to external flash memory */
+#define NRF53_QSPI_TASKS_ERASESTART_OFFSET  0x000c /* Start external flash memory erase operation */
+#define NRF53_QSPI_TASKS_DEACTIVATE_OFFSET  0x0010 /* Deactivate QSPI interface */
+#define NRF53_QSPI_EVENTS_READY_OFFSET      0x0100 /* QSPI peripheral is ready */
+#define NRF53_QSPI_INTEN_OFFSET             0x0300 /* Enable or disable interrupt */
+#define NRF53_QSPI_INTENSET_OFFSET          0x0304 /* Enable interrupt */
+#define NRF53_QSPI_INTENCLR_OFFSET          0x0308 /* Disable interrupt */
+#define NRF53_QSPI_ENABLE_OFFSET            0x0500 /* Enable QSPI peripheral */
+#define NRF53_QSPI_READ_SRC_OFFSET          0x0504 /* Flash memory source address */
+#define NRF53_QSPI_READ_DST_OFFSET          0x0508 /* RAM destination address */
+#define NRF53_QSPI_READ_CNT_OFFSET          0x050c /* Read transfer length */
+#define NRF53_QSPI_WRITE_SRC_OFFSET         0x0510 /* Flash destination address */
+#define NRF53_QSPI_WRITE_DST_OFFSET         0x0514 /* RAM source address */
+#define NRF53_QSPI_WRITE_CNT_OFFSET         0x0518 /* Write transfer length */
+#define NRF53_QSPI_ERASE_PTR_OFFSET         0x051c /* Start address of flash block to be erased */
+#define NRF53_QSPI_ERASE_LEN_OFFSET         0x0520 /* Size of block to be erased */
+#define NRF53_QSPI_PSEL_SCK_OFFSET          0x0524 /* Pin select for serial clock SCK */
+#define NRF53_QSPI_PSEL_CSN_OFFSET          0x0528 /* Pin select for chip select signal CSN */
+#define NRF53_QSPI_PSEL_IO0_OFFSET          0x0530 /* Pin select for serial data MOSI/IO0 */
+#define NRF53_QSPI_PSEL_IO1_OFFSET          0x0534 /* Pin select for serial data MISO/IO1 */
+#define NRF53_QSPI_PSEL_IO2_OFFSET          0x0538 /* Pin select for serial data IO2 */
+#define NRF53_QSPI_PSEL_IO3_OFFSET          0x053c /* Pin select for serial data IO3 */
+#define NRF53_QSPI_XIPOFFSET_OFFSET         0x0540 /* Address offset into the external memory for XIP */
+#define NRF53_QSPI_IFCONFIG0_OFFSET         0x0544 /* Interface configuration */
+#define NRF53_QSPI_XIPEN_OFFSET             0x054c /* Enable Execute in Place operation. */
+#define NRF53_QSPI_XIPENC_KEY0_OFFSET       0x0560 /* Bits 31:0 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY1_OFFSET       0x0564 /* Bits 63:32 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY2_OFFSET       0x0568 /* Bits 95:64 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_KEY3_OFFSET       0x056c /* Bits 95:64 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_NONCE0_OFFSET     0x0570 /* Bits 127:96 of XIP AES KEY */
+#define NRF53_QSPI_XIPENC_NONCE1_OFFSET     0x0574 /* Bits 31:0 of XIP NONCE */
+#define NRF53_QSPI_XIPENC_NONCE2_OFFSET     0x0578 /* Bits 63:32 of XIP NONCE */
+#define NRF53_QSPI_XIPENC_ENABLE_OFFSET     0x057c /* Enable stream cipher for XIP */
+#define NRF53_QSPI_DMAENC_KEY0_OFFSET       0x0580 /* Bits 31:0 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY1_OFFSET       0x0584 /* Bits 63:32 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY2_OFFSET       0x0588 /* Bits 95:64 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_KEY3_OFFSET       0x058c /* Bits 127:96 of DMA AES KEY */
+#define NRF53_QSPI_DMAENC_NONCE0_OFFSET     0x0590 /* Bits 31:0 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_NONCE1_OFFSET     0x0594 /* Bits 63:32 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_NONCE2_OFFSET     0x0598 /* Bits 95:64 of DMA NONCE */
+#define NRF53_QSPI_DMAENC_ENABLE_OFFSET     0x059c /* Enable stream cipher for EasyDMA */
+#define NRF53_QSPI_IFCONFIG1_OFFSET         0x0600 /* Interface configuration */
+#define NRF53_QSPI_STATUS_OFFSET            0x0604 /* Status register */
+#define NRF53_QSPI_DPMDUR_OFFSET            0x0614 /* DPM duration */
+#define NRF53_QSPI_ADDRCONF_OFFSET          0x0624 /* Extended address configuration. */
+#define NRF53_QSPI_CINSTRCONF_OFFSET        0x0634 /* Custom instruction configuration register. */
+#define NRF53_QSPI_CINSTRDAT0_OFFSET        0x0638 /* Custom instruction data register 0. */
+#define NRF53_QSPI_CINSTRDAT1_OFFSET        0x063c /* Custom instruction data register 1. */
+#define NRF53_QSPI_IFTIMING_OFFSET          0x0640 /* SPI interface timing. */
+
+/* Register Bitfield Definitions ********************************************/
+
+/* INTEN/INTENSET/INTENCLR */
+
+#define QSPI_INT_READY                   (1 << 0)
+
+/* ENABLE */
+
+#define QSPI_ENABLE_EN                   (1)
+#define QSPI_ENABLE_DIS                  (0)
+
+/* ERASE.LEN */
+
+#define QSPI_ERASE_SECTOR                (0)
+#define QSPI_ERASE_PAGE                  (1)
+#define QSPI_ERASE_ALL                   (2)
+
+/* PSEL */
+
+#define QSPI_PSEL_PIN_SHIFT              (0)
+#define QSPI_PSEL_PORT_SHIFT             (5)
+#define QSPI_PSEL_CONNECT                (1 << 31)
+
+/* IFCONFIG0 */
+
+#define QSPI_IFCONFIG0_READOC_SHIFT      (0)
+#define QSPI_IFCONFIG0_READOC_MASK       (0x7 << QSPI_IFCONFIG0_READOC_SHIFT)
+#  define QSPI_IFCONFIG0_READOC_FASTREAD (0 << QSPI_IFCONFIG0_READOC_SHIFT)
+#  define QSPI_IFCONFIG0_READOC_READ2O   (1 << QSPI_IFCONFIG0_READOC_SHIFT)
+#  define QSPI_IFCONFIG0_READOC_READ2IO  (2 << QSPI_IFCONFIG0_READOC_SHIFT)
+#  define QSPI_IFCONFIG0_READOC_READ4O   (3 << QSPI_IFCONFIG0_READOC_SHIFT)
+#  define QSPI_IFCONFIG0_READOC_READ4IO  (4 << QSPI_IFCONFIG0_READOC_SHIFT)
+#define QSPI_IFCONFIG0_WRITEOC_SHIFT     (3)
+#define QSPI_IFCONFIG0_WRITEOC_MASK      (0x7 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#  define QSPI_IFCONFIG0_WRITEOC_PP      (0 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#  define QSPI_IFCONFIG0_WRITEOC_PP2O    (1 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#  define QSPI_IFCONFIG0_WRITEOC_PP4O    (2 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#  define QSPI_IFCONFIG0_WRITEOC_PP4IO   (3 << QSPI_IFCONFIG0_WRITEOC_SHIFT)
+#define QSPI_IFCONFIG0_ADDRMODE_24       (0 << 6)
+#define QSPI_IFCONFIG0_ADDRMODE_32       (1 << 6)
+#define QSPI_IFCONFIG0_DPMENABLE         (1 << 7)
+#define QSPI_IFCONFIG0_PPSIZE_512        (1 << 12)
+
+/* IFCONFIG1 */
+
+#define QSPI_IFCONFIG1_SCKDELAY_SHIFT    (0)
+#define QSPI_IFCONFIG1_SCKDELAY_MASK     (0xff << QSPI_IFCONFIG1_SCKDELAY_SHIFT)
+#define QSPI_IFCONFIG1_DPMEN_EXIT        (0 << 24)
+#define QSPI_IFCONFIG1_DPMEN_ENTER       (1 << 24)
+#define QSPI_IFCONFIG1_SPIMODE_0         (0 << 25)
+#define QSPI_IFCONFIG1_SPIMODE_3         (1 << 25)
+#define QSPI_IFCONFIG1_SCKFREQ_SHIFT     (28)
+#define QSPI_IFCONFIG1_SCKFREQ_MASK      (0xf << QSPI_IFCONFIG1_SCKFREQ_SHIFT)
+
+/* STATUS */
+
+#define QSPI_STATUS_DPM                  (1 << 2)
+#define QSPI_STATUS_READY                (1 << 3)
+#define QSPI_STATUS_SREG_SHIFT           (24)
+#define QSPI_STATUS_SREG_MASK            (0xff << QSPI_STATUS_SREG_SHIFT)
+
+/* DPMDUR */
+
+#define QSPI_DPMDUR_ENTER_SHIFT          (0)
+#define QSPI_DPMDUR_ENTER_MASK           (0xffff << QSPI_DPMDUR_ENTER_SHIFT)
+#define QSPI_DPMDUR_EXIT_SHIFT           (16)
+#define QSPI_DPMDUR_EXIT_MASK            (0xffff << QSPI_DPMDUR_EXIT_SHIFT)
+
+/* ADDRCONF */
+
+#define QSPI_ADDRCONF_OPCODE_SHIFT       (0)
+#define QSPI_ADDRCONF_OPCODE_MASK        (0xff << QSPI_ADDRCONF_OPCODE_SHIFT)
+#define QSPI_ADDRCONF_BYTE0_SHIFT        (8)
+#define QSPI_ADDRCONF_BYTE0_MASK         (0xff << QSPI_ADDRCONF_BYTE0_SHIFT)
+#define QSPI_ADDRCONF_BYTE1_SHIFT        (16)
+#define QSPI_ADDRCONF_BYTE1_MASK         (0xff << QSPI_ADDRCONF_BYTE1_SHIFT)
+#define QSPI_ADDRCONF_MODE_SHIFT         (24)
+#define QSPI_ADDRCONF_MODE_MASK          (0x3 << QSPI_ADDRCONF_MODE_SHIFT)
+#  define QSPI_ADDRCONF_MODE_NOINSTR     (0 << QSPI_ADDRCONF_MODE_SHIFT)
+#  define QSPI_ADDRCONF_MODE_OPCODE      (1 << QSPI_ADDRCONF_MODE_SHIFT)
+#  define QSPI_ADDRCONF_MODE_OPBYTE0     (2 << QSPI_ADDRCONF_MODE_SHIFT)
+#  define QSPI_ADDRCONF_MODE_ALL         (3 << QSPI_ADDRCONF_MODE_SHIFT)
+#define QSPI_ADDRCONF_WIPWAIT            (1 << 26)
+#define QSPI_ADDRCONF_WREN               (1 << 27)
+
+/* CINSTRCONF */
+
+#define QSPI_CINSTRCONF_OPCODE_SHIFT     (0)
+#define QSPI_CINSTRCONF_OPCODE_MASK      (0xff << QSPI_CINSTRCONF_OPCODE_SHIFT)
+#define QSPI_CINSTRCONF_LENGTH_SHIFT     (8)
+#define QSPI_CINSTRCONF_LENGTH_MASK      (0xf << QSPI_CINSTRCONF_LENGTH_SHIFT)
+#define QSPI_CINSTRCONF_LENGTH(n)        ((n) << QSPI_CINSTRCONF_LENGTH_SHIFT)
+#define QSPI_CINSTRCONF_LIO2             (1 << 12)
+#define QSPI_CINSTRCONF_LIO3             (1 << 13)
+#define QSPI_CINSTRCONF_WIPWAIT          (1 << 14)
+#define QSPI_CINSTRCONF_WREN             (1 << 15)
+#define QSPI_CINSTRCONF_LFEN             (1 << 16)
+#define QSPI_CINSTRCONF_LFSTOP_STOP      (1 << 17)
+
+/* CINSTRDAT0 */
+
+#define QSPI_CINSTRDAT0_BYTE0_SHIFT      (0)
+#define QSPI_CINSTRDAT0_BYTE0_MASK       (0xff << QSPI_CINSTRDAT0_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE0(n)         ((n) << QSPI_CINSTRDAT0_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE1_SHIFT      (8)
+#define QSPI_CINSTRDAT0_BYTE1_MASK       (0xff << QSPI_CINSTRDAT0_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE1(n)         ((n) << QSPI_CINSTRDAT0_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE2_SHIFT      (16)
+#define QSPI_CINSTRDAT0_BYTE2_MASK       (0xff << QSPI_CINSTRDAT0_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE2(n)         ((n) << QSPI_CINSTRDAT0_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE3_SHIFT      (24)
+#define QSPI_CINSTRDAT0_BYTE3_MASK       (0xff << QSPI_CINSTRDAT0_BYTE3_SHIFT)
+#define QSPI_CINSTRDAT0_BYTE3(n)         ((n) << QSPI_CINSTRDAT0_BYTE3_SHIFT)
+
+/* CINSTRDAT1 */
+
+#define QSPI_CINSTRDAT1_BYTE0_SHIFT      (0)
+#define QSPI_CINSTRDAT1_BYTE0_MASK       (0xff << QSPI_CINSTRDAT1_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE0(n)         ((n) << QSPI_CINSTRDAT1_BYTE0_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE1_SHIFT      (8)
+#define QSPI_CINSTRDAT1_BYTE1_MASK       (0xff << QSPI_CINSTRDAT1_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE1(n)         ((n) << QSPI_CINSTRDAT1_BYTE1_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE2_SHIFT      (16)
+#define QSPI_CINSTRDAT1_BYTE2_MASK       (0xff << QSPI_CINSTRDAT1_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE2(n)         ((n) << QSPI_CINSTRDAT1_BYTE2_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE3_SHIFT      (24)
+#define QSPI_CINSTRDAT1_BYTE3_MASK       (0xff << QSPI_CINSTRDAT1_BYTE3_SHIFT)
+#define QSPI_CINSTRDAT1_BYTE3(n)         ((n) << QSPI_CINSTRDAT1_BYTE3_SHIFT)
+
+/* IFTIMING */
+
+#define QSPI_IFTIMING_RXDELAY_SHIFT      (8)
+#define QSPI_IFTIMING_RXDELAY_MASK       (0xff << QSPI_IFTIMING_RXDELAY_SHIFT)
+#define QSPI_IFTIMING_RXDELAY(n)         ((n) << QSPI_IFTIMING_RXDELAY_SHIFT)
+
+#endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_QSPI_H */
diff --git a/arch/arm/src/nrf53/nrf53_clockconfig.c b/arch/arm/src/nrf53/nrf53_clockconfig.c
index 19bb9a346c..e205b33634 100644
--- a/arch/arm/src/nrf53/nrf53_clockconfig.c
+++ b/arch/arm/src/nrf53/nrf53_clockconfig.c
@@ -111,11 +111,11 @@ void nrf53_clockconfig(void)
   /* Initialize HFCLK192M */
 
 #if defined(CONFIG_NRF53_HFCLK192M_192)
-  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV1);
+  putreg32(CLOCK_HFCLK192MSRC_DIV1, NRF53_CLOCK_HFCLK192MSRC);
 #elif defined(CONFIG_NRF53_HFCLK192M_96)
-  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV2);
+  putreg32(CLOCK_HFCLK192MSRC_DIV2, NRF53_CLOCK_HFCLK192MSRC);
 #elif defined(CONFIG_NRF53_HFCLK192M_48)
-  putreg32(NRF53_CLOCK_HFCLK192MSRC, CLOCK_HFCLK192MSRC_DIV4);
+  putreg32(CLOCK_HFCLK192MSRC_DIV4, NRF53_CLOCK_HFCLK192MSRC);
 #endif
 
   /* Trigger HFCLK192M start */
diff --git a/arch/arm/src/nrf53/nrf53_qspi.c b/arch/arm/src/nrf53/nrf53_qspi.c
new file mode 100644
index 0000000000..7f06a96596
--- /dev/null
+++ b/arch/arm/src/nrf53/nrf53_qspi.c
@@ -0,0 +1,942 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/nrf53_qspi.c
+ *
+ * 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 <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/mutex.h>
+#include <nuttx/semaphore.h>
+#include <arch/board/board.h>
+
+#include "arm_internal.h"
+
+#include "hardware/nrf53_qspi.h"
+
+#include "nrf53_clockconfig.h"
+#include "nrf53_gpio.h"
+#include "nrf53_qspi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if ((NRF53_PCLK192M_FREQ != 192000000) && (NRF53_PCLK192M_FREQ != 96000000))
+#  error not supported PCLK192M frequency
+#endif
+
+/* QSPI frequency limits */
+
+#define NRF53_QSPI_FREQMAX (NRF53_PCLK192M_FREQ / (2 * 1))
+#define NRF53_QSPI_FREQMIN (NRF53_PCLK192M_FREQ / (2 * 16))
+
+/* Instruction handled by the NRF53 QSPI peripheral */
+
+#define QSPI_SECTOR_ERASE 0x20
+#define QSPI_BLOCK_ERASE  0xd8
+#define QSPI_ALL_ERASE    0xc7
+
+/* QSPI memory synchronization */
+
+#define MEMORY_SYNC()     do { ARM_DSB(); ARM_ISB(); } while (0)
+
+/* Ensure that the DMA buffers are word-aligned. */
+
+#define ALIGN_SHIFT       2
+#define ALIGN_MASK        3
+#define ALIGN_UP(n)       (((n)+ALIGN_MASK) & ~ALIGN_MASK)
+#define IS_ALIGNED(n)     (((uint32_t)(n) & ALIGN_MASK) == 0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct nrf53_qspidev_s
+{
+  struct qspi_dev_s qspi;           /* Externally visible part of the QSPI interface */
+  mutex_t           lock;           /* Assures mutually exclusive access to QSPI */
+  uint32_t          base;           /* QSPI base address */
+  uint32_t          actual;         /* Actual clock frequency */
+  uint32_t          frequency;      /* Requested clock frequency */
+  bool              initialized;    /* TRUE: Controller has been initialized */
+  uint8_t           intf;           /* QSPI controller number (0) */
+  uint8_t           mode;           /* Mode 0,3 */
+  sem_t             op_sem;         /* Block until complete */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helpers */
+
+static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
+                                     uint32_t offset,
+                                     uint32_t value);
+static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
+                                         uint32_t offset);
+static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
+                                      struct qspi_cmdinfo_s *cmdinfo);
+static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
+                                      struct qspi_cmdinfo_s *cmdinfo);
+
+/* QSPI operations */
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock);
+static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
+                                        uint32_t frequency);
+static void nrf53_qspi_setmode(struct qspi_dev_s *dev,
+                               enum qspi_mode_e mode);
+static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits);
+static int nrf53_qspi_command(struct qspi_dev_s *dev,
+                             struct qspi_cmdinfo_s *cmdinfo);
+static int nrf53_qspi_memory(struct qspi_dev_s *dev,
+                             struct qspi_meminfo_s *meminfo);
+static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen);
+static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer);
+
+static int nrf53_qspi_interrupt(int irq, void *context, void *arg);
+static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct qspi_ops_s g_qspi_ops =
+{
+  .lock              = nrf53_qspi_lock,
+  .setfrequency      = nrf53_qspi_setfrequency,
+  .setmode           = nrf53_qspi_setmode,
+  .setbits           = nrf53_qspi_setbits,
+  .command           = nrf53_qspi_command,
+  .memory            = nrf53_qspi_memory,
+  .alloc             = nrf53_qspi_alloc,
+  .free              = nrf53_qspi_free,
+};
+
+static struct nrf53_qspidev_s g_qspi0_dev =
+{
+  .qspi      =
+  {
+    .ops     = &g_qspi_ops,
+  },
+  .lock      = NXMUTEX_INITIALIZER,
+  .op_sem    = SEM_INITIALIZER(0),
+  .base      = NRF53_QSPI_BASE,
+  .intf      = 0
+};
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_putreg
+ *
+ * Description:
+ *   Put a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline void nrf53_qspi_putreg(struct nrf53_qspidev_s *priv,
+                                     uint32_t offset,
+                                     uint32_t value)
+{
+  putreg32(value, priv->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_getreg
+ *
+ * Description:
+ *   Get a 32-bit register value by offset
+ *
+ ****************************************************************************/
+
+static inline uint32_t nrf53_qspi_getreg(struct nrf53_qspidev_s *priv,
+                                        uint32_t offset)
+{
+  return getreg32(priv->base + offset);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_lock
+ *
+ * Description:
+ *   On QSPI buses where there are multiple devices, it will be necessary to
+ *   lock QSPI to have exclusive access to the buses for a sequence of
+ *   transfers.  The bus should be locked before the chip is selected. After
+ *   locking the QSPI bus, the caller should then also call the setfrequency,
+ *   setbits, and setmode methods to make sure that the QSPI is properly
+ *   configured for the device.  If the QSPI bus is being shared, then it
+ *   may have been left in an incompatible state.
+ *
+ * Input Parameters:
+ *   dev  - Device-specific state data
+ *   lock - true: Lock QSPI bus, false: unlock QSPI bus
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_lock(struct qspi_dev_s *dev, bool lock)
+{
+  struct nrf53_qspidev_s *priv = (struct nrf53_qspidev_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: nrf53_qspi_setfrequency
+ *
+ * Description:
+ *   Set the QSPI frequency.
+ *
+ * Input Parameters:
+ *   dev -       Device-specific state data
+ *   frequency - The QSPI frequency requested
+ *
+ * Returned Value:
+ *   Returns the actual frequency selected
+ *
+ ****************************************************************************/
+
+static uint32_t nrf53_qspi_setfrequency(struct qspi_dev_s *dev,
+                                        uint32_t frequency)
+{
+  struct nrf53_qspidev_s *priv    = (struct nrf53_qspidev_s *)dev;
+  uint32_t                sckfreq = 0;
+  uint32_t                actual  = 0;
+  uint32_t                regval  = 0;
+
+  spiinfo("frequency=%ld\n", frequency);
+  DEBUGASSERT(priv);
+
+  /* Check if the requested frequency is the same as the frequency
+   * selection
+   */
+
+  if (priv->frequency == frequency)
+    {
+      /* We are already at this frequency.  Return the actual. */
+
+      return priv->actual;
+    }
+
+  /* Get prescaler */
+
+  if (frequency <= NRF53_QSPI_FREQMIN)
+    {
+      sckfreq = 15;
+    }
+  else if (frequency <= NRF53_QSPI_FREQMAX)
+    {
+      sckfreq = ((NRF53_PCLK192M_FREQ / 2) / frequency) - 1;
+    }
+  else
+    {
+      sckfreq = 0;
+    }
+
+  /* Modify register */
+
+  regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
+  regval &= ~QSPI_IFCONFIG1_SCKFREQ_MASK;
+  regval |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_SHIFT;
+  nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
+
+  /* Calculate the new actual frequency */
+
+  actual = NRF53_PCLK192M_FREQ / (2 * (sckfreq + 1));
+
+  /* Save the frequency setting */
+
+  priv->frequency = frequency;
+  priv->actual    = actual;
+
+  spiinfo("Frequency %ld->%ld\n", frequency, actual);
+
+  return actual;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_setmode
+ *
+ * Description:
+ *   Set the QSPI mode. Optional.  See enum qspi_mode_e for mode definitions.
+ *   NOTE:  the NRF53 QSPI supports only modes 0 and 3.
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   mode - The QSPI mode requested
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_setmode(struct qspi_dev_s *dev, enum qspi_mode_e mode)
+{
+  struct nrf53_qspidev_s *priv    = (struct nrf53_qspidev_s *)dev;
+  uint32_t                regval  = 0;
+
+  spiinfo("mode=%d\n", mode);
+
+  /* Has the mode changed? */
+
+  if (mode != priv->mode)
+    {
+      regval = nrf53_qspi_getreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET);
+
+      switch (mode)
+        {
+          case QSPIDEV_MODE0:
+            {
+              regval |= (QSPI_IFCONFIG1_SPIMODE_0);
+              break;
+            }
+
+          case QSPIDEV_MODE3:
+            {
+              regval |= (QSPI_IFCONFIG1_SPIMODE_3);
+              break;
+            }
+
+          case QSPIDEV_MODE1:
+          case QSPIDEV_MODE2:
+            {
+              spiinfo("unsupported mode=%d\n", mode);
+
+              /* No break here */
+            }
+          default:
+            {
+              DEBUGASSERT(0);
+              return;
+            }
+        }
+
+      /* Write new mode */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG1_OFFSET, regval);
+
+      /* Save the mode so that subsequent re-configurations will be faster */
+
+      priv->mode = mode;
+    }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_setbits
+ *
+ * Description:
+ *   Set the number of bits per word.
+ *   NOTE:  the NRF53 QSPI only supports 8 bits, so this does nothing.
+ *
+ * Input Parameters:
+ *   dev -  Device-specific state data
+ *   nbits - The number of bits requests
+ *
+ * Returned Value:
+ *   none
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_setbits(struct qspi_dev_s *dev, int nbits)
+{
+  if (nbits != 8)
+    {
+      spiinfo("unsupported nbits=%d\n", nbits);
+      DEBUGASSERT(FALSE);
+    }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_cinstrdata_get
+ *
+ * Description:
+ *   Get command data
+ *
+ * Input Parameters:
+ *   priv - Device state structure.
+ *   cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ *   Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_cinstrdata_get(struct nrf53_qspidev_s *priv,
+                                      struct qspi_cmdinfo_s *cmdinfo)
+{
+  uint32_t regval = 0;
+  int      i      = 0;
+  uint8_t *buffer = cmdinfo->buffer;
+
+  DEBUGASSERT(cmdinfo->buflen <= 8);
+
+  /* Get Bytes 0-3 */
+
+  regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET);
+
+  if (cmdinfo->buflen > 0)
+    {
+      for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
+        {
+          buffer[i] = (regval >> (i * 8)) & 0xff;
+        }
+    }
+
+  /* Write Bytes 4-7 */
+
+  regval = nrf53_qspi_getreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET);
+
+  if (cmdinfo->buflen > 4)
+    {
+      for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
+        {
+          buffer[i] = (regval >> ((i - 4) * 8)) & 0xff;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_cinstrdata_put
+ *
+ * Description:
+ *   Put command data
+ *
+ * Input Parameters:
+ *   priv - Device state structure.
+ *   cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ *   Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_cinstrdata_put(struct nrf53_qspidev_s *priv,
+                                      struct qspi_cmdinfo_s *cmdinfo)
+{
+  uint32_t regval = 0;
+  int      i      = 0;
+  uint8_t *buffer = cmdinfo->buffer;
+
+  DEBUGASSERT(cmdinfo->buflen <= 8);
+
+  regval = 0;
+
+  if (cmdinfo->buflen > 0)
+    {
+      for (i = 0; (i < 4) && (i < cmdinfo->buflen); i += 1)
+        {
+          regval |= (buffer[i] << (i * 8));
+        }
+    }
+
+  /* Write Bytes 0-3 */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT0_OFFSET, regval);
+
+  regval = 0;
+  if (cmdinfo->buflen > 4)
+    {
+      for (i = 4; (i < 8) && (i < cmdinfo->buflen); i += 1)
+        {
+          regval |= (buffer[i] << ((i - 4) * 8));
+        }
+    }
+
+  /* Write Bytes 4-7 */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRDAT1_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_command
+ *
+ * Description:
+ *   Perform one QSPI data transfer
+ *
+ *   TODO: long frame mode not supported
+ *
+ * Input Parameters:
+ *   dev     - Device-specific state data
+ *   cmdinfo - Describes the command transfer to be performed.
+ *
+ * Returned Value:
+ *   Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_command(struct qspi_dev_s *dev,
+                              struct qspi_cmdinfo_s *cmdinfo)
+{
+  struct nrf53_qspidev_s *priv   = (struct nrf53_qspidev_s *)dev;
+  uint32_t                regval = 0;
+
+  DEBUGASSERT(cmdinfo->cmd < 256);
+
+  if (QSPICMD_ISADDRESS(cmdinfo->flags))
+    {
+      /* Only ERASE commands supported */
+
+      switch (cmdinfo->cmd)
+        {
+          case QSPI_SECTOR_ERASE:
+            {
+              regval = QSPI_ERASE_SECTOR;
+              break;
+            }
+
+          case QSPI_BLOCK_ERASE:
+            {
+              regval = QSPI_ERASE_PAGE;
+              break;
+            }
+
+          case QSPI_ALL_ERASE:
+            {
+              regval = QSPI_ERASE_ALL;
+              break;
+            }
+
+          default:
+            {
+              /* Not supported addressed command */
+
+              DEBUGASSERT(0);
+              return -EINVAL;
+            }
+        }
+
+      /* Configure erase length */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_LEN_OFFSET, regval);
+
+      /* Configure erase address */
+
+      regval = cmdinfo->addr;
+      nrf53_qspi_putreg(priv, NRF53_QSPI_ERASE_PTR_OFFSET, regval);
+
+      /* Start erase operation */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ERASESTART_OFFSET, 1);
+
+      /* Wait for the READY event.
+       * TODO: add timeout.
+       *
+       * NOTE: READ event only signals that the erase operation
+       *       has been started.
+       */
+
+      nxsem_wait(&priv->op_sem);
+
+      return OK;
+    }
+
+  if (QSPICMD_ISWRITE(cmdinfo->flags))
+    {
+      /* Write data to CINSTRDAT registers */
+
+      nrf53_qspi_cinstrdata_put(priv, cmdinfo);
+    }
+
+  /* Configure custom instruction */
+
+  regval = cmdinfo->cmd << QSPI_ADDRCONF_OPCODE_SHIFT;
+  regval |= QSPI_CINSTRCONF_LENGTH(cmdinfo->buflen + 1);
+
+  if (QSPICMD_ISWRITE(cmdinfo->flags))
+    {
+      /* Write request */
+
+      regval |= QSPI_CINSTRCONF_WREN;
+
+      /* Wait for write complete before sending command */
+
+      regval |= QSPI_CINSTRCONF_WIPWAIT;
+    }
+
+  /* IO2 and IO3 high during transmission of custom instruction */
+
+  regval |= QSPI_CINSTRCONF_LIO2 | QSPI_CINSTRCONF_LIO3;
+
+  /* Write CINSTRCONF register to initiate transfer */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_CINSTRCONF_OFFSET, regval);
+
+  /* Wait for the READY event.
+   * TODO: add timeout.
+   */
+
+  nxsem_wait(&priv->op_sem);
+
+  if (QSPICMD_ISREAD(cmdinfo->flags))
+    {
+      /* Get response */
+
+      nrf53_qspi_cinstrdata_get(priv, cmdinfo);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_memory
+ *
+ * Description:
+ *   Perform one QSPI memory transfer
+ *
+ * Input Parameters:
+ *   dev     - Device-specific state data
+ *   meminfo - Describes the memory transfer to be performed.
+ *
+ * Returned Value:
+ *   Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_memory(struct qspi_dev_s *dev,
+                             struct qspi_meminfo_s *meminfo)
+{
+  struct nrf53_qspidev_s *priv   = (struct nrf53_qspidev_s *)dev;
+
+  DEBUGASSERT(meminfo->buffer != NULL && meminfo->buflen > 0);
+
+  if (QSPIMEM_ISWRITE(meminfo->flags))
+    {
+      /* Configure data transfer */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_SRC_OFFSET,
+                        meminfo->addr);
+      nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_DST_OFFSET,
+                        (uint32_t) meminfo->buffer);
+      nrf53_qspi_putreg(priv, NRF53_QSPI_WRITE_CNT_OFFSET,
+                        meminfo->buflen);
+
+      /* Start WRITE task */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_WRITESTART_OFFSET, 1);
+    }
+  else
+    {
+      /* Configure data transfer */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_READ_SRC_OFFSET,
+                        meminfo->addr);
+      nrf53_qspi_putreg(priv, NRF53_QSPI_READ_DST_OFFSET,
+                        (uint32_t) meminfo->buffer);
+      nrf53_qspi_putreg(priv, NRF53_QSPI_READ_CNT_OFFSET,
+                        meminfo->buflen);
+
+      /* Start READ task */
+
+      nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_READSTART_OFFSET, 1);
+    }
+
+  /* Wait for the READY event.
+   * TODO: add timeout.
+   */
+
+  nxsem_wait(&priv->op_sem);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_alloc
+ *
+ * Description:
+ *   Allocate a buffer suitable for DMA data transfer
+ *
+ * Input Parameters:
+ *   dev    - Device-specific state data
+ *   buflen - Buffer length to allocate in bytes
+ *
+ * Returned Value:
+ *   Address of the allocated memory on success; NULL is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static void *nrf53_qspi_alloc(struct qspi_dev_s *dev, size_t buflen)
+{
+  return kmm_malloc(ALIGN_UP(buflen));
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_free
+ *
+ * Description:
+ *   Free memory returned by QSPI_ALLOC
+ *
+ * Input Parameters:
+ *   dev    - Device-specific state data
+ *   buffer - Buffer previously allocated via QSPI_ALLOC
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void nrf53_qspi_free(struct qspi_dev_s *dev, void *buffer)
+{
+  if (buffer)
+    {
+      kmm_free(buffer);
+    }
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_interrupt
+ *
+ * Description:
+ *   Interrupt handler; we handle all QSPI cases -- reads, writes,
+ *   automatic status polling, etc.
+ *
+ * Input Parameters:
+ *   irq  -
+ *   context  -
+ *   qrg  -
+ *
+ * Returned Value:
+ *   OK means we handled it
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_interrupt(int irq, void *context, void *arg)
+{
+  struct nrf53_qspidev_s *priv = arg;
+
+  /* Clear READY event */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_EVENTS_READY_OFFSET, 0);
+
+  /* Signal TASK complete */
+
+  nxsem_post(&g_qspi0_dev.op_sem);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: nrf53_qspi_hw_initialize
+ *
+ * Description:
+ *   Initialize the QSPI peripheral from hardware reset.
+ *
+ * Input Parameters:
+ *   priv - Device state structure.
+ *
+ * Returned Value:
+ *   Zero (OK) on SUCCESS, a negated errno on value of failure
+ *
+ ****************************************************************************/
+
+static int nrf53_qspi_hw_initialize(struct nrf53_qspidev_s *priv)
+{
+  uint32_t regval = 0;
+  int      pin    = 0;
+  int      port   = 0;
+  int      ret    = 0;
+
+  /* Only for QSPI0 */
+
+  DEBUGASSERT(priv->intf == 0);
+
+  /* Attach the interrupt handler */
+
+  ret = irq_attach(NRF53_IRQ_QSPI, nrf53_qspi_interrupt, priv);
+  if (ret < 0)
+    {
+      spierr("ERROR: Failed to attach QSPI irq\n");
+      return ret;
+    }
+
+  /* SCK pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_SCK_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_SCK_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_SCK_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_SCK_OFFSET, regval);
+
+  /* CSN pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_CSN_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_CSN_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_CSN_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_CSN_OFFSET, regval);
+
+  /* IO0 pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_IO0_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO0_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_IO0_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO0_OFFSET, regval);
+
+  /* IO1 pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_IO1_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO1_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_IO1_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO1_OFFSET, regval);
+
+  /* IO2 pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_IO2_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO2_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_IO2_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO2_OFFSET, regval);
+
+  /* IO3 pin */
+
+  nrf53_gpio_config(NRF53_QSPI0_IO3_PIN | GPIO_DRIVE_H0H1);
+  pin = GPIO_PIN_DECODE(NRF53_QSPI0_IO3_PIN);
+  port = GPIO_PORT_DECODE(NRF53_QSPI0_IO3_PIN);
+  regval = (pin << QSPI_PSEL_PIN_SHIFT) | (port << QSPI_PSEL_PORT_SHIFT);
+  nrf53_qspi_putreg(priv, NRF53_QSPI_PSEL_IO3_OFFSET, regval);
+
+  /* Configure quad data line SPI */
+
+  regval = (QSPI_IFCONFIG0_READOC_READ4IO | QSPI_IFCONFIG0_WRITEOC_PP4IO);
+  regval |= QSPI_IFCONFIG0_PPSIZE_512;
+  nrf53_qspi_putreg(priv, NRF53_QSPI_IFCONFIG0_OFFSET, regval);
+
+  /* Enable READY interrupt */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_INTENSET_OFFSET, QSPI_INT_READY);
+
+  /* Configure RX delay */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_IFTIMING_OFFSET,
+                    QSPI_IFTIMING_RXDELAY(CONFIG_NRF53_QSPI_RXDELAY));
+
+  /* Enable QSPI interrupts */
+
+  up_enable_irq(NRF53_IRQ_QSPI);
+
+  /* Enable QSPI */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_ENABLE_OFFSET, 1);
+
+  /* Activate QSPI */
+
+  nrf53_qspi_putreg(priv, NRF53_QSPI_TASKS_ACTIVATE_OFFSET, 1);
+
+  /* Wait for READY event.
+   * TODO: add timeout.
+   */
+
+  nxsem_wait(&priv->op_sem);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_initialize
+ *
+ * Description:
+ *   Initialize the selected QSPI port in master mode
+ *
+ * Input Parameters:
+ *   intf - Interface number(must be zero)
+ *
+ * Returned Value:
+ *   Valid QSPI device structure reference on success; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct qspi_dev_s *nrf53_qspi_initialize(int intf)
+{
+  struct nrf53_qspidev_s *priv = NULL;
+  int                     ret  = OK;
+
+  /* The NRF53 has only a single QSPI port */
+
+  spiinfo("intf: %d\n", intf);
+  DEBUGASSERT(intf == 0);
+
+  /* Select the QSPI interface */
+
+  if (intf == 0)
+    {
+      /* Select QSPI0 */
+
+      priv = &g_qspi0_dev;
+    }
+  else
+    {
+      spierr("ERROR: QSPI%d not supported\n", intf);
+      return NULL;
+    }
+
+  /* Has the QSPI hardware been initialized? */
+
+  if (!priv->initialized)
+    {
+      /* Perform hardware initialization.  Puts the QSPI into an active
+       * state.
+       */
+
+      ret = nrf53_qspi_hw_initialize(priv);
+      if (ret < 0)
+        {
+          spierr("ERROR: Failed to initialize QSPI hardware\n");
+          irq_detach(NRF53_IRQ_QSPI);
+          return NULL;
+        }
+
+      /* Enable interrupts at the NVIC */
+
+      priv->initialized = true;
+    }
+
+  return &priv->qspi;
+}
diff --git a/arch/arm/src/nrf53/nrf53_qspi.h b/arch/arm/src/nrf53/nrf53_qspi.h
new file mode 100644
index 0000000000..f0c1d3a660
--- /dev/null
+++ b/arch/arm/src/nrf53/nrf53_qspi.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * arch/arm/src/nrf53/nrf53_qspi.h
+ *
+ * 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_NRF53_NRF53_QSPI_H
+#define __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/spi/qspi.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_qspi_initialize
+ *
+ * Description:
+ *   Initialize the selected QSPI port in master mode
+ *
+ * Input Parameters:
+ *   intf - Interface number(must be zero)
+ *
+ * Returned Value:
+ *   Valid QSPI device structure reference on success; a NULL on failure
+ *
+ ****************************************************************************/
+
+struct qspi_dev_s *nrf53_qspi_initialize(int intf);
+
+#endif  /* __ARCH_ARM_SRC_NRF53_NRF53_QSPI_H */


[nuttx] 03/03: boards/nrf5340-dk: add mx25 memory support

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit e06ce27f566656dd25f943f7935bebcf6045d59d
Author: raiden00pl <ra...@railab.me>
AuthorDate: Tue May 23 12:00:07 2023 +0200

    boards/nrf5340-dk: add mx25 memory support
    
    From now on-board QSPI memory is supported.
---
 .../nrf5340-dk/configs/qspi_cpuapp/#defconfig#     |  44 +++++++++
 .../nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig |  50 ++++++++++
 boards/arm/nrf53/nrf5340-dk/include/board.h        |  24 +++++
 boards/arm/nrf53/nrf5340-dk/src/Make.defs          |   6 +-
 boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h       |  12 +++
 boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c    |  10 ++
 boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c       | 107 +++++++++++++++++++++
 7 files changed, 252 insertions(+), 1 deletion(-)

diff --git a/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig# b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig#
new file mode 100644
index 0000000000..ba94923f38
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/#defconfig#
@@ -0,0 +1,44 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nrf5340-dk"
+CONFIG_ARCH_BOARD_NRF5340_DK=y
+CONFIG_ARCH_CHIP="nrf53"
+CONFIG_ARCH_CHIP_NRF5340=y
+CONFIG_ARCH_CHIP_NRF5340_CPUAPP=y
+CONFIG_ARCH_CHIP_NRF53=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_STDARG_H=y
+CONFIG_BOARD_LOOPSPERMSEC=5500
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_LITTLEFS=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_MM_REGIONS=2
+CONFIG_MTD=y
+CONFIG_MTD_MX25RXX=y
+CONFIG_NRF52_QSPI=y
+CONFIG_NRF53_UART0=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=524288
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=26
+CONFIG_START_MONTH=3
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig
new file mode 100644
index 0000000000..5ff9c59011
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/configs/qspi_cpuapp/defconfig
@@ -0,0 +1,50 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="nrf5340-dk"
+CONFIG_ARCH_BOARD_NRF5340_DK=y
+CONFIG_ARCH_CHIP="nrf53"
+CONFIG_ARCH_CHIP_NRF5340=y
+CONFIG_ARCH_CHIP_NRF5340_CPUAPP=y
+CONFIG_ARCH_CHIP_NRF53=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_STDARG_H=y
+CONFIG_BOARD_LOOPSPERMSEC=5500
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_LITTLEFS=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_MM_REGIONS=2
+CONFIG_MTD=y
+CONFIG_MTD_MX25RXX=y
+CONFIG_MX25RXX_QSPI_FREQUENCY=98000000
+CONFIG_MX25RXX_QSPI_READ_FREQUENCY=98000000
+CONFIG_NRF53_QSPI=y
+CONFIG_NRF53_QSPI_RXDELAY=1
+CONFIG_NRF53_UART0=y
+CONFIG_NRF53_USE_HFCLK192M=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=524288
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=26
+CONFIG_START_MONTH=3
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/arm/nrf53/nrf5340-dk/include/board.h b/boards/arm/nrf53/nrf5340-dk/include/board.h
index 5ee9b31916..e535d03f0a 100644
--- a/boards/arm/nrf53/nrf5340-dk/include/board.h
+++ b/boards/arm/nrf53/nrf5340-dk/include/board.h
@@ -155,4 +155,28 @@
 #define NRF53_ADC_CH2_PIN (GPIO_MCUSEL_APP | GPIO_INPUT | GPIO_PORT0 | GPIO_PIN(6))
 #define NRF53_ADC_CH3_PIN (GPIO_MCUSEL_APP | GPIO_INPUT | GPIO_PORT0 | GPIO_PIN(7))
 
+/* QSPI Pins ****************************************************************/
+
+/* QSPI0
+ *   QSPI CS  - P0.18
+ *   QSPI SCK - P0.17
+ *   QSPI IO0 - P0.13
+ *   QSPI IO1 - P0.14
+ *   QSPI IO2 - P0.15
+ *   QSPI IO3 - P0.16
+ */
+
+#define NRF53_QSPI0_CSN_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_VALUE_ONE | GPIO_PORT0 | GPIO_PIN(18))
+#define NRF53_QSPI0_SCK_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_PORT0 | GPIO_PIN(17))
+#define NRF53_QSPI0_IO0_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_PORT0 | GPIO_PIN(13))
+#define NRF53_QSPI0_IO1_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_PORT0 | GPIO_PIN(14))
+#define NRF53_QSPI0_IO2_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_PORT0 | GPIO_PIN(15))
+#define NRF53_QSPI0_IO3_PIN (GPIO_MCUSEL_PERIP | GPIO_OUTPUT | \
+                             GPIO_PORT0 | GPIO_PIN(16))
+
 #endif /* __BOARDS_ARM_NRF53_NRF5340_DK_INCLUDE_BOARD_H */
diff --git a/boards/arm/nrf53/nrf5340-dk/src/Make.defs b/boards/arm/nrf53/nrf5340-dk/src/Make.defs
index d28956f307..3ce6ef9935 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/Make.defs
+++ b/boards/arm/nrf53/nrf5340-dk/src/Make.defs
@@ -56,6 +56,10 @@ ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
 CSRCS += nrf53_composite.c
 endif
 
+ifeq ($(CONFIG_NRF53_QSPI),y)
+CSRCS += nrf53_mx25.c
+endif
+
 DEPPATH += --dep-path board
 VPATH += :board
-CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
\ No newline at end of file
+CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h b/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
index 4b0b0ecef7..0b52d1d2a2 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf5340-dk.h
@@ -118,5 +118,17 @@ int nrf53_pwm_setup(void);
 int nrf53_adc_setup(void);
 #endif
 
+/****************************************************************************
+ * Name: nrf53_mx25_initialize
+ *
+ * Description:
+ *   Initialize the MX25RXX QSPI memeory
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NRF53_QSPI
+int nrf53_mx25_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_NRF53_NRF5340_DK_SRC_NRF5340_DK_H */
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c b/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
index d9698045a2..c59768f9f8 100644
--- a/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf53_bringup.c
@@ -285,6 +285,16 @@ int nrf53_bringup(void)
   usbdev_rndis_initialize(mac);
 #endif
 
+#ifdef CONFIG_NRF53_QSPI
+  /* Initialize the MX25 QSPU memory */
+
+  ret = nrf53_mx25_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: nrf53_mx25_initialize() failed: %d\n", ret);
+    }
+#endif
+
   /* Initialize BLE */
 
 #ifdef CONFIG_NRF53_APPCORE
diff --git a/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c b/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
new file mode 100644
index 0000000000..6b5fb81570
--- /dev/null
+++ b/boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * boards/arm/nrf53/nrf5340-dk/src/nrf53_mx25.c
+ *
+ * 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 <debug.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mtd/mtd.h>
+#include <nuttx/spi/qspi.h>
+
+#include "nrf53_qspi.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nrf53_mx25_initialize
+ *
+ * Description:
+ *   Initialize the MX25RXX QSPI memeory
+ *
+ ****************************************************************************/
+
+int nrf53_mx25_initialize(void)
+{
+  struct qspi_dev_s *qspi_dev;
+  struct mtd_dev_s  *mtd_dev;
+  char               blockdev[32];
+  int                ret = -1;
+
+  /* Create an instance of the NRF53 QSPI device driver */
+
+  qspi_dev = nrf53_qspi_initialize(0);
+  if (!qspi_dev)
+    {
+      _err("nrf53_qspi_initialize() failed\n");
+      return -1;
+    }
+
+  _info("nrf53_qspi_initialize() successful\n");
+
+  /* Use the QSPI device instance to initialize the MX25 device */
+
+  mtd_dev = mx25rxx_initialize(qspi_dev, true);
+  if (!mtd_dev)
+    {
+      _err("mx25rxx_initialize() failed\n");
+      return -1;
+    }
+
+  /* Configure the device with no partition support */
+
+  snprintf(blockdev, sizeof(blockdev), "/dev/mtdqspi%d", 0);
+
+  ret = register_mtddriver(blockdev, mtd_dev, 0755, NULL);
+  if (ret != OK)
+    {
+      _err("register_mtddriver() failed: %d\n", ret);
+      return -1;
+    }
+
+  _info("register_mtddriver() successful\n");
+
+#ifdef CONFIG_FS_LITTLEFS
+  ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0, NULL);
+  if (ret < 0)
+    {
+      ret = nx_mount(blockdev, "/mnt/qspi", "littlefs", 0,
+                     "forceformat");
+      if (ret < 0)
+        {
+          _err("nx_mount() failed: %d\n", ret);
+        }
+      else
+        {
+          _info("nx_mount() successful\n");
+        }
+    }
+#endif
+
+  return ret;
+}