mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2026-01-27 12:35:36 +01:00
LF-13910-5: drivers: firmware: imx: add support for imx93 soc
Add support for imx93 soc and its platforms. Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com> Acked-by: Rahul Kumar Yadav <rahulkumar.yadav@nxp.com> Acked-by: Vabhav Sharma <vabhav.sharma@nxp.com> Acked-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com> Acked-by: Jason Liu <jason.hui.liu@nxp.com>
This commit is contained in:
parent
2c2034c656
commit
c44540c6a8
|
|
@ -52,3 +52,16 @@ config IMX_SEC_ENCLAVE
|
|||
like base, HSM, V2X & SHE using the SAB protocol via the shared Messaging
|
||||
Unit. This driver exposes these interfaces via a set of file descriptors
|
||||
allowing to configure shared memory, send and receive messages.
|
||||
|
||||
config IMX_ELE_TRNG
|
||||
bool "i.MX ELE True Random Number Generator"
|
||||
depends on IMX_SEC_ENCLAVE
|
||||
default y
|
||||
select CRYPTO_RNG
|
||||
select HW_RANDOM
|
||||
|
||||
help
|
||||
With platforms having secure enclave as the only true source for
|
||||
generating true random number, the config CONFIG_ELE_TRNG needs to be enabled.
|
||||
This config helps provides kernel-side support for the Random Number generation,
|
||||
through NXP hardware IP for secure-enclave(s), called EdgeLock Enclave.
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco
|
|||
obj-${CONFIG_IMX_SCMI_MISC_CONTROL} += sm-misc.o
|
||||
obj-$(CONFIG_IMX_SCMI_BBM_CONTROL) += sm-bbm.o
|
||||
obj-$(CONFIG_IMX_ISPMU) += isp-mu.o
|
||||
sec_enclave-objs = se_ctrl.o ele_common.o ele_base_msg.o
|
||||
sec_enclave-objs = se_ctrl.o ele_common.o ele_base_msg.o ele_fw_api.o
|
||||
obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
|
||||
sec_enclave-${CONFIG_IMX_ELE_TRNG} += ele_trng.o
|
||||
|
|
|
|||
|
|
@ -404,3 +404,252 @@ int ele_debug_dump(struct se_if_priv *priv)
|
|||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ele_start_rng() - prepare and send the command to start
|
||||
* initialization of the ELE RNG context
|
||||
*
|
||||
* returns: 0 on success.
|
||||
*/
|
||||
int ele_start_rng(struct se_if_priv *priv)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_START_RNG_REQ_MSG_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rx_msg = kzalloc(ELE_START_RNG_RSP_MSG_SZ, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv,
|
||||
(struct se_msg_hdr *)&tx_msg->header,
|
||||
ELE_START_RNG_REQ,
|
||||
ELE_START_RNG_REQ_MSG_SZ,
|
||||
true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_START_RNG_REQ_MSG_SZ,
|
||||
rx_msg,
|
||||
ELE_START_RNG_RSP_MSG_SZ);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
ELE_START_RNG_REQ,
|
||||
ELE_START_RNG_RSP_MSG_SZ,
|
||||
true);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ele_write_fuse(struct se_if_priv *priv, u16 fuse_index,
|
||||
u32 value, bool block)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_WRITE_FUSE_REQ_MSG_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rx_msg = kzalloc(ELE_WRITE_FUSE_RSP_MSG_SZ, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv,
|
||||
(struct se_msg_hdr *)&tx_msg->header,
|
||||
ELE_WRITE_FUSE,
|
||||
ELE_WRITE_FUSE_REQ_MSG_SZ,
|
||||
true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
tx_msg->data[0] = (32 << 16) | (fuse_index << 5);
|
||||
if (block)
|
||||
tx_msg->data[0] |= BIT(31);
|
||||
|
||||
tx_msg->data[1] = value;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_WRITE_FUSE_REQ_MSG_SZ,
|
||||
rx_msg,
|
||||
ELE_WRITE_FUSE_RSP_MSG_SZ);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
ELE_WRITE_FUSE,
|
||||
ELE_WRITE_FUSE_RSP_MSG_SZ,
|
||||
true);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* read_common_fuse() - Brief description of function.
|
||||
* @struct device *dev: Device to send the request to read fuses.
|
||||
* @u16 fuse_id: Fuse identifier to read.
|
||||
* @u32 *value: unsigned integer array to store the fused-values.
|
||||
*
|
||||
* Secure-enclave like EdgeLock Enclave, manages the fuse. This API
|
||||
* requests FW to read the common fuses. FW sends the read value as
|
||||
* response.
|
||||
*
|
||||
* Context: This function takes two mutex locks: one on the command
|
||||
* and second on the message unit.
|
||||
* such that multiple commands cannot be sent.
|
||||
* for the device Describes whether the function can sleep, what locks it takes,
|
||||
* releases, or expects to be held. It can extend over multiple
|
||||
* lines.
|
||||
* Return: Describe the return value of function_name.
|
||||
*
|
||||
* The return value description can also have multiple paragraphs, and should
|
||||
* be placed at the end of the comment block.
|
||||
*/
|
||||
int read_common_fuse(struct se_if_priv *priv,
|
||||
u16 fuse_id, u32 *value)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
int rx_msg_sz = ELE_READ_FUSE_RSP_MSG_SZ;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_READ_FUSE_REQ_MSG_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fuse_id == OTP_UNIQ_ID)
|
||||
rx_msg_sz = ELE_READ_FUSE_OTP_UNQ_ID_RSP_MSG_SZ;
|
||||
|
||||
rx_msg = kzalloc(rx_msg_sz, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv, (struct se_msg_hdr *)&tx_msg->header,
|
||||
ELE_READ_FUSE_REQ, ELE_READ_FUSE_REQ_MSG_SZ,
|
||||
true);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Error: se_fill_cmd_msg_hdr failed.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg->data[0] = fuse_id;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_READ_FUSE_REQ_MSG_SZ,
|
||||
rx_msg,
|
||||
rx_msg_sz);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
ELE_READ_FUSE_REQ,
|
||||
rx_msg_sz,
|
||||
true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
switch (fuse_id) {
|
||||
case OTP_UNIQ_ID:
|
||||
value[0] = rx_msg->data[1];
|
||||
value[1] = rx_msg->data[2];
|
||||
value[2] = rx_msg->data[3];
|
||||
value[3] = rx_msg->data[4];
|
||||
break;
|
||||
default:
|
||||
value[0] = rx_msg->data[1];
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ele_voltage_change_req(struct se_if_priv *priv, bool start)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
u8 cmd = start ? ELE_VOLT_CHANGE_START_REQ : ELE_VOLT_CHANGE_FINISH_REQ;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_VOLT_CHANGE_REQ_MSG_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rx_msg = kzalloc(ELE_VOLT_CHANGE_RSP_MSG_SZ, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv,
|
||||
(struct se_msg_hdr *)&tx_msg->header,
|
||||
cmd,
|
||||
ELE_VOLT_CHANGE_REQ_MSG_SZ,
|
||||
true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_VOLT_CHANGE_REQ_MSG_SZ,
|
||||
rx_msg,
|
||||
ELE_VOLT_CHANGE_RSP_MSG_SZ);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
cmd,
|
||||
ELE_VOLT_CHANGE_RSP_MSG_SZ,
|
||||
true);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,27 @@ struct ele_dev_info {
|
|||
#define ELE_FW_AUTH_REQ_SZ 0x10
|
||||
#define ELE_FW_AUTH_RSP_MSG_SZ 0x08
|
||||
|
||||
#define ELE_START_RNG_REQ 0xA3
|
||||
#define ELE_START_RNG_REQ_MSG_SZ 0x04
|
||||
#define ELE_START_RNG_RSP_MSG_SZ 0x08
|
||||
|
||||
#define ELE_WRITE_FUSE 0xD6
|
||||
#define ELE_WRITE_FUSE_REQ_MSG_SZ 12
|
||||
#define ELE_WRITE_FUSE_RSP_MSG_SZ 12
|
||||
|
||||
#define ELE_READ_FUSE_REQ 0x97
|
||||
#define ELE_READ_FUSE_REQ_MSG_SZ 0x08
|
||||
#define ELE_READ_FUSE_RSP_MSG_SZ 0x0C
|
||||
#define ELE_READ_FUSE_OTP_UNQ_ID_RSP_MSG_SZ \
|
||||
0x1C
|
||||
#define OTP_UNIQ_ID 0x01
|
||||
#define OTFAD_CONFIG 0x2
|
||||
|
||||
#define ELE_VOLT_CHANGE_START_REQ 0x12
|
||||
#define ELE_VOLT_CHANGE_FINISH_REQ 0x13
|
||||
#define ELE_VOLT_CHANGE_REQ_MSG_SZ 0x4
|
||||
#define ELE_VOLT_CHANGE_RSP_MSG_SZ 0x8
|
||||
|
||||
int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info);
|
||||
int ele_fetch_soc_info(struct se_if_priv *priv, void *data);
|
||||
int ele_ping(struct se_if_priv *priv);
|
||||
|
|
@ -95,4 +116,10 @@ int ele_service_swap(struct se_if_priv *priv,
|
|||
u32 addr_size, u16 flag);
|
||||
int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr);
|
||||
int ele_debug_dump(struct se_if_priv *priv);
|
||||
int ele_start_rng(struct se_if_priv *priv);
|
||||
int ele_write_fuse(struct se_if_priv *priv, u16 fuse_index,
|
||||
u32 value, bool block);
|
||||
int ele_voltage_change_req(struct se_if_priv *priv, bool start);
|
||||
int read_common_fuse(struct se_if_priv *priv,
|
||||
u16 fuse_id, u32 *value);
|
||||
#endif
|
||||
|
|
|
|||
152
drivers/firmware/imx/ele_fw_api.c
Normal file
152
drivers/firmware/imx/ele_fw_api.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2023-2024 NXP
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/firmware/imx/se_api.h>
|
||||
|
||||
#include "ele_common.h"
|
||||
#include "ele_fw_api.h"
|
||||
|
||||
struct ele_rng_msg_data {
|
||||
u16 rsv;
|
||||
u16 flags;
|
||||
u32 data[2];
|
||||
};
|
||||
|
||||
int ele_init_fw(struct se_if_priv *priv)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_INIT_FW_REQ_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rx_msg = kzalloc(ELE_INIT_FW_RSP_SZ, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv,
|
||||
(struct se_msg_hdr *)&tx_msg->header,
|
||||
ELE_INIT_FW_REQ,
|
||||
ELE_INIT_FW_REQ_SZ,
|
||||
false);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_INIT_FW_REQ_SZ,
|
||||
rx_msg,
|
||||
ELE_INIT_FW_RSP_SZ);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
ELE_INIT_FW_REQ,
|
||||
ELE_INIT_FW_RSP_SZ,
|
||||
false);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ele_get_random() - prepare and send the command to proceed
|
||||
* with a random number generation operation
|
||||
*
|
||||
* returns: size of the rondom number generated
|
||||
*/
|
||||
int ele_get_random(struct se_if_priv *priv,
|
||||
void *data, size_t len)
|
||||
{
|
||||
struct se_api_msg *tx_msg __free(kfree) = NULL;
|
||||
struct se_api_msg *rx_msg __free(kfree) = NULL;
|
||||
struct ele_rng_msg_data *rng_msg_data;
|
||||
dma_addr_t dst_dma;
|
||||
u8 *buf = NULL;
|
||||
int ret;
|
||||
|
||||
if (!priv) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tx_msg = kzalloc(ELE_GET_RANDOM_REQ_SZ, GFP_KERNEL);
|
||||
if (!tx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rx_msg = kzalloc(ELE_GET_RANDOM_RSP_SZ, GFP_KERNEL);
|
||||
if (!rx_msg) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* As per RBG3(RS) construction mentioned in NIST SP800-90C,
|
||||
* CTR_DRBG generates 128(full entropy) bits after reseeding
|
||||
* the CTR_DRBG with 256 bits of entropy. so splitting the
|
||||
* user rng request in multiple of 128 bits & enforce reseed
|
||||
* for every iteration.
|
||||
*/
|
||||
len = ELE_RNG_MAX_SIZE;
|
||||
buf = dma_alloc_coherent(priv->dev, len, &dst_dma, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
dev_err(priv->dev, "Failed to map destination buffer memory.\n");
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = se_fill_cmd_msg_hdr(priv,
|
||||
(struct se_msg_hdr *)&tx_msg->header,
|
||||
ELE_GET_RANDOM_REQ,
|
||||
ELE_GET_RANDOM_REQ_SZ,
|
||||
false);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
rng_msg_data = (struct ele_rng_msg_data *)tx_msg->data;
|
||||
/* bit 1(blocking reseed): wait for trng entropy,
|
||||
* then reseed rng context.
|
||||
*/
|
||||
if (get_se_soc_id(priv) != SOC_ID_OF_IMX95)
|
||||
rng_msg_data->flags = BIT(1);
|
||||
|
||||
rng_msg_data->data[0] = dst_dma;
|
||||
rng_msg_data->data[1] = len;
|
||||
|
||||
ret = ele_msg_send_rcv(priv->priv_dev_ctx,
|
||||
tx_msg,
|
||||
ELE_GET_RANDOM_REQ_SZ,
|
||||
rx_msg,
|
||||
ELE_GET_RANDOM_RSP_SZ);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = se_val_rsp_hdr_n_status(priv,
|
||||
rx_msg,
|
||||
ELE_GET_RANDOM_REQ,
|
||||
ELE_GET_RANDOM_RSP_SZ,
|
||||
false);
|
||||
if (!ret) {
|
||||
memcpy(data, buf, len);
|
||||
ret = len;
|
||||
}
|
||||
exit:
|
||||
if (buf)
|
||||
dma_free_coherent(priv->dev, len, buf, dst_dma);
|
||||
return ret;
|
||||
}
|
||||
26
drivers/firmware/imx/ele_fw_api.h
Normal file
26
drivers/firmware/imx/ele_fw_api.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2024 NXP
|
||||
*/
|
||||
|
||||
#ifndef ELE_FW_API_H
|
||||
#define ELE_FW_API_H
|
||||
|
||||
#include <linux/hw_random.h>
|
||||
|
||||
#define MESSAGING_VERSION_7 0x7
|
||||
|
||||
#define ELE_INIT_FW_REQ 0x17
|
||||
#define ELE_INIT_FW_REQ_SZ 0x04
|
||||
#define ELE_INIT_FW_RSP_SZ 0x08
|
||||
|
||||
#define ELE_GET_RANDOM_REQ 0xCD
|
||||
#define ELE_GET_RANDOM_REQ_SZ 0x10
|
||||
#define ELE_GET_RANDOM_RSP_SZ 0x08
|
||||
#define ELE_RNG_MAX_SIZE 16
|
||||
|
||||
int ele_init_fw(struct se_if_priv *priv);
|
||||
int ele_get_random(struct se_if_priv *priv, void *data, size_t len);
|
||||
int ele_get_hwrng(struct hwrng *rng, void *data, size_t len, bool wait);
|
||||
|
||||
#endif /* ELE_FW_API_H */
|
||||
47
drivers/firmware/imx/ele_trng.c
Normal file
47
drivers/firmware/imx/ele_trng.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* ELE Random Number Generator Driver NXP's Platforms
|
||||
*
|
||||
* Copyright 2024 NXP
|
||||
*/
|
||||
|
||||
#include "ele_trng.h"
|
||||
#include "ele_fw_api.h"
|
||||
|
||||
struct ele_trng {
|
||||
struct hwrng rng;
|
||||
struct se_if_priv *priv;
|
||||
};
|
||||
|
||||
int ele_trng_init(struct se_if_priv *priv)
|
||||
{
|
||||
struct ele_trng *trng;
|
||||
int ret;
|
||||
|
||||
trng = devm_kzalloc(priv->dev, sizeof(*trng), GFP_KERNEL);
|
||||
if (!trng)
|
||||
return -ENOMEM;
|
||||
|
||||
trng->priv = priv;
|
||||
trng->rng.name = "ele-trng";
|
||||
trng->rng.read = ele_get_hwrng;
|
||||
trng->rng.priv = (unsigned long)trng;
|
||||
trng->rng.quality = 1024;
|
||||
|
||||
dev_dbg(priv->dev, "registering ele-trng\n");
|
||||
|
||||
ret = devm_hwrng_register(priv->dev, &trng->rng);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(priv->dev, "Successfully registered ele-trng\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ele_get_hwrng(struct hwrng *rng,
|
||||
void *data, size_t len, bool wait)
|
||||
{
|
||||
struct ele_trng *trng = (struct ele_trng *)rng->priv;
|
||||
|
||||
return ele_get_random(trng->priv, data, len);
|
||||
}
|
||||
21
drivers/firmware/imx/ele_trng.h
Normal file
21
drivers/firmware/imx/ele_trng.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2024 NXP
|
||||
*/
|
||||
|
||||
#ifndef __ELE_TRNG_H__
|
||||
#define __ELE_TRNG_H__
|
||||
|
||||
#include "se_ctrl.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_IMX_ELE_TRNG)
|
||||
|
||||
int ele_trng_init(struct se_if_priv *priv);
|
||||
|
||||
#else
|
||||
|
||||
#define ele_trng_init NULL
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*__ELE_TRNG_H__ */
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "ele_base_msg.h"
|
||||
#include "ele_common.h"
|
||||
#include "ele_fw_api.h"
|
||||
#include "ele_trng.h"
|
||||
#include "se_ctrl.h"
|
||||
|
||||
#define MAX_SOC_INFO_DATA_SZ 256
|
||||
|
|
@ -60,6 +62,10 @@ struct se_if_node_info {
|
|||
struct se_if_defines if_defs;
|
||||
u8 *pool_name;
|
||||
bool reserved_dma_ranges;
|
||||
int (*start_rng)(struct se_if_priv *priv);
|
||||
int (*init_trng)(struct se_if_priv *priv);
|
||||
int (*se_if_early_init)(struct se_if_priv *priv);
|
||||
int (*se_if_late_init)(struct se_if_priv *priv);
|
||||
};
|
||||
|
||||
/* contains fixed information */
|
||||
|
|
@ -130,8 +136,7 @@ static struct se_if_node_info_list imx93_info = {
|
|||
},
|
||||
.info = {
|
||||
{
|
||||
.se_if_id = 2,
|
||||
.se_if_did = 3,
|
||||
.se_if_id = 0,
|
||||
.if_defs = {
|
||||
.se_if_type = SE_TYPE_ID_HSM,
|
||||
.se_instance_id = 0,
|
||||
|
|
@ -142,6 +147,10 @@ static struct se_if_node_info_list imx93_info = {
|
|||
.fw_api_ver = MESSAGING_VERSION_7,
|
||||
},
|
||||
.reserved_dma_ranges = true,
|
||||
.start_rng = ele_start_rng,
|
||||
.init_trng = ele_trng_init,
|
||||
.se_if_early_init = NULL,
|
||||
.se_if_late_init = ele_init_fw,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1501,6 +1510,25 @@ static int se_if_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (info->se_if_late_init) {
|
||||
ret = info->se_if_late_init(priv);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* start ele rng */
|
||||
if (info->start_rng) {
|
||||
ret = info->start_rng(priv);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed[0x%x] to start rng.\n", ret);
|
||||
}
|
||||
|
||||
if (info->init_trng) {
|
||||
ret = info->init_trng(priv);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed[0x%x] to init trng.\n", ret);
|
||||
}
|
||||
|
||||
/* By default, there is no pending FW to be loaded.*/
|
||||
if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs ||
|
||||
info_list->se_fw_img_nm.seco_fw_nm_in_rfs) {
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ struct se_if_priv {
|
|||
#define SE_DUMP_MU_RCV_BUFS 2
|
||||
#define SE_DUMP_KDEBUG_BUFS 3
|
||||
|
||||
uint32_t get_se_soc_id(struct se_if_priv *priv);
|
||||
int se_dump_to_logfl(struct se_if_device_ctx *dev_ctx,
|
||||
u8 caller_type, int buf_size,
|
||||
const char *buf, ...);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user