Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrf fromtree] Upstream fixes for NCS 2.6.0 #1508

Merged
merged 12 commits into from
Feb 19, 2024
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
9 changes: 6 additions & 3 deletions drivers/serial/uart_async_to_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,15 @@ static void on_rx_buf_req(const struct device *dev,
static void on_rx_dis(const struct device *dev, struct uart_async_to_irq_data *data)
{
if (data->flags & A2I_RX_ENABLE) {
data->rx.pending_buf_req = 0;
int err;

int err = try_rx_enable(dev, data);
err = try_rx_enable(dev, data);
if (err == 0) {
data->rx.pending_buf_req = 0;
}

LOG_INST_DBG(get_config(dev)->log, "Reenabling RX from RX_DISABLED (err:%d)", err);
__ASSERT_NO_MSG(err >= 0);
__ASSERT((err >= 0) || (err == -EBUSY), "err: %d", err);
return;
}

Expand Down
8 changes: 5 additions & 3 deletions drivers/serial/uart_nrfx_uarte.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,9 +1043,11 @@ static void rx_timeout(struct k_timer *timer)
(data->async->rx_timeout_left
< data->async->rx_timeout_slab)) {
/* rx_timeout us elapsed since last receiving */
notify_uart_rx_rdy(dev, len);
data->async->rx_offset += len;
data->async->rx_total_user_byte_cnt += len;
if (data->async->rx_buf != NULL) {
notify_uart_rx_rdy(dev, len);
data->async->rx_offset += len;
data->async->rx_total_user_byte_cnt += len;
}
} else {
data->async->rx_timeout_left -=
data->async->rx_timeout_slab;
Expand Down
23 changes: 15 additions & 8 deletions drivers/spi/Kconfig.nrfx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ config SPI_NRFX_SPIS

config SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
depends on SOC_NRF52832
select NRFX_PPI
bool "Allow enabling the SPIM driver despite PAN 58"
help
Allow enabling the nRF SPI Master with EasyDMA, despite
Expand All @@ -74,14 +75,20 @@ config SPI_NRFX_RAM_BUFFER_SIZE
default 8
depends on SPI_NRFX_SPIM
help
SPIM peripherals cannot transmit data directly from flash. Therefore,
a buffer in RAM needs to be provided for each instance of SPI driver
using SPIM peripheral, so that the driver can copy there a chunk of
data from flash and transmit it.
The size is specified in bytes. A size of 0 means that this feature
should be disabled, and the application must then take care of not
supplying buffers located in flash to the driver, otherwise such
transfers will fail.
Because of using EasyDMA, SPIM peripherals cannot use transmit and
receive buffers from all memory locations. They are restricted to
buffers located in certain RAM memories only. Therefore, each SPIM
driver instance needs to use an intermediate local RAM buffer,
to transfer data in chunks not exceeding the size of that buffer,
and to copy those chunks between the local buffer and the one
specified in the transfer request if the latter is not accessible
by EasyDMA.

This option specifies the size in bytes of such local RAM buffers
for both TX and RX paths. A size of 0 means that this feature should
be disabled and the driver user must take care of not making transfer
requests with buffers not accessible by EasyDMA since such transfers
will fail.

config SPI_NRFX_WAKE_TIMEOUT_US
int "Maximum time to wait for SPI slave to wake up"
Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/spi_nrfx_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ static void finish_transaction(const struct device *dev, int error)
struct spi_nrfx_data *dev_data = dev->data;
struct spi_context *ctx = &dev_data->ctx;

spi_context_cs_control(ctx, false);

LOG_DBG("Transaction finished with status %d", error);

spi_context_complete(ctx, dev, error);
Expand Down Expand Up @@ -277,6 +275,8 @@ static int transceive(const struct device *dev,
/* Clean up the driver state. */
k_sem_reset(&dev_data->ctx.sync);
}

spi_context_cs_control(&dev_data->ctx, false);
}

spi_context_release(&dev_data->ctx, error);
Expand Down
67 changes: 49 additions & 18 deletions drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
#include <nrfx_ppi.h>
#endif
#include <nrfx_spim.h>
#ifdef CONFIG_SOC_NRF5340_CPUAPP
#include <hal/nrf_clock.h>
#endif
#include <nrfx_spim.h>
#include <string.h>
#include <zephyr/linker/devicetree_regions.h>

Expand All @@ -39,8 +41,9 @@ struct spi_nrfx_data {
size_t chunk_len;
bool busy;
bool initialized;
#if SPI_BUFFER_IN_RAM
uint8_t *buffer;
#ifdef SPI_BUFFER_IN_RAM
uint8_t *tx_buffer;
uint8_t *rx_buffer;
#endif
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
bool anomaly_58_workaround_active;
Expand Down Expand Up @@ -69,9 +72,9 @@ static inline uint32_t get_nrf_spim_frequency(uint32_t frequency)
{
/* Get the highest supported frequency not exceeding the requested one.
*/
if (frequency >= MHZ(32) && NRF_SPIM_HAS_32_MHZ_FREQ) {
if (frequency >= MHZ(32) && (NRF_SPIM_HAS_32_MHZ_FREQ || NRF_SPIM_HAS_PRESCALER)) {
return MHZ(32);
} else if (frequency >= MHZ(16) && NRF_SPIM_HAS_16_MHZ_FREQ) {
} else if (frequency >= MHZ(16) && (NRF_SPIM_HAS_16_MHZ_FREQ || NRF_SPIM_HAS_PRESCALER)) {
return MHZ(16);
} else if (frequency >= MHZ(8)) {
return MHZ(8);
Expand Down Expand Up @@ -291,8 +294,6 @@ static void finish_transaction(const struct device *dev, int error)
struct spi_nrfx_data *dev_data = dev->data;
struct spi_context *ctx = &dev_data->ctx;

spi_context_cs_control(ctx, false);

LOG_DBG("Transaction finished with status %d", error);

spi_context_complete(ctx, dev, error);
Expand All @@ -312,25 +313,40 @@ static void transfer_next_chunk(const struct device *dev)
nrfx_spim_xfer_desc_t xfer;
nrfx_err_t result;
const uint8_t *tx_buf = ctx->tx_buf;
#if (CONFIG_SPI_NRFX_RAM_BUFFER_SIZE > 0)
if (spi_context_tx_buf_on(ctx) && !nrfx_is_in_ram(tx_buf)) {
uint8_t *rx_buf = ctx->rx_buf;

if (chunk_len > dev_config->max_chunk_len) {
chunk_len = dev_config->max_chunk_len;
}

#ifdef SPI_BUFFER_IN_RAM
if (spi_context_tx_buf_on(ctx) &&
!nrf_dma_accessible_check(&dev_config->spim.p_reg, tx_buf)) {

if (chunk_len > CONFIG_SPI_NRFX_RAM_BUFFER_SIZE) {
chunk_len = CONFIG_SPI_NRFX_RAM_BUFFER_SIZE;
}

memcpy(dev_data->buffer, tx_buf, chunk_len);
tx_buf = dev_data->buffer;
memcpy(dev_data->tx_buffer, tx_buf, chunk_len);
tx_buf = dev_data->tx_buffer;
}
#endif
if (chunk_len > dev_config->max_chunk_len) {
chunk_len = dev_config->max_chunk_len;

if (spi_context_rx_buf_on(ctx) &&
!nrf_dma_accessible_check(&dev_config->spim.p_reg, rx_buf)) {

if (chunk_len > CONFIG_SPI_NRFX_RAM_BUFFER_SIZE) {
chunk_len = CONFIG_SPI_NRFX_RAM_BUFFER_SIZE;
}

rx_buf = dev_data->rx_buffer;
}
#endif

dev_data->chunk_len = chunk_len;

xfer.p_tx_buffer = tx_buf;
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
xfer.p_rx_buffer = ctx->rx_buf;
xfer.p_rx_buffer = rx_buf;
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
Expand Down Expand Up @@ -374,6 +390,15 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
anomaly_58_workaround_clear(dev_data);
#endif
#ifdef SPI_BUFFER_IN_RAM
if (spi_context_rx_buf_on(&dev_data->ctx) &&
p_event->xfer_desc.p_rx_buffer != NULL &&
p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) {
(void)memcpy(dev_data->ctx.rx_buf,
dev_data->rx_buffer,
dev_data->chunk_len);
}
#endif
spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len);
spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len);
Expand Down Expand Up @@ -443,6 +468,8 @@ static int transceive(const struct device *dev,
anomaly_58_workaround_clear(dev_data);
#endif
}

spi_context_cs_control(&dev_data->ctx, false);
}

spi_context_release(&dev_data->ctx, error);
Expand Down Expand Up @@ -602,15 +629,19 @@ static int spi_nrfx_init(const struct device *dev)
nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \
} \
IF_ENABLED(SPI_BUFFER_IN_RAM, \
(static uint8_t spim_##idx##_buffer \
(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, \
(.buffer = spim_##idx##_buffer,)) \
(.tx_buffer = spim_##idx##_tx_buffer, \
.rx_buffer = spim_##idx##_rx_buffer,)) \
.dev = DEVICE_DT_GET(SPIM(idx)), \
.busy = false, \
}; \
Expand Down Expand Up @@ -639,7 +670,7 @@ static int spi_nrfx_init(const struct device *dev)
WAKE_PIN_NOT_USED), \
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
}; \
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIM(idx), wake_gpios) || \
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); \
Expand Down
22 changes: 21 additions & 1 deletion soc/arm/nordic_nrf/nrf53/Kconfig.soc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ config SOC_NRF5340_CPUAPP
select HAS_POWEROFF
select SOC_COMPATIBLE_NRF5340_CPUAPP
imply SOC_NRF53_RTC_PRETICK
imply SOC_NRF53_ANOMALY_168_WORKAROUND

config SOC_NRF5340_CPUNET
bool
select ARM_ON_EXIT_CPU_IDLE
select SOC_COMPATIBLE_NRF5340_CPUNET
imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED
imply SOC_NRF53_RTC_PRETICK if !WDT_NRFX
imply SOC_NRF53_ANOMALY_168_WORKAROUND

choice
prompt "nRF53x MCU Selection"
Expand Down Expand Up @@ -79,6 +80,25 @@ config SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET

endif

config SOC_NRF53_ANOMALY_168_WORKAROUND
bool "Workaround for nRF5340 anomaly 168"
select ARM_ON_EXIT_CPU_IDLE
help
Indicates that the workaround for the anomaly 168 that affects
the nRF5340 SoC should be applied.
The workaround involves execution of 8 NOP instructions when the CPU
exist its idle state (when the WFI/WFE instruction returns) and it is
enabled by default for both the application and network core.

config SOC_NRF53_ANOMALY_168_WORKAROUND_FOR_EXECUTION_FROM_RAM
bool "Extend the workaround to execution at 128 MHz from RAM"
depends on SOC_NRF53_ANOMALY_168_WORKAROUND && SOC_NRF5340_CPUAPP
help
Indicates that the anomaly 168 workaround is to be extended to cover
also a specific case when the WFI/WFE instruction is executed at 128
MHz from RAM. Then, 26 instead of 8 NOP instructions needs to be
executed after WFI/WFE. This extension is not enabled by default.

if SOC_NRF5340_CPUAPP

config SOC_DCDC_NRF53X_APP
Expand Down
10 changes: 8 additions & 2 deletions soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@

#if defined(_ASMLANGUAGE)

#if defined(CONFIG_SOC_NRF53_ANOMALY_168_WORKAROUND_FOR_EXECUTION_FROM_RAM)
#define SOC_ON_EXIT_CPU_IDLE \
.rept 26; \
nop; \
.endr
#elif defined(CONFIG_SOC_NRF53_ANOMALY_168_WORKAROUND)
#define SOC_ON_EXIT_CPU_IDLE \
.rept 8; \
nop; \
nop; \
nop;
.endr
#endif

#endif /* _ASMLANGUAGE */
Loading