Skip to content

Commit

Permalink
drivers: firmware: scmi: add nxp specific processing
Browse files Browse the repository at this point in the history
An option is added to allow vendor specific processing at
scmi_shmem_write_message() and scmi_shmem_read_message().
Additionally code has been added specific to NXP which has
some extended validation features.

Signed-off-by: Andre Heinemans <andre.heinemans@nxp.com>
  • Loading branch information
AndreHeinemans-NXP committed Mar 4, 2025
1 parent 1903a8f commit 01c58ac
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 9 deletions.
1 change: 1 addition & 0 deletions boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_ddr_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ CONFIG_CONSOLE=y
CONFIG_MBOX=y
CONFIG_MBOX_INIT_PRIORITY=0
CONFIG_ARM_SCMI=y
CONFIG_ARM_SCMI_NXP_VENDOR_EXTENSIONS=y

# kernel-related configurations
CONFIG_XIP=n
1 change: 1 addition & 0 deletions boards/nxp/imx95_evk/imx95_evk_mimx9596_m7_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ CONFIG_XIP=y
CONFIG_MBOX=y
CONFIG_MBOX_INIT_PRIORITY=0
CONFIG_ARM_SCMI=y
CONFIG_ARM_SCMI_NXP_VENDOR_EXTENSIONS=y
2 changes: 2 additions & 0 deletions drivers/firmware/scmi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c)
zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_CLK_HELPERS clk.c)
zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_PINCTRL_HELPERS pinctrl.c)
zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_POWER_DOMAIN_HELPERS power.c)

add_subdirectory_ifdef(CONFIG_ARM_SCMI nxp)
2 changes: 2 additions & 0 deletions drivers/firmware/scmi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ config ARM_SCMI_TRANSPORT_INIT_PRIORITY
help
SCMI transport driver device initialization priority.

source "drivers/firmware/scmi/nxp/Kconfig"

endif # ARM_SCMI
5 changes: 5 additions & 0 deletions drivers/firmware/scmi/nxp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()

zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_NXP_VENDOR_EXTENSIONS shmem.c)
8 changes: 8 additions & 0 deletions drivers/firmware/scmi/nxp/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright 2025 NXP
# SPDX-License-Identifier: Apache-2.0

config ARM_SCMI_NXP_VENDOR_EXTENSIONS
bool "Allow NXP specific SCMI features"
select CRC
help
When enabled, additional SCMI features specific to NXP will be available
50 changes: 50 additions & 0 deletions drivers/firmware/scmi/nxp/shmem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/drivers/firmware/scmi/shmem.h>
#include <zephyr/sys/crc.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(arm_scmi_shmem_nxp);

#define SMT_CRC_NONE 0U
#define SMT_CRC_XOR 1U /* Unsupported */
#define SMT_CRC_J1850 2U /* Unsupported */
#define SMT_CRC_CRC32 3U

int scmi_shmem_vendor_read_message(const struct scmi_shmem_layout *layout)
{
uint32_t validation_type = layout->res1[0];

if (validation_type == SMT_CRC_CRC32) {
if (layout->res1[1] != crc32_ieee((const uint8_t *)&layout->msg_hdr, layout->len)) {
LOG_ERR("bad message crc");
return -EBADMSG;
}
} else if (validation_type == SMT_CRC_NONE) {
/* do nothing */
} else {
LOG_ERR("invalid validation type 0x%x", validation_type);
return -EINVAL;
}

return 0;
}

int scmi_shmem_vendor_write_message(struct scmi_shmem_layout *layout)
{
uint32_t validation_type = layout->res1[0];

if (validation_type == SMT_CRC_CRC32) {
layout->res1[1] = crc32_ieee((const uint8_t *)&layout->msg_hdr, layout->len);
} else if (validation_type == SMT_CRC_NONE) {
/* do nothing */
} else {
LOG_ERR("invalid validation type 0x%x", validation_type);
return -EINVAL;
}

return 0;
}
28 changes: 19 additions & 9 deletions drivers/firmware/scmi/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,6 @@ struct scmi_shmem_data {
mm_reg_t regmap;
};

struct scmi_shmem_layout {
volatile uint32_t res0;
volatile uint32_t chan_status;
volatile uint32_t res1[2];
volatile uint32_t chan_flags;
volatile uint32_t len;
volatile uint32_t msg_hdr;
};

int scmi_shmem_get_channel_status(const struct device *dev, uint32_t *status)
{
struct scmi_shmem_data *data;
Expand All @@ -57,6 +48,16 @@ static void scmi_shmem_memcpy(mm_reg_t dst, mm_reg_t src, uint32_t bytes)
}
}

__weak int scmi_shmem_vendor_read_message(const struct scmi_shmem_layout *layout)
{
return 0;
}

__weak int scmi_shmem_vendor_write_message(struct scmi_shmem_layout *layout)
{
return 0;
}

int scmi_shmem_read_message(const struct device *shmem, struct scmi_message *msg)
{
struct scmi_shmem_layout *layout;
Expand Down Expand Up @@ -96,6 +97,11 @@ int scmi_shmem_read_message(const struct device *shmem, struct scmi_message *msg
return -EINVAL;
}

if (scmi_shmem_vendor_read_message(layout) < 0) {
LOG_ERR("vendor specific validation failed");
return -EINVAL;
}

if (msg->content) {
scmi_shmem_memcpy(POINTER_TO_UINT(msg->content),
data->regmap + sizeof(*layout), msg->len);
Expand Down Expand Up @@ -139,6 +145,10 @@ int scmi_shmem_write_message(const struct device *shmem, struct scmi_message *ms
POINTER_TO_UINT(msg->content), msg->len);
}

if (scmi_shmem_vendor_write_message(layout) < 0) {
return -EINVAL;
}

/* done, mark channel as busy and proceed */
layout->chan_status &= ~SCMI_SHMEM_CHAN_STATUS_BUSY_BIT;

Expand Down
29 changes: 29 additions & 0 deletions include/zephyr/drivers/firmware/scmi/shmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
#define SCMI_SHMEM_CHAN_STATUS_BUSY_BIT BIT(0)
#define SCMI_SHMEM_CHAN_FLAG_IRQ_BIT BIT(0)

struct scmi_shmem_layout {
volatile uint32_t res0;
volatile uint32_t chan_status;
volatile uint32_t res1[2];
volatile uint32_t chan_flags;
volatile uint32_t len;
volatile uint32_t msg_hdr;
};

struct scmi_message;

/**
Expand Down Expand Up @@ -64,4 +73,24 @@ void scmi_shmem_update_flags(const struct device *shmem,
*/
uint32_t scmi_shmem_channel_status(const struct device *shmem);

/**
* @brief Process vendor specific features when writing message
*
* @param layout layout of the message
*
* @retval 0 if successful
* @retval negative errno if failure
*/
int scmi_shmem_vendor_write_message(struct scmi_shmem_layout *layout);

/**
* @brief Process vendor specific features when reading message
*
* @param layout layout of the message
*
* @retval 0 if successful
* @retval negative errno if failure
*/
int scmi_shmem_vendor_read_message(const struct scmi_shmem_layout *layout);

#endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_SHMEM_H_ */

0 comments on commit 01c58ac

Please sign in to comment.