aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-10-09 09:35:43 -0400
committerTom Rini <trini@konsulko.com>2019-10-09 11:44:45 -0400
commiteaa0bde05186b1738d221bc5effc6f257a14e360 (patch)
tree4e3c589df0fcd55fb38587ff708f6cd4a0d3863b /drivers/misc
parent8c05abad1367e33908ee43c590801e338967838d (diff)
parent9fb50c68daa696056c7842989e5f7fae1d326b34 (diff)
downloadu-boot-eaa0bde05186b1738d221bc5effc6f257a14e360.zip
u-boot-eaa0bde05186b1738d221bc5effc6f257a14e360.tar.gz
u-boot-eaa0bde05186b1738d221bc5effc6f257a14e360.tar.bz2
Merge tag 'u-boot-imx-20191009' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20191009 ------------------- Travis : https://travis-ci.org/sbabic/u-boot-imx/builds/595148532 - MX6UL / ULZ - Toradex board - Allow to set OCRAM for MX6Q/D - MX7ULP - MX8: (container image, imx8mq_mek), SCU API - fix several board booting from SD/EMMC (cubox-i for example) - pico boards [trini: display5 merged manually] Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/misc/imx8/scu_api.c553
2 files changed, 554 insertions, 1 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8037b6e..ba50893 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -202,7 +202,7 @@ config JZ4780_EFUSE
config MXC_OCOTP
bool "Enable MXC OCOTP Driver"
- depends on ARCH_IMX8M || ARCH_MX6 || ARCH_MX7 || ARCH_VF610
+ depends on ARCH_IMX8M || ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_VF610
default y
help
If you say Y here, you will get support for the One Time
diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c
index 031bc00..b2fdeef 100644
--- a/drivers/misc/imx8/scu_api.c
+++ b/drivers/misc/imx8/scu_api.c
@@ -13,6 +13,8 @@
DECLARE_GLOBAL_DATA_PTR;
+#define B2U8(X) (((X) != SC_FALSE) ? (u8)(0x01U) : (u8)(0x00U))
+
/* CLK and PM */
int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
sc_pm_clock_rate_t *rate)
@@ -93,6 +95,30 @@ int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
return ret;
}
+int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_clk_t clk, sc_pm_clk_parent_t parent)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+ RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_PARENT;
+ RPC_U16(&msg, 0U) = (u16)resource;
+ RPC_U8(&msg, 2U) = (u8)clk;
+ RPC_U8(&msg, 3U) = (u8)parent;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: resource:%d clk:%d: parent clk: %d, res:%d\n",
+ __func__, resource, clk, parent, RPC_R8(&msg));
+
+ return ret;
+}
+
int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
sc_pm_power_mode_t mode)
{
@@ -119,6 +145,33 @@ int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
return ret;
}
+sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+ u8 result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM);
+ RPC_FUNC(&msg) = (u8)(PM_FUNC_IS_PARTITION_STARTED);
+ RPC_U8(&msg, 0U) = (u8)(pt);
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+
+ result = RPC_R8(&msg);
+ if (result != 0 && result != 1) {
+ printf("%s: partition:%d res:%d\n",
+ __func__, pt, RPC_R8(&msg));
+ if (ret)
+ printf("%s: partition:%d res:%d\n", __func__, pt,
+ RPC_R8(&msg));
+ }
+ return !!result;
+}
+
/* PAD */
int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
{
@@ -146,6 +199,33 @@ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
}
/* MISC */
+int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, u32 val)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+
+ if (!dev)
+ hang();
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (u8)MISC_FUNC_SET_CONTROL;
+ RPC_U32(&msg, 0U) = (u32)ctrl;
+ RPC_U32(&msg, 4U) = (u32)val;
+ RPC_U16(&msg, 8U) = (u16)resource;
+ RPC_SIZE(&msg) = 4U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: ctrl:%d resource:%d: res:%d\n",
+ __func__, ctrl, resource, RPC_R8(&msg));
+
+ return ret;
+}
+
int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
u32 *val)
{
@@ -175,6 +255,28 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
return ret;
}
+int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_SET_MASTER_SID;
+ RPC_U16(&msg, 0U) = (u16)resource;
+ RPC_U16(&msg, 2U) = (u16)sid;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: resource:%d sid:%d: res:%d\n",
+ __func__, resource, sid, RPC_R8(&msg));
+
+ return ret;
+}
+
void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
{
struct udevice *dev = gd->arch.scu_dev;
@@ -332,6 +434,64 @@ sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
return (sc_bool_t)result;
}
+int sc_rm_find_memreg(sc_ipc_t ipc, sc_rm_mr_t *mr, sc_faddr_t addr_start,
+ sc_faddr_t addr_end)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+
+ if (!dev)
+ hang();
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = (u8)(RM_FUNC_FIND_MEMREG);
+ RPC_U32(&msg, 0U) = (u32)(addr_start >> 32ULL);
+ RPC_U32(&msg, 4U) = (u32)(addr_start);
+ RPC_U32(&msg, 8U) = (u32)(addr_end >> 32ULL);
+ RPC_U32(&msg, 12U) = (u32)(addr_end);
+ RPC_SIZE(&msg) = 5U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: start:0x%llx, end:0x%llx res:%d\n", __func__, addr_start, addr_end, RPC_R8(&msg));
+
+ if (mr)
+ *mr = RPC_U8(&msg, 0U);
+
+ return ret;
+}
+
+int sc_rm_set_memreg_permissions(sc_ipc_t ipc, sc_rm_mr_t mr,
+ sc_rm_pt_t pt, sc_rm_perm_t perm)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ int size = sizeof(struct sc_rpc_msg_s);
+ struct sc_rpc_msg_s msg;
+ int ret;
+
+ if (!dev)
+ hang();
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_RM);
+ RPC_FUNC(&msg) = (u8)(RM_FUNC_SET_MEMREG_PERMISSIONS);
+ RPC_U8(&msg, 0U) = (u8)(mr);
+ RPC_U8(&msg, 1U) = (u8)(pt);
+ RPC_U8(&msg, 2U) = (u8)(perm);
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: mr:%u, pt:%u, perm:%u, res:%d\n", __func__,
+ mr, pt, perm, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
sc_faddr_t *addr_end)
{
@@ -393,3 +553,396 @@ sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
return !!result;
}
+
+int sc_rm_partition_alloc(sc_ipc_t ipc, sc_rm_pt_t *pt, sc_bool_t secure,
+ sc_bool_t isolated, sc_bool_t restricted,
+ sc_bool_t grant, sc_bool_t coherent)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_PARTITION_ALLOC;
+ RPC_U8(&msg, 0U) = B2U8(secure);
+ RPC_U8(&msg, 1U) = B2U8(isolated);
+ RPC_U8(&msg, 2U) = B2U8(restricted);
+ RPC_U8(&msg, 3U) = B2U8(grant);
+ RPC_U8(&msg, 4U) = B2U8(coherent);
+ RPC_SIZE(&msg) = 3U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: secure:%u isolated:%u restricted:%u grant:%u coherent:%u res:%d\n",
+ __func__, secure, isolated, restricted, grant, coherent,
+ RPC_R8(&msg));
+ }
+
+ if (pt)
+ *pt = RPC_U8(&msg, 0U);
+
+ return ret;
+}
+
+int sc_rm_partition_free(sc_ipc_t ipc, sc_rm_pt_t pt)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_PARTITION_FREE;
+ RPC_U8(&msg, 0U) = (u8)pt;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: pt:%u res:%d\n",
+ __func__, pt, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+int sc_rm_get_partition(sc_ipc_t ipc, sc_rm_pt_t *pt)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_GET_PARTITION;
+ RPC_SIZE(&msg) = 1U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: res:%d\n", __func__, RPC_R8(&msg));
+
+ if (pt)
+ *pt = RPC_U8(&msg, 0U);
+
+ return ret;
+}
+
+int sc_rm_set_parent(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rm_pt_t pt_parent)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_SET_PARENT;
+ RPC_U8(&msg, 0U) = (u8)pt;
+ RPC_U8(&msg, 1U) = (u8)pt_parent;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: pt:%u, pt_parent:%u, res:%d\n",
+ __func__, pt, pt_parent, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+int sc_rm_assign_resource(sc_ipc_t ipc, sc_rm_pt_t pt, sc_rsrc_t resource)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_RESOURCE;
+ RPC_U16(&msg, 0U) = (u16)resource;
+ RPC_U8(&msg, 2U) = (u8)pt;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: pt:%u, resource:%u, res:%d\n",
+ __func__, pt, resource, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+int sc_rm_assign_pad(sc_ipc_t ipc, sc_rm_pt_t pt, sc_pad_t pad)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_ASSIGN_PAD;
+ RPC_U16(&msg, 0U) = (u16)pad;
+ RPC_U8(&msg, 2U) = (u8)pt;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: pt:%u, pad:%u, res:%d\n",
+ __func__, pt, pad, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+sc_bool_t sc_rm_is_pad_owned(sc_ipc_t ipc, sc_pad_t pad)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+ u8 result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_IS_PAD_OWNED;
+ RPC_U8(&msg, 0U) = (u8)pad;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ result = RPC_R8(&msg);
+ if (result != 0 && result != 1) {
+ printf("%s: pad:%d res:%d\n", __func__, pad, RPC_R8(&msg));
+ if (ret) {
+ printf("%s: pad:%d res:%d\n", __func__,
+ pad, RPC_R8(&msg));
+ }
+ }
+
+ return !!result;
+}
+
+int sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rm_pt_t *pt)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
+ RPC_FUNC(&msg) = (u8)RM_FUNC_GET_RESOURCE_OWNER;
+ RPC_U16(&msg, 0U) = (u16)resource;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (pt)
+ *pt = RPC_U8(&msg, 0U);
+
+ return ret;
+}
+
+int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable,
+ sc_faddr_t address)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+ RPC_FUNC(&msg) = (u8)PM_FUNC_CPU_START;
+ RPC_U32(&msg, 0U) = (u32)(address >> 32ULL);
+ RPC_U32(&msg, 4U) = (u32)address;
+ RPC_U16(&msg, 8U) = (u16)resource;
+ RPC_U8(&msg, 10U) = B2U8(enable);
+ RPC_SIZE(&msg) = 4U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: resource:%d address:0x%llx: res:%d\n",
+ __func__, resource, address, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+int sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_pm_power_mode_t *mode)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
+ RPC_FUNC(&msg) = (u8)PM_FUNC_GET_RESOURCE_POWER_MODE;
+ RPC_U16(&msg, 0U) = (u16)resource;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: resource:%d: res:%d\n",
+ __func__, resource, RPC_R8(&msg));
+ }
+
+ if (mode)
+ *mode = RPC_U8(&msg, 0U);
+
+ return ret;
+}
+
+int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd,
+ sc_faddr_t addr)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
+ RPC_FUNC(&msg) = (u8)SECO_FUNC_AUTHENTICATE;
+ RPC_U32(&msg, 0U) = (u32)(addr >> 32ULL);
+ RPC_U32(&msg, 4U) = (u32)addr;
+ RPC_U8(&msg, 8U) = (u8)cmd;
+ RPC_SIZE(&msg) = 4U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: res:%d\n", __func__, RPC_R8(&msg));
+
+ return ret;
+}
+
+int sc_seco_forward_lifecycle(sc_ipc_t ipc, u32 change)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
+ RPC_FUNC(&msg) = (u8)SECO_FUNC_FORWARD_LIFECYCLE;
+ RPC_U32(&msg, 0U) = (u32)change;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: change:%u, res:%d\n", __func__,
+ change, RPC_R8(&msg));
+ }
+
+ return ret;
+}
+
+int sc_seco_chip_info(sc_ipc_t ipc, u16 *lc, u16 *monotonic, u32 *uid_l,
+ u32 *uid_h)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
+ RPC_FUNC(&msg) = (u8)SECO_FUNC_CHIP_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: res:%d\n", __func__, RPC_R8(&msg));
+
+ if (uid_l)
+ *uid_l = RPC_U32(&msg, 0U);
+
+ if (uid_h)
+ *uid_h = RPC_U32(&msg, 4U);
+
+ if (lc)
+ *lc = RPC_U16(&msg, 8U);
+
+ if (monotonic)
+ *monotonic = RPC_U16(&msg, 10U);
+
+ return ret;
+}
+
+void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO);
+ RPC_FUNC(&msg) = (u8)(SECO_FUNC_BUILD_INFO);
+ RPC_SIZE(&msg) = 1U;
+
+ misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+
+ if (version)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
+ RPC_FUNC(&msg) = (u8)SECO_FUNC_GET_EVENT;
+ RPC_U8(&msg, 0U) = (u8)idx;
+ RPC_SIZE(&msg) = 2U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret)
+ printf("%s: idx: %u, res:%d\n", __func__, idx, RPC_R8(&msg));
+
+ if (event)
+ *event = RPC_U32(&msg, 0U);
+
+ return ret;
+}
+
+int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr,
+ sc_faddr_t export_addr, u16 max_size)
+{
+ struct udevice *dev = gd->arch.scu_dev;
+ struct sc_rpc_msg_s msg;
+ int size = sizeof(struct sc_rpc_msg_s);
+ int ret;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (u8)SC_RPC_SVC_SECO;
+ RPC_FUNC(&msg) = (u8)SECO_FUNC_GEN_KEY_BLOB;
+ RPC_U32(&msg, 0U) = (u32)(load_addr >> 32ULL);
+ RPC_U32(&msg, 4U) = (u32)load_addr;
+ RPC_U32(&msg, 8U) = (u32)(export_addr >> 32ULL);
+ RPC_U32(&msg, 12U) = (u32)export_addr;
+ RPC_U32(&msg, 16U) = (u32)id;
+ RPC_U16(&msg, 20U) = (u16)max_size;
+ RPC_SIZE(&msg) = 7U;
+
+ ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
+ if (ret) {
+ printf("%s: id: %u, load_addr 0x%llx, export_addr 0x%llx, res:%d\n",
+ __func__, id, load_addr, export_addr, RPC_R8(&msg));
+ }
+
+ return ret;
+}