
Now we have to use UCLASS_SM driver instead of raw smc_call() function call.
Signed-off-by: Alexey Romanov avromanov@salutedevices.com --- 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..0c60aa8695 100644 --- a/arch/arm/mach-meson/sm.c +++ b/arch/arm/mach-meson/sm.c @@ -9,6 +9,7 @@ #include <dm.h> #include <log.h> #include <regmap.h> +#include <sm.h> #include <syscon.h> #include <asm/arch/sm.h> #include <asm/cache.h> @@ -18,70 +19,62 @@ #include <linux/err.h> #include <linux/kernel.h> #include <linux/bitfield.h> +#include <meson/sm.h>
-#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_get_device_by_name(UCLASS_SM, "secure-monitor", &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; }