Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/clock_control/clock_control_nrf2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ int nrf_clock_control_request_sync(const struct device *dev,

err = k_sem_take(&req.sem, timeout);
if (err < 0) {
nrf_clock_control_cancel_or_release(dev, spec, &req.cli);
return err;
}

Expand Down
101 changes: 98 additions & 3 deletions drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <zephyr/cache.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/mem_mgmt/mem_attr.h>
#include <soc.h>
Expand Down Expand Up @@ -42,6 +43,16 @@
#define SPI_BUFFER_IN_RAM 1
#endif

#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL) && \
(defined(CONFIG_HAS_HW_NRF_SPIM120) || \
defined(CONFIG_HAS_HW_NRF_SPIM121))
#define SPIM_REQUESTS_CLOCK(idx) UTIL_OR(IS_EQ(idx, 120), \
IS_EQ(idx, 121))
#define USE_CLOCK_REQUESTS 1
#else

Check notice on line 52 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:52 -#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL) && \ - (defined(CONFIG_HAS_HW_NRF_SPIM120) || \ - defined(CONFIG_HAS_HW_NRF_SPIM121)) -#define SPIM_REQUESTS_CLOCK(idx) UTIL_OR(IS_EQ(idx, 120), \ - IS_EQ(idx, 121)) -#define USE_CLOCK_REQUESTS 1 +#if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL) && \ + (defined(CONFIG_HAS_HW_NRF_SPIM120) || defined(CONFIG_HAS_HW_NRF_SPIM121)) +#define SPIM_REQUESTS_CLOCK(idx) UTIL_OR(IS_EQ(idx, 120), IS_EQ(idx, 121)) +#define USE_CLOCK_REQUESTS 1
#define SPIM_REQUESTS_CLOCK(idx) 0
#endif

struct spi_nrfx_data {
struct spi_context ctx;
const struct device *dev;
Expand All @@ -57,6 +68,9 @@
uint8_t ppi_ch;
uint8_t gpiote_ch;
#endif
#ifdef USE_CLOCK_REQUESTS
bool clock_requested;
#endif
};

struct spi_nrfx_config {
Expand All @@ -74,10 +88,55 @@
#ifdef CONFIG_DCACHE
uint32_t mem_attr;
#endif
#ifdef USE_CLOCK_REQUESTS
const struct device *clk_dev;
struct nrf_clock_spec clk_spec;
#endif
};

static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);

static inline int request_clock(const struct device *dev)
{
#ifdef USE_CLOCK_REQUESTS
struct spi_nrfx_data *dev_data = dev->data;
const struct spi_nrfx_config *dev_config = dev->config;
int error;

if (!dev_config->clk_dev) {
return 0;
}

error = nrf_clock_control_request_sync(
dev_config->clk_dev, &dev_config->clk_spec,
K_MSEC(CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE));
if (error < 0) {

Check notice on line 113 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:113 - error = nrf_clock_control_request_sync( - dev_config->clk_dev, &dev_config->clk_spec, - K_MSEC(CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE)); + error = nrf_clock_control_request_sync(dev_config->clk_dev, &dev_config->clk_spec, + K_MSEC(CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE));
LOG_ERR("Failed to request clock: %d", error);
return error;
}

dev_data->clock_requested = true;
#endif

return 0;
}

static inline void release_clock(const struct device *dev)
{
#ifdef USE_CLOCK_REQUESTS
struct spi_nrfx_data *dev_data = dev->data;
const struct spi_nrfx_config *dev_config = dev->config;

if (!dev_data->clock_requested) {
return;
}

dev_data->clock_requested = false;

nrf_clock_control_release(dev_config->clk_dev, &dev_config->clk_spec);
#endif
}

static inline void finalize_spi_transaction(const struct device *dev, bool deactivate_cs)
{
struct spi_nrfx_data *dev_data = dev->data;
Expand All @@ -92,6 +151,10 @@
nrfy_spim_disable(reg);
}

if (!IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
release_clock(dev);
}

pm_device_runtime_put_async(dev, K_NO_WAIT);
}

Expand Down Expand Up @@ -467,6 +530,11 @@
spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg);

error = configure(dev, spi_cfg);

if (error == 0 && !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
error = request_clock(dev);
}

if (error == 0) {
dev_data->busy = true;

Expand Down Expand Up @@ -518,6 +586,8 @@
} else if (error) {
finalize_spi_transaction(dev, true);
}
} else {
pm_device_runtime_put(dev);
}

spi_context_release(&dev_data->ctx, error);
Expand Down Expand Up @@ -575,7 +645,7 @@
.release = spi_nrfx_release,
};

static void spim_resume(const struct device *dev)
static int spim_resume(const struct device *dev)
{
const struct spi_nrfx_config *dev_config = dev->config;

Expand All @@ -587,6 +657,8 @@
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(dev_config->pcfg, false);
#endif

return IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME) ? request_clock(dev) : 0;
}

static void spim_suspend(const struct device *dev)
Expand All @@ -599,6 +671,10 @@
dev_data->initialized = false;
}

if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
release_clock(dev);
}

#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(dev_config->pcfg, true);
#endif
Expand All @@ -609,7 +685,11 @@
static int spim_nrfx_pm_action(const struct device *dev, enum pm_device_action action)
{
if (action == PM_DEVICE_ACTION_RESUME) {
spim_resume(dev);
int error = spim_resume(dev);

if (error < 0) {
return error;
}
} else if (IS_ENABLED(CONFIG_PM_DEVICE) && (action == PM_DEVICE_ACTION_SUSPEND)) {
spim_suspend(dev);
} else {
Expand Down Expand Up @@ -685,6 +765,14 @@
(0))), \
(0))

#define SPIM_INIT_LEVEL(idx) \
COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), (POST_KERNEL), (PRE_KERNEL_1))

#define SPIM_INIT_PRIO(idx) \
COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
(CONFIG_SPI_INIT_PRIORITY))

#define SPI_NRFX_SPIM_DEFINE(idx) \
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \
static void irq_connect##idx(void) \
Expand Down Expand Up @@ -735,6 +823,13 @@
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
IF_ENABLED(CONFIG_DCACHE, \
(.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
IF_ENABLED(USE_CLOCK_REQUESTS, \
(.clk_dev = SPIM_REQUESTS_CLOCK(idx) \
? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
: NULL, \
.clk_spec = { \
.frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \
},)) \
}; \
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
Expand All @@ -745,9 +840,9 @@
PM_DEVICE_DT_GET(SPIM(idx)), \
&spi_##idx##_data, \
&spi_##idx##z_config, \
POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
SPIM_INIT_LEVEL(idx), SPIM_INIT_PRIO(idx), \
&spi_nrfx_driver_api)

Check notice on line 845 in drivers/spi/spi_nrfx_spim.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/spi/spi_nrfx_spim.c:845 -#define SPIM_INIT_LEVEL(idx) \ - COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), (POST_KERNEL), (PRE_KERNEL_1)) - -#define SPIM_INIT_PRIO(idx) \ - COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \ - (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ - (CONFIG_SPI_INIT_PRIORITY)) - -#define SPI_NRFX_SPIM_DEFINE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \ - static void irq_connect##idx(void) \ - { \ - IRQ_CONNECT(DT_IRQN(SPIM(idx)), DT_IRQ(SPIM(idx), priority), \ - nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \ - } \ - IF_ENABLED(SPI_BUFFER_IN_RAM, \ - (static uint8_t spim_##idx##_tx_buffer \ - [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ - SPIM_MEMORY_SECTION(idx); \ - static uint8_t spim_##idx##_rx_buffer \ - [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ - SPIM_MEMORY_SECTION(idx);)) \ - static struct spi_nrfx_data spi_##idx##_data = { \ - SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx), \ - SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx) \ - IF_ENABLED(SPI_BUFFER_IN_RAM, \ - (.tx_buffer = spim_##idx##_tx_buffer, \ - .rx_buffer = spim_##idx##_rx_buffer,)) \ - .dev = DEVICE_DT_GET(SPIM(idx)), \ - .busy = false, \ - }; \ - PINCTRL_DT_DEFINE(SPIM(idx)); \ - static const struct spi_nrfx_config spi_##idx##z_config = { \ - .spim = { \ - .p_reg = (NRF_SPIM_Type *)DT_REG_ADDR(SPIM(idx)), \ - .drv_inst_idx = NRFX_SPIM##idx##_INST_IDX, \ - }, \ - .max_freq = SPIM_PROP(idx, max_frequency), \ - .def_config = { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, \ - .orc = SPIM_PROP(idx, overrun_character), \ - SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \ - }, \ - .irq_connect = irq_connect##idx, \ - .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIM(idx)), \ - .max_chunk_len = BIT_MASK(SPIM_PROP(idx, easydma_maxcnt_bits)),\ - COND_CODE_1(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58, \ - (.anomaly_58_workaround = \ - SPIM_PROP(idx, anomaly_58_workaround),), \ - ()) \ - .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \ - WAKE_PIN_NOT_USED), \ - .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ - IF_ENABLED(CONFIG_DCACHE, \ - (.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \ - IF_ENABLED(USE_CLOCK_REQUESTS, \ - (.clk_dev = SPIM_REQUESTS_CLOCK(idx) \ - ? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \ - : NULL, \ - .clk_spec = { \ - .frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \ - },)) \ - }; \ - BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ - !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ - "WAKE line must be configured as active high"); \ - PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \ - DEVICE_DT_DEFINE(SPIM(idx), \ - spi_nrfx_init, \ - PM_DEVICE_DT_GET(SPIM(idx)), \ - &spi_##idx##_data, \ - &spi_##idx##z_config, \ - SPIM_INIT_LEVEL(idx), SPIM_INIT_PRIO(idx), \ - &spi_nrfx_driver_api) +#define SPIM_INIT_LEVEL(idx) COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), (POST_KERNEL), (PRE_KERNEL_1)) + +#define SPIM_INIT_PRIO(idx) \ + COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \ + (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \ + (CONFIG_SPI_INIT_PRIORITY)) + +#define SPI_NRFX_SPIM_DEFINE(idx)
#define SPIM_MEMORY_SECTION(idx) \
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
Expand Down
2 changes: 2 additions & 0 deletions dts/common/nordic/nrf54h20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@
power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>;
easydma-maxcnt-bits = <15>;
interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>;
clocks = <&hsfll120>;
max-frequency = <DT_FREQ_M(32)>;
#address-cells = <1>;
#size-cells = <0>;
Expand All @@ -683,6 +684,7 @@
status = "disabled";
easydma-maxcnt-bits = <15>;
interrupts = <231 NRF_DEFAULT_IRQ_PRIORITY>;
clocks = <&hsfll120>;
power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>;
max-frequency = <DT_FREQ_M(32)>;
#address-cells = <1>;
Expand Down
Loading