diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 66316c16312..01191caa829 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -88,6 +88,9 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact if (NRF_SPIM_IS_320MHZ_SPIM(reg) && !(dev_data->ctx.config->operation & SPI_HOLD_ON_CS)) { nrfy_spim_disable(reg); } + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_put(dev); + } } static inline uint32_t get_nrf_spim_frequency(uint32_t frequency) @@ -141,56 +144,15 @@ static inline nrf_spim_bit_order_t get_nrf_spim_bit_order(uint16_t operation) } } -static int spim_init(const struct device *dev) -{ - struct spi_nrfx_data *dev_data = dev->data; - const struct spi_nrfx_config *dev_config = dev->config; - nrfx_spim_config_t config; - struct spi_context *ctx = &dev_data->ctx; - const struct spi_config *spi_cfg = ctx->config; - uint32_t max_freq = dev_config->max_freq; - nrfx_err_t result = NRFX_SUCCESS; - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) - /* On nRF5340, the 32 Mbps speed is supported by the application core - * when it is running at 128 MHz (see the Timing specifications section - * in the nRF5340 PS). - */ - if (max_freq > 16000000 && - nrf_clock_hfclk_div_get(NRF_CLOCK) != NRF_CLOCK_HFCLK_DIV_1) { - max_freq = 16000000; - } -#endif - - config = dev_config->def_config; - - /* Limit the frequency to that supported by the SPIM instance. */ - config.frequency = get_nrf_spim_frequency(MIN(spi_cfg->frequency, - max_freq)); - config.mode = get_nrf_spim_mode(spi_cfg->operation); - config.bit_order = get_nrf_spim_bit_order(spi_cfg->operation); - - if (dev_data->initialized) { - nrfx_spim_uninit(&dev_config->spim); - dev_data->initialized = false; - } - - result = nrfx_spim_init(&dev_config->spim, &config, - event_handler, (void *)dev); - if (result != NRFX_SUCCESS) { - LOG_ERR("Failed to initialize nrfx driver: %08x", result); - return -EIO; - } - return 0; -} - static int configure(const struct device *dev, const struct spi_config *spi_cfg) { struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; struct spi_context *ctx = &dev_data->ctx; - int ret; + uint32_t max_freq = dev_config->max_freq; + nrfx_spim_config_t config; + nrfx_err_t result; if (dev_data->initialized && spi_context_configured(ctx, spi_cfg)) { /* Already configured. No need to do it again. */ @@ -228,22 +190,44 @@ static int configure(const struct device *dev, return -EINVAL; } +#if defined(CONFIG_SOC_NRF5340_CPUAPP) + /* On nRF5340, the 32 Mbps speed is supported by the application core + * when it is running at 128 MHz (see the Timing specifications section + * in the nRF5340 PS). + */ + if (max_freq > 16000000 && + nrf_clock_hfclk_div_get(NRF_CLOCK) != NRF_CLOCK_HFCLK_DIV_1) { + max_freq = 16000000; + } +#endif + + config = dev_config->def_config; + + /* Limit the frequency to that supported by the SPIM instance. */ + config.frequency = get_nrf_spim_frequency(MIN(spi_cfg->frequency, + max_freq)); + config.mode = get_nrf_spim_mode(spi_cfg->operation); + config.bit_order = get_nrf_spim_bit_order(spi_cfg->operation); + nrfy_gpio_pin_write(nrfy_spim_sck_pin_get(dev_config->spim.p_reg), spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); - ctx->config = spi_cfg; -#ifdef CONFIG_PM_DEVICE_RUNTIME - ret = pm_device_runtime_get(dev); -#else - ret = spim_init(dev); -#endif - if (ret < 0) { + if (dev_data->initialized) { + nrfx_spim_uninit(&dev_config->spim); + dev_data->initialized = false; + } - return ret; + result = nrfx_spim_init(&dev_config->spim, &config, + event_handler, (void *)dev); + if (result != NRFX_SUCCESS) { + LOG_ERR("Failed to initialize nrfx driver: %08x", result); + return -EIO; } dev_data->initialized = true; + ctx->config = spi_cfg; + return 0; } @@ -341,7 +325,6 @@ static void finish_transaction(const struct device *dev, int error) dev_data->busy = false; finalize_spi_transaction(dev, true); - (void)pm_device_runtime_put(dev); } static void transfer_next_chunk(const struct device *dev) @@ -478,6 +461,9 @@ static int transceive(const struct device *dev, void *reg = dev_config->spim.p_reg; int error; + if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) { + pm_device_runtime_get(dev); + } spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); error = configure(dev, spi_cfg); @@ -589,22 +575,23 @@ static const struct spi_driver_api spi_nrfx_driver_api = { .release = spi_nrfx_release, }; -#ifdef CONFIG_PM_DEVICE static int spim_nrfx_pm_action(const struct device *dev, enum pm_device_action action) { - int ret = 0; + int ret = -ENOTSUP; struct spi_nrfx_data *dev_data = dev->data; const struct spi_nrfx_config *dev_config = dev->config; switch (action) { + case PM_DEVICE_ACTION_TURN_ON: + ret = 0; + break; case PM_DEVICE_ACTION_RESUME: ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; - } - ret = spim_init(dev); + /* nrfx_spim_init() will be called at configuration before + * the next transfer. + */ break; case PM_DEVICE_ACTION_SUSPEND: @@ -615,19 +602,14 @@ static int spim_nrfx_pm_action(const struct device *dev, ret = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; - } break; default: - ret = -ENOTSUP; + break; } return ret; } -#endif /* CONFIG_PM_DEVICE */ - static int spi_nrfx_init(const struct device *dev) { @@ -635,10 +617,7 @@ static int spi_nrfx_init(const struct device *dev) struct spi_nrfx_data *dev_data = dev->data; int err; - err = pinctrl_apply_state(dev_config->pcfg, - COND_CODE_1(CONFIG_PM_DEVICE_RUNTIME, - (PINCTRL_STATE_SLEEP), - (PINCTRL_STATE_DEFAULT))); + err = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); if (err < 0) { return err; } @@ -664,16 +643,13 @@ static int spi_nrfx_init(const struct device *dev) spi_context_unlock_unconditionally(&dev_data->ctx); -#ifdef CONFIG_PM_DEVICE_RUNTIME - pm_device_init_suspended(dev); - pm_device_runtime_enable(dev); -#endif - #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 - return anomaly_58_workaround_init(dev); -#else - return 0; + err = anomaly_58_workaround_init(dev); + if (err < 0) { + return err; + } #endif + return pm_device_driver_init(dev, spim_nrfx_pm_action); } /* * We use NODELABEL here because the nrfx API requires us to call diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/nrf52840dk_nrf52840.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/nrf52840dk_nrf52840.overlay index f0909162552..91cd073041e 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/nrf52840dk_nrf52840.overlay +++ b/tests/drivers/spi/spi_controller_peripheral/boards/nrf52840dk_nrf52840.overlay @@ -50,6 +50,7 @@ pinctrl-names = "default", "sleep"; overrun-character = <0x00>; cs-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; dut_spi_dt: test-spi-dev@0 { compatible = "vnd,spi-device"; reg = <0>; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_common.dtsi b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_common.dtsi index 8661760a5e3..d431933ab5a 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_common.dtsi +++ b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_common.dtsi @@ -60,6 +60,7 @@ pinctrl-names = "default", "sleep"; overrun-character = <0x00>; cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; dut_spi_dt: test-spi-dev@0 { compatible = "vnd,spi-device"; reg = <0>; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay index 0523426db45..4441819249f 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay +++ b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay @@ -55,6 +55,7 @@ overrun-character = <0x00>; memory-regions = <&dma_fast_region>; cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; dut_spi_dt: test-spi-dev@0 { compatible = "vnd,spi-device"; reg = <0>; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index 6ba01f86352..0188a2c4e24 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -54,10 +54,11 @@ pinctrl-names = "default", "sleep"; overrun-character = <0x00>; cs-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; dut_spi_dt: test-spi-dev@0 { compatible = "vnd,spi-device"; reg = <0>; - spi-max-frequency = ; + spi-max-frequency = ; }; }; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf51dk_nrf51822.overlay b/tests/drivers/spi/spi_loopback/boards/nrf51dk_nrf51822.overlay index 812f643f3e8..06a0d63816a 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf51dk_nrf51822.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf51dk_nrf51822.overlay @@ -7,6 +7,7 @@ &spi1 { overrun-character = <0x00>; cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf52840dk_nrf52840.overlay b/tests/drivers/spi/spi_loopback/boards/nrf52840dk_nrf52840.overlay index 7f511d0753d..7de4d8d6322 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf52840dk_nrf52840.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf52840dk_nrf52840.overlay @@ -8,6 +8,7 @@ overrun-character = <0x00>; rx-delay = <1>; cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf52dk_nrf52832.overlay b/tests/drivers/spi/spi_loopback/boards/nrf52dk_nrf52832.overlay index 812f643f3e8..06a0d63816a 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf52dk_nrf52832.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf52dk_nrf52832.overlay @@ -7,6 +7,7 @@ &spi1 { overrun-character = <0x00>; cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index 89e5fbad08a..6743e1d0933 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -30,6 +30,7 @@ pinctrl-names = "default", "sleep"; overrun-character = <0x00>; memory-regions = <&cpuapp_dma_region>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay index d6c3c972afd..2857c48f6fb 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay @@ -30,6 +30,7 @@ pinctrl-names = "default", "sleep"; overrun-character = <0x00>; memory-regions = <&dma_fast_region>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/tests/drivers/spi/spi_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index f2e84b72f9b..8dcf6fd190d 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -29,6 +29,7 @@ pinctrl-1 = <&spi00_sleep>; pinctrl-names = "default", "sleep"; overrun-character = <0x00>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf9160dk_nrf9160.overlay b/tests/drivers/spi/spi_loopback/boards/nrf9160dk_nrf9160.overlay index a07ed5fbf5d..bcd2472166a 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf9160dk_nrf9160.overlay +++ b/tests/drivers/spi/spi_loopback/boards/nrf9160dk_nrf9160.overlay @@ -7,6 +7,7 @@ &spi3 { overrun-character = <0x00>; cs-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + zephyr,pm-device-runtime-auto; slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>;