@@ -26,6 +26,9 @@ struct qspi_nor_config {
2626 uint32_t size ;
2727};
2828
29+ /* Main config structure */
30+ static nrfx_qspi_config_t QSPIconfig ;
31+
2932/* Status register bits */
3033#define QSPI_SECTOR_SIZE SPI_NOR_SECTOR_SIZE
3134#define QSPI_BLOCK_SIZE SPI_NOR_BLOCK_SIZE
@@ -50,6 +53,18 @@ BUILD_ASSERT(((INST_0_QER == JESD216_DW15_QER_NONE)
5053 || (INST_0_QER == JESD216_DW15_QER_S1B6 )),
5154 "Driver only supports NONE or S1B6 for quad-enable-requirements" );
5255
56+ #if NRF52_ERRATA_122_PRESENT
57+ #include <hal/nrf_gpio.h>
58+ static int anomaly_122_init (const struct device * dev );
59+ static void anomaly_122_uninit (const struct device * dev );
60+
61+ #define ANOMALY_122_INIT (dev ) anomaly_122_init(dev)
62+ #define ANOMALY_122_UNINIT (dev ) anomaly_122_uninit(dev)
63+ #else
64+ #define ANOMALY_122_INIT (dev ) 0
65+ #define ANOMALY_122_UNINIT (dev )
66+ #endif
67+
5368#define WORD_SIZE 4
5469
5570LOG_MODULE_REGISTER (qspi_nor , CONFIG_FLASH_LOG_LEVEL );
@@ -98,6 +113,10 @@ struct qspi_nor_data {
98113 struct k_sem sem ;
99114 /* The semaphore to indicate that transfer has completed. */
100115 struct k_sem sync ;
116+ #if NRF52_ERRATA_122_PRESENT
117+ /* The semaphore to control driver init/uninit. */
118+ struct k_sem count ;
119+ #endif
101120#else /* CONFIG_MULTITHREADING */
102121 /* A flag that signals completed transfer when threads are
103122 * not enabled.
@@ -214,6 +233,9 @@ static struct qspi_nor_data qspi_nor_memory_data = {
214233 .trans = Z_SEM_INITIALIZER (qspi_nor_memory_data .trans , 1 , 1 ),
215234 .sem = Z_SEM_INITIALIZER (qspi_nor_memory_data .sem , 1 , 1 ),
216235 .sync = Z_SEM_INITIALIZER (qspi_nor_memory_data .sync , 0 , 1 ),
236+ #if NRF52_ERRATA_122_PRESENT
237+ .count = Z_SEM_INITIALIZER (qspi_nor_memory_data .count , 0 , K_SEM_MAX_LIMIT ),
238+ #endif
217239#endif /* CONFIG_MULTITHREADING */
218240};
219241
@@ -332,6 +354,73 @@ static void qspi_handler(nrfx_qspi_evt_t event, void *p_context)
332354 }
333355}
334356
357+ #if NRF52_ERRATA_122_PRESENT
358+ static bool qspi_initialized ;
359+
360+ static int anomaly_122_init (const struct device * dev )
361+ {
362+ struct qspi_nor_data * dev_data = get_dev_data (dev );
363+ nrfx_err_t res ;
364+ int ret = 0 ;
365+
366+ if (!nrf52_errata_122 ()) {
367+ return 0 ;
368+ }
369+
370+ qspi_lock (dev );
371+
372+ /* In multithreading, driver can call anomaly_122_init more than once
373+ * before calling anomaly_122_uninit. Keepping count, so QSPI is
374+ * uninitialized only at the last call (count == 0).
375+ */
376+ #ifdef CONFIG_MULTITHREADING
377+ k_sem_give (& dev_data -> count );
378+ #endif
379+
380+ if (!qspi_initialized ) {
381+ res = nrfx_qspi_init (& QSPIconfig , qspi_handler , dev_data );
382+ ret = qspi_get_zephyr_ret_code (res );
383+ qspi_initialized = (ret == 0 );
384+ }
385+
386+ qspi_unlock (dev );
387+
388+ return ret ;
389+ }
390+
391+ static void anomaly_122_uninit (const struct device * dev )
392+ {
393+ struct qspi_nor_data * dev_data = get_dev_data (dev );
394+ bool last = true;
395+
396+ if (!nrf52_errata_122 ()) {
397+ return ;
398+ }
399+
400+ qspi_lock (dev );
401+
402+ #ifdef CONFIG_MULTITHREADING
403+ /* The last thread to finish using the driver uninit the QSPI */
404+ (void ) k_sem_take (& dev_data -> count , K_NO_WAIT );
405+ last = (k_sem_count_get (& dev_data -> count ) == 0 );
406+ #endif
407+
408+ if (last ) {
409+ while (nrfx_qspi_mem_busy_check () != NRFX_SUCCESS ) {
410+ k_msleep (50 );
411+ }
412+
413+ nrf_gpio_cfg_output (QSPI_PROP_AT (csn_pins , 0 ));
414+ nrf_gpio_pin_set (QSPI_PROP_AT (csn_pins , 0 ));
415+
416+ nrfx_qspi_uninit ();
417+ qspi_initialized = false;
418+ }
419+
420+ qspi_unlock (dev );
421+ }
422+ #endif /* NRF52_ERRATA_122_PRESENT */
423+
335424
336425/* QSPI send custom command.
337426 *
@@ -442,6 +531,10 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size)
442531 int rv = 0 ;
443532 const struct qspi_nor_config * params = dev -> config ;
444533
534+ rv = ANOMALY_122_INIT (dev );
535+ if (rv != 0 ) {
536+ goto out ;
537+ }
445538 qspi_trans_lock (dev );
446539 rv = qspi_nor_write_protection_set (dev , false);
447540 qspi_lock (dev );
@@ -488,6 +581,8 @@ static int qspi_erase(const struct device *dev, uint32_t addr, uint32_t size)
488581 rv = rv2 ;
489582 }
490583
584+ out :
585+ ANOMALY_122_UNINIT (dev );
491586 return rv ;
492587}
493588
@@ -555,8 +650,6 @@ static int qspi_nrfx_configure(const struct device *dev)
555650 }
556651
557652 struct qspi_nor_data * dev_data = dev -> data ;
558- /* Main config structure */
559- nrfx_qspi_config_t QSPIconfig ;
560653
561654 qspi_fill_init_struct (& QSPIconfig );
562655
@@ -633,7 +726,14 @@ static int qspi_read_jedec_id(const struct device *dev,
633726 .rx_buf = & rx_buf ,
634727 };
635728
636- return qspi_send_cmd (dev , & cmd , false);
729+ int ret = ANOMALY_122_INIT (dev );
730+
731+ if (ret == 0 ) {
732+ ret = qspi_send_cmd (dev , & cmd , false);
733+ }
734+ ANOMALY_122_UNINIT (dev );
735+
736+ return ret ;
637737}
638738
639739#if defined(CONFIG_FLASH_JESD216_API )
@@ -656,10 +756,15 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset,
656756 .io3_level = true,
657757 };
658758
659- qspi_lock (dev );
759+ int res = ANOMALY_122_INIT (dev );
660760
661- int res = nrfx_qspi_lfm_start (& cinstr_cfg );
761+ if (res != NRFX_SUCCESS ) {
762+ LOG_DBG ("ANOMALY_122_INIT: %x" , res );
763+ goto out ;
764+ }
662765
766+ qspi_lock (dev );
767+ res = nrfx_qspi_lfm_start (& cinstr_cfg );
663768 if (res != NRFX_SUCCESS ) {
664769 LOG_DBG ("lfm_start: %x" , res );
665770 goto out ;
@@ -679,6 +784,7 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset,
679784
680785out :
681786 qspi_unlock (dev );
787+ ANOMALY_122_UNINIT (dev );
682788 return qspi_get_zephyr_ret_code (res );
683789}
684790
@@ -806,14 +912,22 @@ static int qspi_nor_read(const struct device *dev, off_t addr, void *dest,
806912 return - EINVAL ;
807913 }
808914
915+ int rc = ANOMALY_122_INIT (dev );
916+
917+ if (rc != 0 ) {
918+ goto out ;
919+ }
920+
809921 qspi_lock (dev );
810922
811923 nrfx_err_t res = read_non_aligned (dev , addr , dest , size );
812924
813925 qspi_unlock (dev );
814926
815- int rc = qspi_get_zephyr_ret_code (res );
927+ rc = qspi_get_zephyr_ret_code (res );
816928
929+ out :
930+ ANOMALY_122_UNINIT (dev );
817931 return rc ;
818932}
819933
@@ -908,6 +1022,12 @@ static int qspi_nor_write(const struct device *dev, off_t addr,
9081022
9091023 nrfx_err_t res = NRFX_SUCCESS ;
9101024
1025+ int rc = ANOMALY_122_INIT (dev );
1026+
1027+ if (rc != 0 ) {
1028+ goto out ;
1029+ }
1030+
9111031 qspi_trans_lock (dev );
9121032 res = qspi_nor_write_protection_set (dev , false);
9131033 qspi_lock (dev );
@@ -930,7 +1050,10 @@ static int qspi_nor_write(const struct device *dev, off_t addr,
9301050 res = res2 ;
9311051 }
9321052
933- return qspi_get_zephyr_ret_code (res );
1053+ rc = qspi_get_zephyr_ret_code (res );
1054+ out :
1055+ ANOMALY_122_UNINIT (dev );
1056+ return rc ;
9341057}
9351058
9361059static int qspi_nor_erase (const struct device * dev , off_t addr , size_t size )
@@ -983,6 +1106,8 @@ static int qspi_nor_configure(const struct device *dev)
9831106 return ret ;
9841107 }
9851108
1109+ ANOMALY_122_UNINIT (dev );
1110+
9861111 /* now the spi bus is configured, we can verify the flash id */
9871112 if (qspi_nor_read_id (dev , params ) != 0 ) {
9881113 return - ENODEV ;
0 commit comments