Skip to content

Commit 7ea6937

Browse files
e-rkcarlescufi
authored andcommitted
[nrf noup] drivers: spi_dw: add custom EXMIF peripheral handling
The Synopsys Designware SPI peripheral core is wrapped in hardware that manages interrupts, power and clock. The SPI core registers are shifted by 0x500 bytes. Before the SPI core is used, the power and clock must be enabled by writing to EXMIF.TASKS_START register. Interrupts must be enabled by writing to EXMIF.INTENSET/INTENCLR registers. The SER register must be configured unconditionally during peripheral setup. Otherwise, the serial transaction does not complete. Signed-off-by: Rafał Kuźnia <[email protected]>
1 parent 52cf91a commit 7ea6937

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

drivers/spi/spi_dw.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ LOG_MODULE_REGISTER(spi_dw);
4040
#include <zephyr/drivers/pinctrl.h>
4141
#endif
4242

43+
#ifdef CONFIG_HAS_NRFX
44+
#include <nrfx.h>
45+
#endif
46+
4347
static inline bool spi_dw_is_slave(struct spi_dw_data *spi)
4448
{
4549
return (IS_ENABLED(CONFIG_SPI_SLAVE) &&
@@ -257,6 +261,7 @@ static int spi_dw_configure(const struct device *dev,
257261
/* Baud rate and Slave select, for master only */
258262
write_baudr(dev, SPI_DW_CLK_DIVIDER(info->clock_frequency,
259263
config->frequency));
264+
write_ser(dev, BIT(config->slave));
260265
}
261266

262267
if (spi_dw_is_slave(spi)) {
@@ -499,6 +504,10 @@ void spi_dw_isr(const struct device *dev)
499504
uint32_t int_status;
500505
int error;
501506

507+
#ifdef CONFIG_HAS_NRFX
508+
NRF_EXMIF->EVENTS_CORE = 0;
509+
#endif
510+
502511
int_status = read_isr(dev);
503512

504513
LOG_DBG("SPI %p int_status 0x%x - (tx: %d, rx: %d)", dev, int_status,
@@ -544,6 +553,11 @@ int spi_dw_init(const struct device *dev)
544553

545554
DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
546555

556+
#ifdef CONFIG_HAS_NRFX
557+
NRF_EXMIF->INTENSET = BIT(0);
558+
NRF_EXMIF->TASKS_START = 1;
559+
#endif
560+
547561
info->config_func();
548562

549563
/* Masking interrupt and making sure controller is disabled */
@@ -562,6 +576,11 @@ int spi_dw_init(const struct device *dev)
562576
return 0;
563577
}
564578

579+
#define REG_ADDR(inst) \
580+
COND_CODE_1(DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), nordic_nrf_exmif), \
581+
(Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(core, DT_DRV_INST(inst))), \
582+
(DEVICE_MMIO_ROM_INIT(DT_DRV_INST(inst))))
583+
565584
#define SPI_CFG_IRQS_SINGLE_ERR_LINE(inst) \
566585
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(inst, rx_avail, irq), \
567586
DT_INST_IRQ_BY_NAME(inst, rx_avail, priority), \
@@ -634,7 +653,7 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \
634653
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx) \
635654
}; \
636655
static const struct spi_dw_config spi_dw_config_##inst = { \
637-
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(inst)), \
656+
REG_ADDR(inst), \
638657
.clock_frequency = COND_CODE_1( \
639658
DT_NODE_HAS_PROP(DT_INST_PHANDLE(inst, clocks), clock_frequency), \
640659
(DT_INST_PROP_BY_PHANDLE(inst, clocks, clock_frequency)), \

0 commit comments

Comments
 (0)