mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-04 20:26:13 +02:00
Merge patch series "firmware: scmi: Support SCMI LMM/CPU protocol for i.MX95"
Peng Fan (OSS) <peng.fan@oss.nxp.com> says: i.MX95 System Manager(SM) implements Logical Machine Management(LMM) and CPU protocol to manage Logical Machine(LM) and CPUs(eg, M7). To manage M7 in a separate LM or in same LM as U-Boot/Linux itself. LMM APIs and CPU APIs are needed. When M7 is in LM 'lm-m7', and this LM is managable by 'uboot-lm', U-Boot could use LMM_BOOT, LMM_SHUTDOWN and etc to manage 'lm-m7'. If in same LM, use CPU_START, CPU_STOP, CPU_RESET_VECTOR_SET and etc to manage M7. Both LMM/CPU APIs will be used by remoteproc driver. The documentation could be found in Linux Kernel: drivers/firmware/arm_scmi/vendors/imx/imx95.rst Link: https://lore.kernel.org/r/20251017-scmi-lmm-v1-0-9fd41e7a5ac0@nxp.com
This commit is contained in:
commit
fd976ff3a2
@ -41,3 +41,11 @@ config SCMI_AGENT_OPTEE
|
||||
help
|
||||
Enable the SCMI communication channel based on OP-TEE transport
|
||||
for compatible "linaro,scmi-optee".
|
||||
|
||||
config SCMI_ID_VENDOR_80
|
||||
bool
|
||||
|
||||
config SCMI_ID_VENDOR_82
|
||||
bool
|
||||
|
||||
source "drivers/firmware/scmi/vendors/imx/Kconfig"
|
||||
|
||||
@ -6,3 +6,4 @@ obj-$(CONFIG_SCMI_AGENT_MAILBOX) += mailbox_agent.o
|
||||
obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o
|
||||
obj-$(CONFIG_SCMI_POWER_DOMAIN) += pwdom.o
|
||||
obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o
|
||||
obj-y += vendors/imx/
|
||||
|
||||
@ -86,21 +86,41 @@ struct udevice *scmi_get_protocol(struct udevice *dev,
|
||||
case SCMI_PROTOCOL_ID_BASE:
|
||||
proto = priv->base_dev;
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
|
||||
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
|
||||
proto = priv->pwdom_dev;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_CLK_SCMI)
|
||||
case SCMI_PROTOCOL_ID_CLOCK:
|
||||
proto = priv->clock_dev;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_RESET_SCMI)
|
||||
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
|
||||
proto = priv->resetdom_dev;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
|
||||
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
|
||||
proto = priv->voltagedom_dev;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_PINCTRL_IMX_SCMI)
|
||||
case SCMI_PROTOCOL_ID_PINCTRL:
|
||||
proto = priv->pinctrl_dev;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_80)
|
||||
case SCMI_PROTOCOL_ID_VENDOR_80:
|
||||
proto = priv->vendor_dev_80;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_82)
|
||||
case SCMI_PROTOCOL_ID_VENDOR_82:
|
||||
proto = priv->vendor_dev_82;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
dev_err(dev, "Protocol not supported\n");
|
||||
proto = NULL;
|
||||
@ -139,21 +159,41 @@ static int scmi_add_protocol(struct udevice *dev,
|
||||
case SCMI_PROTOCOL_ID_BASE:
|
||||
priv->base_dev = proto;
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
|
||||
case SCMI_PROTOCOL_ID_POWER_DOMAIN:
|
||||
priv->pwdom_dev = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_CLK_SCMI)
|
||||
case SCMI_PROTOCOL_ID_CLOCK:
|
||||
priv->clock_dev = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_RESET_SCMI)
|
||||
case SCMI_PROTOCOL_ID_RESET_DOMAIN:
|
||||
priv->resetdom_dev = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
|
||||
case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
|
||||
priv->voltagedom_dev = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_PINCTRL_IMX_SCMI)
|
||||
case SCMI_PROTOCOL_ID_PINCTRL:
|
||||
priv->pinctrl_dev = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_80)
|
||||
case SCMI_PROTOCOL_ID_VENDOR_80:
|
||||
priv->vendor_dev_80 = proto;
|
||||
break;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_82)
|
||||
case SCMI_PROTOCOL_ID_VENDOR_82:
|
||||
priv->vendor_dev_82 = proto;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
dev_err(dev, "Protocol not supported\n");
|
||||
return -EPROTO;
|
||||
|
||||
15
drivers/firmware/scmi/vendors/imx/Kconfig
vendored
Normal file
15
drivers/firmware/scmi/vendors/imx/Kconfig
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
config IMX_SM_CPU
|
||||
bool "Enable i.MX System Manager CPU API"
|
||||
depends on ARCH_IMX9 && SCMI_FIRMWARE
|
||||
select SCMI_ID_VENDOR_82
|
||||
help
|
||||
If you say Y here to enable i.MX System Manager CPU
|
||||
API to work on some NXP i.MX processors.
|
||||
|
||||
config IMX_SM_LMM
|
||||
bool "Enable i.MX System Manager Logical Machine API"
|
||||
depends on ARCH_IMX9 && SCMI_FIRMWARE
|
||||
select SCMI_ID_VENDOR_80
|
||||
help
|
||||
If you say Y here to enable i.MX System Manager Logical Machine
|
||||
API to work on some NXP i.MX processors.
|
||||
8
drivers/firmware/scmi/vendors/imx/Makefile
vendored
Normal file
8
drivers/firmware/scmi/vendors/imx/Makefile
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Copyright 2025 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_IMX_SM_CPU) += imx-sm-cpu.o
|
||||
obj-$(CONFIG_IMX_SM_LMM) += imx-sm-lmm.o
|
||||
179
drivers/firmware/scmi/vendors/imx/imx-sm-cpu.c
vendored
Normal file
179
drivers/firmware/scmi/vendors/imx/imx-sm-cpu.c
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* i.MX SCMI CPU protocol
|
||||
*
|
||||
* Copyright 2025 NXP
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <misc.h>
|
||||
#include <scmi_agent.h>
|
||||
#include <scmi_agent-uclass.h>
|
||||
#include <scmi_protocols.h>
|
||||
#include <scmi_nxp_protocols.h>
|
||||
|
||||
enum scmi_imx_cpu_protocol_cmd {
|
||||
SCMI_IMX_CPU_ATTRIBUTES = 0x3,
|
||||
SCMI_IMX_CPU_START = 0x4,
|
||||
SCMI_IMX_CPU_STOP = 0x5,
|
||||
SCMI_IMX_CPU_RESET_VECTOR_SET = 0x6,
|
||||
SCMI_IMX_CPU_INFO_GET = 0xC,
|
||||
};
|
||||
|
||||
struct scmi_imx_cpu_priv {
|
||||
u32 nr_cpu;
|
||||
};
|
||||
|
||||
struct scmi_imx_cpu_reset_vector_set_in {
|
||||
__le32 cpuid;
|
||||
#define CPU_VEC_FLAGS_RESUME BIT(31)
|
||||
#define CPU_VEC_FLAGS_START BIT(30)
|
||||
#define CPU_VEC_FLAGS_BOOT BIT(29)
|
||||
__le32 flags;
|
||||
__le32 resetvectorlow;
|
||||
__le32 resetvectorhigh;
|
||||
};
|
||||
|
||||
struct scmi_imx_cpu_info_get_out {
|
||||
__le32 status;
|
||||
#define CPU_RUN_MODE_START 0
|
||||
#define CPU_RUN_MODE_HOLD 1
|
||||
#define CPU_RUN_MODE_STOP 2
|
||||
#define CPU_RUN_MODE_SLEEP 3
|
||||
__le32 runmode;
|
||||
__le32 sleepmode;
|
||||
__le32 resetvectorlow;
|
||||
__le32 resetvectorhigh;
|
||||
};
|
||||
|
||||
int scmi_imx_cpu_start(struct udevice *dev, u32 cpuid, bool start)
|
||||
{
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_82,
|
||||
.message_id = SCMI_IMX_CPU_STOP,
|
||||
.in_msg = (u8 *)&cpuid,
|
||||
.in_msg_sz = sizeof(cpuid),
|
||||
.out_msg = (u8 *)&status,
|
||||
.out_msg_sz = sizeof(status),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (start)
|
||||
msg.message_id = SCMI_IMX_CPU_START;
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scmi_imx_cpu_reset_vector_set(struct udevice *dev, u32 cpuid, u32 flags, u64 vector,
|
||||
bool start, bool boot, bool resume)
|
||||
{
|
||||
struct scmi_imx_cpu_reset_vector_set_in in;
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_82,
|
||||
.message_id = SCMI_IMX_CPU_RESET_VECTOR_SET,
|
||||
.in_msg = (u8 *)&in,
|
||||
.in_msg_sz = sizeof(in),
|
||||
.out_msg = (u8 *)&status,
|
||||
.out_msg_sz = sizeof(status),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
in.cpuid = cpu_to_le32(cpuid);
|
||||
in.flags = cpu_to_le32(0);
|
||||
if (start)
|
||||
in.flags |= CPU_VEC_FLAGS_START;
|
||||
if (boot)
|
||||
in.flags |= CPU_VEC_FLAGS_BOOT;
|
||||
if (resume)
|
||||
in.flags |= CPU_VEC_FLAGS_RESUME;
|
||||
in.resetvectorlow = cpu_to_le32(lower_32_bits(vector));
|
||||
in.resetvectorhigh = cpu_to_le32(upper_32_bits(vector));
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scmi_imx_cpu_started(struct udevice *dev, u32 cpuid, bool *started)
|
||||
{
|
||||
struct scmi_imx_cpu_info_get_out out;
|
||||
u32 mode;
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_82,
|
||||
.message_id = SCMI_IMX_CPU_INFO_GET,
|
||||
.in_msg = (u8 *)&cpuid,
|
||||
.in_msg_sz = sizeof(cpuid),
|
||||
.out_msg = (u8 *)&out,
|
||||
.out_msg_sz = sizeof(out),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
status = cpu_to_le32(out.status);
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
mode = le32_to_cpu(out.runmode);
|
||||
if (mode == CPU_RUN_MODE_START || mode == CPU_RUN_MODE_SLEEP)
|
||||
*started = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scmi_imx_cpu_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devm_scmi_of_get_channel(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get channel (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(scmi_imx_cpu) = {
|
||||
.name = "scmi_imx_cpu",
|
||||
.id = UCLASS_SCMI_BASE,
|
||||
.probe = scmi_imx_cpu_probe,
|
||||
.priv_auto = sizeof(struct scmi_imx_cpu_priv),
|
||||
};
|
||||
|
||||
static struct scmi_proto_match match[] = {
|
||||
{ .proto_id = SCMI_PROTOCOL_ID_VENDOR_82},
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_SCMI_PROTO_DRIVER(scmi_imx_cpu, match);
|
||||
213
drivers/firmware/scmi/vendors/imx/imx-sm-lmm.c
vendored
Normal file
213
drivers/firmware/scmi/vendors/imx/imx-sm-lmm.c
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* i.MX SCMI LMM protocol
|
||||
*
|
||||
* Copyright 2025 NXP
|
||||
*/
|
||||
|
||||
#include <compiler.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/types.h>
|
||||
#include <misc.h>
|
||||
#include <scmi_agent.h>
|
||||
#include <scmi_agent-uclass.h>
|
||||
#include <scmi_protocols.h>
|
||||
#include <scmi_nxp_protocols.h>
|
||||
|
||||
enum scmi_imx_lmm_protocol_cmd {
|
||||
SCMI_IMX_LMM_ATTRIBUTES = 0x3,
|
||||
SCMI_IMX_LMM_BOOT = 0x4,
|
||||
SCMI_IMX_LMM_RESET = 0x5,
|
||||
SCMI_IMX_LMM_SHUTDOWN = 0x6,
|
||||
SCMI_IMX_LMM_WAKE = 0x7,
|
||||
SCMI_IMX_LMM_SUSPEND = 0x8,
|
||||
SCMI_IMX_LMM_NOTIFY = 0x9,
|
||||
SCMI_IMX_LMM_RESET_REASON = 0xA,
|
||||
SCMI_IMX_LMM_POWER_ON = 0xB,
|
||||
SCMI_IMX_LMM_RESET_VECTOR_SET = 0xC,
|
||||
};
|
||||
|
||||
struct scmi_imx_lmm_priv {
|
||||
u32 nr_lmm;
|
||||
};
|
||||
|
||||
struct scmi_msg_imx_lmm_attributes_out {
|
||||
__le32 status;
|
||||
__le32 lmid;
|
||||
__le32 attributes;
|
||||
__le32 state;
|
||||
__le32 errstatus;
|
||||
u8 name[LMM_MAX_NAME];
|
||||
};
|
||||
|
||||
struct scmi_imx_lmm_reset_vector_set_in {
|
||||
__le32 lmid;
|
||||
__le32 cpuid;
|
||||
__le32 flags; /* reserved for future extension */
|
||||
__le32 resetvectorlow;
|
||||
__le32 resetvectorhigh;
|
||||
};
|
||||
|
||||
struct scmi_imx_lmm_shutdown_in {
|
||||
__le32 lmid;
|
||||
#define SCMI_IMX_LMM_SHUTDOWN_GRACEFUL BIT(0)
|
||||
__le32 flags;
|
||||
};
|
||||
|
||||
int scmi_imx_lmm_info(struct udevice *dev, u32 lmid, struct scmi_imx_lmm_info *info)
|
||||
{
|
||||
struct scmi_msg_imx_lmm_attributes_out out;
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_80,
|
||||
.message_id = SCMI_IMX_LMM_ATTRIBUTES,
|
||||
.in_msg = (u8 *)&lmid,
|
||||
.in_msg_sz = sizeof(lmid),
|
||||
.out_msg = (u8 *)&out,
|
||||
.out_msg_sz = sizeof(out),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
status = cpu_to_le32(out.status);
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
info->lmid = le32_to_cpu(out.lmid);
|
||||
info->state = le32_to_cpu(out.state);
|
||||
info->errstatus = le32_to_cpu(out.errstatus);
|
||||
strcpy(info->name, out.name);
|
||||
dev_dbg(dev, "i.MX LMM: Logical Machine(%d), name: %s\n",
|
||||
info->lmid, info->name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int scmi_imx_lmm_power_boot(struct udevice *dev, u32 lmid, bool boot)
|
||||
{
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_80,
|
||||
.message_id = SCMI_IMX_LMM_POWER_ON,
|
||||
.in_msg = (u8 *)&lmid,
|
||||
.in_msg_sz = sizeof(lmid),
|
||||
.out_msg = (u8 *)&status,
|
||||
.out_msg_sz = sizeof(status),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (boot)
|
||||
msg.message_id = SCMI_IMX_LMM_BOOT;
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scmi_imx_lmm_reset_vector_set(struct udevice *dev, u32 lmid, u32 cpuid, u32 flags, u64 vector)
|
||||
{
|
||||
struct scmi_imx_lmm_reset_vector_set_in in;
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_80,
|
||||
.message_id = SCMI_IMX_LMM_RESET_VECTOR_SET,
|
||||
.in_msg = (u8 *)&in,
|
||||
.in_msg_sz = sizeof(in),
|
||||
.out_msg = (u8 *)&status,
|
||||
.out_msg_sz = sizeof(status),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
in.lmid = lmid;
|
||||
in.cpuid = cpuid;
|
||||
in.flags = flags;
|
||||
in.resetvectorlow = vector & 0xFFFFFFFF;
|
||||
in.resetvectorhigh = vector >> 32;
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scmi_imx_lmm_shutdown(struct udevice *dev, u32 lmid, bool flags)
|
||||
{
|
||||
struct scmi_imx_lmm_shutdown_in in;
|
||||
s32 status;
|
||||
struct scmi_msg msg = {
|
||||
.protocol_id = SCMI_PROTOCOL_ID_VENDOR_80,
|
||||
.message_id = SCMI_IMX_LMM_SHUTDOWN,
|
||||
.in_msg = (u8 *)&in,
|
||||
.in_msg_sz = sizeof(in),
|
||||
.out_msg = (u8 *)&status,
|
||||
.out_msg_sz = sizeof(status),
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
in.lmid = lmid;
|
||||
if (flags & SCMI_IMX_LMM_SHUTDOWN_GRACEFUL)
|
||||
in.flags = cpu_to_le32(SCMI_IMX_LMM_SHUTDOWN_GRACEFUL);
|
||||
else
|
||||
in.flags = cpu_to_le32(0);
|
||||
|
||||
ret = devm_scmi_process_msg(dev, &msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status)
|
||||
return scmi_to_linux_errno(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scmi_imx_lmm_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devm_scmi_of_get_channel(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get channel (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(scmi_imx_lmm) = {
|
||||
.name = "scmi_imx_lmm",
|
||||
.id = UCLASS_SCMI_BASE,
|
||||
.probe = scmi_imx_lmm_probe,
|
||||
.priv_auto = sizeof(struct scmi_imx_lmm_priv),
|
||||
};
|
||||
|
||||
static struct scmi_proto_match match[] = {
|
||||
{ .proto_id = SCMI_PROTOCOL_ID_VENDOR_80},
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_SCMI_PROTO_DRIVER(scmi_imx_lmm, match);
|
||||
@ -40,11 +40,27 @@ struct scmi_agent_priv {
|
||||
u8 *agent_name;
|
||||
u32 agent_id;
|
||||
struct udevice *base_dev;
|
||||
#if IS_ENABLED(CONFIG_SCMI_POWER_DOMAIN)
|
||||
struct udevice *pwdom_dev;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_CLK_SCMI)
|
||||
struct udevice *clock_dev;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_RESET_SCMI)
|
||||
struct udevice *resetdom_dev;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_DM_REGULATOR_SCMI)
|
||||
struct udevice *voltagedom_dev;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_PINCTRL_IMX_SCMI)
|
||||
struct udevice *pinctrl_dev;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_80)
|
||||
struct udevice *vendor_dev_80;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_82)
|
||||
struct udevice *vendor_dev_82;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline u32 scmi_version(struct udevice *dev)
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
#include <asm/types.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
enum scmi_imx_protocol {
|
||||
SCMI_IMX_PROTOCOL_ID_MISC = 0x84,
|
||||
};
|
||||
#define SCMI_PROTOCOL_ID_IMX_LMM 0x80
|
||||
#define SCMI_PROTOCOL_ID_IMX_CPU 0x82
|
||||
#define SCMI_PROTOCOL_ID_IMX_MISC 0x84
|
||||
|
||||
#define SCMI_PAYLOAD_LEN 100
|
||||
|
||||
@ -52,4 +52,71 @@ struct scmi_imx_misc_reset_reason_out {
|
||||
u32 extInfo[MISC_MAX_EXTINFO];
|
||||
};
|
||||
|
||||
#define LMM_ID_DISCOVER 0xFFFFFFFFU
|
||||
#define LMM_MAX_NAME 16
|
||||
|
||||
enum scmi_imx_lmm_state {
|
||||
LMM_STATE_LM_OFF,
|
||||
LMM_STATE_LM_ON,
|
||||
LMM_STATE_LM_SUSPEND,
|
||||
LMM_STATE_LM_POWERED,
|
||||
};
|
||||
|
||||
struct scmi_imx_lmm_info {
|
||||
u32 lmid;
|
||||
enum scmi_imx_lmm_state state;
|
||||
u32 errstatus;
|
||||
u8 name[LMM_MAX_NAME];
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IMX_SM_LMM)
|
||||
int scmi_imx_lmm_info(struct udevice *dev, u32 lmid, struct scmi_imx_lmm_info *info);
|
||||
int scmi_imx_lmm_power_boot(struct udevice *dev, u32 lmid, bool boot);
|
||||
int scmi_imx_lmm_reset_vector_set(struct udevice *dev, u32 lmid, u32 cpuid, u32 flags, u64 vector);
|
||||
int scmi_imx_lmm_shutdown(struct udevice *dev, u32 lmid, bool flags);
|
||||
#else
|
||||
static inline int scmi_imx_lmm_info(struct udevice *dev, u32 lmid, struct scmi_imx_lmm_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int scmi_imx_lmm_power_boot(struct udevice *dev, u32 lmid, bool boot)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int
|
||||
scmi_imx_lmm_reset_vector_set(struct udevice *dev, u32 lmid, u32 cpuid, u32 flags, u64 vector)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int scmi_imx_lmm_shutdown(struct udevice *dev, u32 lmid, bool flags)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_IMX_SM_CPU)
|
||||
int scmi_imx_cpu_started(struct udevice *dev, u32 cpuid, bool *started);
|
||||
int scmi_imx_cpu_reset_vector_set(struct udevice *dev, u32 cpuid, u32 flags, u64 vector,
|
||||
bool start, bool boot, bool resume);
|
||||
int scmi_imx_cpu_start(struct udevice *dev, u32 cpuid, bool start);
|
||||
#else
|
||||
static inline int scmi_imx_cpu_started(struct udevice *dev, u32 cpuid, bool *started)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int scmi_imx_cpu_reset_vector_set(struct udevice *dev, u32 cpuid, u32 flags,
|
||||
u64 vector, bool start, bool boot, bool resume)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int scmi_imx_cpu_start(struct udevice *dev, u32 cpuid, bool start)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -25,7 +25,8 @@ enum scmi_std_protocol {
|
||||
SCMI_PROTOCOL_ID_RESET_DOMAIN = 0x16,
|
||||
SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN = 0x17,
|
||||
SCMI_PROTOCOL_ID_PINCTRL = 0x19,
|
||||
SCMI_PROTOCOL_ID_IMX_MISC = 0x84,
|
||||
SCMI_PROTOCOL_ID_VENDOR_80 = 0x80,
|
||||
SCMI_PROTOCOL_ID_VENDOR_82 = 0x82,
|
||||
};
|
||||
|
||||
enum scmi_status_code {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user