diff --git a/drivers/mspi/mspi_nrfe.c b/drivers/mspi/mspi_nrfe.c index 9e530b00df50..295e61b3b5d6 100644 --- a/drivers/mspi/mspi_nrfe.c +++ b/drivers/mspi/mspi_nrfe.c @@ -83,6 +83,9 @@ static const struct mspi_nrfe_config dev_config = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; +static nrfe_mspi_pinctrl_soc_pin_t mspi_pin_config; +static nrfe_mspi_xfer_config_t mspi_xfer_config; + static void ipc_recv_clbk(const void *data, size_t len); static void ep_bound(void *priv) @@ -130,22 +133,6 @@ static void ipc_recv_clbk(const void *data, size_t len) k_sem_give(&ipc_sem_cfg); #else atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_CONFIG_PINS); -#endif - break; - } - case NRFE_MSPI_CONFIG_CTRL: { -#if defined(CONFIG_MULTITHREADING) - k_sem_give(&ipc_sem_cfg); -#else - atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_CONFIG_CTRL); -#endif - break; - } - case NRFE_MSPI_CONFIG_DEV: { -#if defined(CONFIG_MULTITHREADING) - k_sem_give(&ipc_sem_cfg); -#else - atomic_set_bit(&ipc_atomic_sem, NRFE_MSPI_CONFIG_DEV); #endif break; } @@ -167,7 +154,7 @@ static void ipc_recv_clbk(const void *data, size_t len) } case NRFE_MSPI_TXRX: { if (len > 0) { - ipc_received = len - 1; + ipc_received = len - sizeof(nrfe_mspi_opcode_t); ipc_receive_buffer = (uint8_t *)&response->data; } #if defined(CONFIG_MULTITHREADING) @@ -196,7 +183,7 @@ static void ipc_recv_clbk(const void *data, size_t len) * @return 0 on success, -ENOMEM if there is no space in the buffer, * -ETIMEDOUT if the transfer timed out. */ -static int mspi_ipc_data_send(enum nrfe_mspi_opcode opcode, const void *data, size_t len) +static int mspi_ipc_data_send(nrfe_mspi_opcode_t opcode, const void *data, size_t len) { int rc; @@ -233,15 +220,13 @@ static int mspi_ipc_data_send(enum nrfe_mspi_opcode opcode, const void *data, si * * @return 0 on success, -ETIMEDOUT if the operation timed out. */ -static int nrfe_mspi_wait_for_response(enum nrfe_mspi_opcode opcode, uint32_t timeout) +static int nrfe_mspi_wait_for_response(nrfe_mspi_opcode_t opcode, uint32_t timeout) { #if defined(CONFIG_MULTITHREADING) int ret = 0; switch (opcode) { case NRFE_MSPI_CONFIG_PINS: - case NRFE_MSPI_CONFIG_CTRL: - case NRFE_MSPI_CONFIG_DEV: case NRFE_MSPI_CONFIG_XFER: { ret = k_sem_take(&ipc_sem_cfg, K_MSEC(timeout)); break; @@ -280,28 +265,6 @@ static int nrfe_mspi_wait_for_response(enum nrfe_mspi_opcode opcode, uint32_t ti return 0; } -/** - * @brief Send a data struct to the FLPR core using the IPC service. - * - * The function sends a data structure to the FLPR core, - * inserting a byte at the beginning responsible for the opcode. - * - * @param opcode The NRFE MSPI opcode. - * @param data The data to send. - * @param len The length of the data to send. - * - * @return 0 on success, negative errno code on failure. - */ -static int send_with_opcode(enum nrfe_mspi_opcode opcode, const void *data, size_t len) -{ - uint8_t buffer[len + 1]; - - buffer[0] = (uint8_t)opcode; - memcpy(&buffer[1], data, len); - - return mspi_ipc_data_send(opcode, buffer, sizeof(buffer)); -} - /** * @brief Send a configuration struct to the FLPR core using the IPC service. * @@ -311,11 +274,11 @@ static int send_with_opcode(enum nrfe_mspi_opcode opcode, const void *data, size * * @return 0 on success, negative errno code on failure. */ -static int send_config(enum nrfe_mspi_opcode opcode, const void *config, size_t len) +static int send_config(nrfe_mspi_opcode_t opcode, const void *config, size_t len) { int rc; + rc = mspi_ipc_data_send(opcode, config, len); - rc = send_with_opcode(opcode, config, len); if (rc < 0) { LOG_ERR("Configuration send failed: %d", rc); return rc; @@ -342,28 +305,25 @@ static int send_config(enum nrfe_mspi_opcode opcode, const void *config, size_t */ static int api_config(const struct mspi_dt_spec *spec) { - int ret; - const struct mspi_cfg *config = &spec->config; const struct mspi_nrfe_config *drv_cfg = spec->bus->config; - if (config->op_mode != MSPI_OP_MODE_CONTROLLER) { - LOG_ERR("Only MSPI controller mode is supported."); + if (spec->config.op_mode != MSPI_OP_MODE_CONTROLLER) { + LOG_ERR("%u, only support MSPI controller mode.", __LINE__); return -ENOTSUP; } - if (config->dqs_support) { - LOG_ERR("DQS mode is not supported."); + if (spec->config.dqs_support) { + LOG_ERR("%u, only support non-DQS mode.", __LINE__); return -ENOTSUP; } - if (config->max_freq > drv_cfg->mspicfg.max_freq) { - LOG_ERR("max_freq is too large."); + if (spec->config.max_freq > drv_cfg->mspicfg.max_freq) { + LOG_ERR("%u, max_freq too large.", __LINE__); return -ENOTSUP; } /* Create pinout configuration */ uint8_t state_id; - nrfe_mspi_pinctrl_soc_pin_t pins_cfg; for (state_id = 0; state_id < drv_cfg->pcfg->state_cnt; state_id++) { if (drv_cfg->pcfg->states[state_id].id == PINCTRL_STATE_DEFAULT) { @@ -382,17 +342,14 @@ static int api_config(const struct mspi_dt_spec *spec) } for (uint8_t i = 0; i < drv_cfg->pcfg->states[state_id].pin_cnt; i++) { - pins_cfg.pin[i] = drv_cfg->pcfg->states[state_id].pins[i]; + mspi_pin_config.pin[i] = drv_cfg->pcfg->states[state_id].pins[i]; } + mspi_pin_config.opcode = NRFE_MSPI_CONFIG_PINS; - /* Send pinout configuration to FLPR */ - ret = send_config(NRFE_MSPI_CONFIG_PINS, (const void *)pins_cfg.pin, sizeof(pins_cfg)); - if (ret < 0) { - return ret; - } + memset(mspi_xfer_config.ce_polarities, NRFE_MSPI_POL_UNDEFINED, NRFE_MSPI_CE_PINS_MAX*sizeof(nrfe_mspi_polarity_t)); - /* Send controller configuration to FLPR */ - return send_config(NRFE_MSPI_CONFIG_CTRL, (const void *)config, sizeof(struct mspi_cfg)); + /* Send pinout configuration to FLPR */ + return send_config(NRFE_MSPI_CONFIG_PINS, (const void *)&mspi_pin_config, sizeof(nrfe_mspi_pinctrl_soc_pin_t)); } static int check_io_mode(enum mspi_io_mode io_mode) @@ -471,10 +428,16 @@ static int api_dev_config(const struct device *dev, const struct mspi_dev_id *de } } + mspi_xfer_config.ce_polarities[cfg->ce_num] = (cfg->ce_polarity == MSPI_CE_ACTIVE_LOW) ? NRFE_MSPI_POL_ACTIVE_LOW : NRFE_MSPI_POL_ACTIVE_HIGH; + mspi_xfer_config.ce_index = cfg->ce_num; + mspi_xfer_config.io_mode = cfg->io_mode; + mspi_xfer_config.cpp = cfg->cpp; + mspi_xfer_config.freq = cfg->freq; + memcpy((void *)&drv_data->dev_cfg, (void *)cfg, sizeof(drv_data->dev_cfg)); drv_data->dev_id = *dev_id; - return send_config(NRFE_MSPI_CONFIG_DEV, (void *)cfg, sizeof(struct mspi_dev_cfg)); + return 0; } static int api_get_channel_status(const struct device *dev, uint8_t ch) @@ -497,21 +460,24 @@ static int api_get_channel_status(const struct device *dev, uint8_t ch) static int xfer_packet(struct mspi_xfer_packet *packet, uint32_t timeout) { int rc; - uint32_t struct_size = sizeof(struct mspi_xfer_packet); - uint32_t len = struct_size + packet->num_bytes + 1; - uint8_t buffer[len]; - enum nrfe_mspi_opcode opcode = (packet->dir == MSPI_RX) ? NRFE_MSPI_TXRX : NRFE_MSPI_TX; + nrfe_mspi_xfer_packet_t xfer_packet = { + .opcode = (packet->dir == MSPI_RX) ? NRFE_MSPI_TXRX : NRFE_MSPI_TX, + .command = packet->cmd, + .address = packet->address, + .num_bytes = packet->num_bytes, + }; - buffer[0] = (uint8_t)opcode; - memcpy((void *)&buffer[1], (void *)packet, struct_size); - memcpy((void *)(&buffer[1] + struct_size), (void *)packet->data_buf, packet->num_bytes); + uint32_t len = sizeof(nrfe_mspi_xfer_packet_t)+packet->num_bytes; + uint8_t buffer[len]; + memcpy((void *)buffer, (void *)&xfer_packet, sizeof(nrfe_mspi_xfer_packet_t)); + memcpy((void *)(buffer + sizeof(nrfe_mspi_xfer_packet_t)), (void *)packet->data_buf, packet->num_bytes); - rc = mspi_ipc_data_send(opcode, buffer, len); + rc = mspi_ipc_data_send(xfer_packet.opcode, buffer, len); if (rc < 0) { LOG_ERR("Packet transfer error: %d", rc); } - rc = nrfe_mspi_wait_for_response(opcode, timeout); + rc = nrfe_mspi_wait_for_response(xfer_packet.opcode, timeout); if (rc < 0) { LOG_ERR("FLPR Xfer response timeout: %d", rc); return rc; @@ -588,9 +554,16 @@ static int api_transceive(const struct device *dev, const struct mspi_dev_id *de return -EFAULT; } + mspi_xfer_config.opcode = NRFE_MSPI_CONFIG_XFER; + mspi_xfer_config.command_length = req->cmd_length; + mspi_xfer_config.address_length = req->addr_length; + mspi_xfer_config.hold_ce = req->hold_ce; + mspi_xfer_config.tx_dummy = req->tx_dummy; + mspi_xfer_config.rx_dummy = req->rx_dummy; + drv_data->xfer = *req; - rc = send_config(NRFE_MSPI_CONFIG_XFER, (void *)&drv_data->xfer, sizeof(struct mspi_xfer)); + rc = send_config(NRFE_MSPI_CONFIG_XFER, (void *)&mspi_xfer_config, sizeof(nrfe_mspi_xfer_config_t)); if (rc < 0) { LOG_ERR("Send xfer config error: %d", rc); return rc; diff --git a/include/drivers/mspi/nrfe_mspi.h b/include/drivers/mspi/nrfe_mspi.h index f404a42e1d8a..6dbb73e58bed 100644 --- a/include/drivers/mspi/nrfe_mspi.h +++ b/include/drivers/mspi/nrfe_mspi.h @@ -16,6 +16,10 @@ extern "C" { #ifdef CONFIG_SOC_NRF54L15 +#define NRFE_MSPI_CE_PINS_MAX 5 +#define NRFE_MSPI_DATA_PINS_MAX 8 +#define NRFE_MSPI_VIO_COUNT 11 + #define NRFE_MSPI_PORT_NUMBER 2 /* Physical port number */ #define NRFE_MSPI_SCK_PIN_NUMBER 1 /* Physical pins number on port 2 */ #define NRFE_MSPI_DQ0_PIN_NUMBER 2 @@ -30,48 +34,53 @@ extern "C" { #endif /** @brief eMSPI opcodes. */ -enum nrfe_mspi_opcode { +typedef enum { NRFE_MSPI_EP_BOUNDED = 0, - NRFE_MSPI_CONFIG_PINS, - NRFE_MSPI_CONFIG_CTRL, /* struct mspi_cfg */ - NRFE_MSPI_CONFIG_DEV, /* struct mspi_dev_cfg */ - NRFE_MSPI_CONFIG_XFER, /* struct mspi_xfer */ - NRFE_MSPI_TX, - NRFE_MSPI_TXRX, + NRFE_MSPI_CONFIG_PINS, /*nrfe_mspi_pinctrl_soc_pin_t*/ + NRFE_MSPI_CONFIG_XFER, /*nrfe_mspi_xfer_config_t*/ + NRFE_MSPI_TX, /*nrfe_mspi_xfer_packet_t + data buffer at the end*/ + NRFE_MSPI_TXRX, NRFE_MSPI_WRONG_OPCODE, NRFE_MSPI_ALL_OPCODES = NRFE_MSPI_WRONG_OPCODE, -}; +} nrfe_mspi_opcode_t; -typedef struct __packed { - uint8_t opcode; /* nrfe_mspi_opcode */ +typedef enum { + NRFE_MSPI_POL_UNDEFINED = 0, + NRFE_MSPI_POL_ACTIVE_LOW, + NRFE_MSPI_POL_ACTIVE_HIGH, +} nrfe_mspi_polarity_t; + +typedef struct { + nrfe_mspi_opcode_t opcode; /* nrfe_mspi_opcode */ pinctrl_soc_pin_t pin[NRFE_MSPI_PINS_MAX]; } nrfe_mspi_pinctrl_soc_pin_t; +typedef struct { + nrfe_mspi_opcode_t opcode; /* nrfe_mspi_opcode */ + uint8_t command_length; + uint8_t address_length; + uint8_t ce_index; ///< CE vio index in the same order as it arrived in NRFE_MSPI_CONFIG_PINS IPC message. + enum mspi_io_mode io_mode; + enum mspi_cpp_mode cpp; + bool hold_ce; + nrfe_mspi_polarity_t ce_polarities[NRFE_MSPI_CE_PINS_MAX]; + uint16_t tx_dummy; + uint16_t rx_dummy; + uint32_t freq; +} nrfe_mspi_xfer_config_t; + +typedef struct { + nrfe_mspi_opcode_t opcode; /* nrfe_mspi_opcode */ + uint32_t command; + uint32_t address; + uint32_t num_bytes; +} nrfe_mspi_xfer_packet_t; + typedef struct __packed { uint8_t opcode; /* nrfe_mspi_opcode */ uint8_t data; } nrfe_mspi_flpr_response_t; -typedef struct __packed { - uint8_t opcode; - struct mspi_cfg cfg; -} nrfe_mspi_cfg_t; - -typedef struct __packed { - uint8_t opcode; - struct mspi_dev_cfg cfg; -} nrfe_mspi_dev_cfg_t; - -typedef struct __packed { - uint8_t opcode; - struct mspi_xfer xfer; -} nrfe_mspi_xfer_t; - -typedef struct __packed { - uint8_t opcode; - struct mspi_xfer_packet packet; -} nrfe_mspi_xfer_packet_t; - #ifdef __cplusplus } #endif