From 7cd53e0d5203f8e25bb69d2e675769888fcbc754 Mon Sep 17 00:00:00 2001 From: Alexey Romanov Date: Thu, 21 Sep 2023 11:13:41 +0300 Subject: [PATCH] arch: meson: use secure monitor driver Now we have to use UCLASS_SM driver instead of raw smc_call() function call. Signed-off-by: Alexey Romanov Reviewed-by: Simon Glass Link: https://lore.kernel.org/r/20230921081346.22157-9-avromanov@salutedevices.com Signed-off-by: Neil Armstrong --- arch/arm/mach-meson/Kconfig | 1 + arch/arm/mach-meson/sm.c | 110 +++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 53 deletions(-) diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index 669ca09a00..d6c8905806 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig @@ -11,6 +11,7 @@ config MESON64_COMMON select PWRSEQ select MMC_PWRSEQ select BOARD_LATE_INIT + select MESON_SM imply CMD_DM config MESON_GX diff --git a/arch/arm/mach-meson/sm.c b/arch/arm/mach-meson/sm.c index b5dd6c6d39..914fd11c98 100644 --- a/arch/arm/mach-meson/sm.c +++ b/arch/arm/mach-meson/sm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,70 +19,62 @@ #include #include #include +#include -#define FN_GET_SHARE_MEM_INPUT_BASE 0x82000020 -#define FN_GET_SHARE_MEM_OUTPUT_BASE 0x82000021 -#define FN_EFUSE_READ 0x82000030 -#define FN_EFUSE_WRITE 0x82000031 -#define FN_CHIP_ID 0x82000044 -#define FN_PWRDM_SET 0x82000093 - -static void *shmem_input; -static void *shmem_output; - -static void meson_init_shmem(void) +static inline struct udevice *meson_get_sm_device(void) { - struct pt_regs regs; - - if (shmem_input && shmem_output) - return; + struct udevice *dev; + int err; - regs.regs[0] = FN_GET_SHARE_MEM_INPUT_BASE; - smc_call(®s); - shmem_input = (void *)regs.regs[0]; - - regs.regs[0] = FN_GET_SHARE_MEM_OUTPUT_BASE; - smc_call(®s); - shmem_output = (void *)regs.regs[0]; + err = uclass_first_device_err(UCLASS_SM, &dev); + if (err) { + pr_err("Mesom SM device not found\n"); + return ERR_PTR(err); + } - debug("Secure Monitor shmem: 0x%p 0x%p\n", shmem_input, shmem_output); + return dev; } ssize_t meson_sm_read_efuse(uintptr_t offset, void *buffer, size_t size) { - struct pt_regs regs; + struct udevice *dev; + struct pt_regs regs = { 0 }; + int err; - meson_init_shmem(); + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); - regs.regs[0] = FN_EFUSE_READ; regs.regs[1] = offset; regs.regs[2] = size; - smc_call(®s); + err = sm_call_read(dev, buffer, size, + MESON_SMC_CMD_EFUSE_READ, ®s); + if (err < 0) + pr_err("Failed to read efuse memory (%d)\n", err); - if (regs.regs[0] == 0) - return -1; - - memcpy(buffer, shmem_output, min(size, regs.regs[0])); - - return regs.regs[0]; + return err; } ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, size_t size) { - struct pt_regs regs; - - meson_init_shmem(); + struct udevice *dev; + struct pt_regs regs = { 0 }; + int err; - memcpy(shmem_input, buffer, size); + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); - regs.regs[0] = FN_EFUSE_WRITE; regs.regs[1] = offset; regs.regs[2] = size; - smc_call(®s); + err = sm_call_write(dev, buffer, size, + MESON_SMC_CMD_EFUSE_WRITE, ®s); + if (err < 0) + pr_err("Failed to write efuse memory (%d)\n", err); - return regs.regs[0]; + return err; } #define SM_CHIP_ID_LENGTH 119 @@ -90,18 +83,21 @@ ssize_t meson_sm_write_efuse(uintptr_t offset, void *buffer, size_t size) int meson_sm_get_serial(void *buffer, size_t size) { - struct pt_regs regs; + struct udevice *dev; + struct pt_regs regs = { 0 }; + u8 id_buffer[SM_CHIP_ID_LENGTH]; + int err; - meson_init_shmem(); + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); - regs.regs[0] = FN_CHIP_ID; - regs.regs[1] = 0; - regs.regs[2] = 0; + err = sm_call_read(dev, id_buffer, SM_CHIP_ID_LENGTH, + MESON_SMC_CMD_CHIP_ID_GET, ®s); + if (err < 0) + pr_err("Failed to read serial number (%d)\n", err); - smc_call(®s); - - memcpy(buffer, shmem_output + SM_CHIP_ID_OFFSET, - min_t(size_t, size, SM_CHIP_ID_SIZE)); + memcpy(buffer, id_buffer + SM_CHIP_ID_OFFSET, size); return 0; } @@ -141,13 +137,21 @@ int meson_sm_get_reboot_reason(void) int meson_sm_pwrdm_set(size_t index, int cmd) { - struct pt_regs regs; + struct udevice *dev; + struct pt_regs regs = { 0 }; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); - regs.regs[0] = FN_PWRDM_SET; regs.regs[1] = index; regs.regs[2] = cmd; - smc_call(®s); + err = sm_call(dev, MESON_SMC_CMD_PWRDM_SET, NULL, ®s); + if (err) + pr_err("Failed to %s power domain ind=%zu (%d)\n", cmd == PWRDM_ON ? + "enable" : "disable", index, err); - return regs.regs[0]; + return err; } -- 2.39.5