Now we have to use UCLASS_FIRMWARE meson secure monitor driver instead of raw smc_call() function call.
Signed-off-by: Alexey Romanov <avroma...@sberdevices.ru> --- arch/arm/mach-meson/sm.c | 161 +++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 64 deletions(-) diff --git a/arch/arm/mach-meson/sm.c b/arch/arm/mach-meson/sm.c index d600c64d0be..347ff448f79 100644 --- a/arch/arm/mach-meson/sm.c +++ b/arch/arm/mach-meson/sm.c @@ -16,72 +16,74 @@ #include <linux/kernel.h> #include <dm.h> #include <linux/bitfield.h> +#include <meson/sm_handle.h> #include <regmap.h> #include <syscon.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_FIRMWARE, "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; - - meson_init_shmem(); - - regs.regs[0] = FN_EFUSE_READ; - regs.regs[1] = offset; - regs.regs[2] = size; - - smc_call(®s); - - if (regs.regs[0] == 0) - return -1; + struct meson_sm_handle *handle; + struct udevice *dev; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + handle = meson_sm_get_handle(dev); + if (IS_ERR(handle)) { + pr_err("Failed to get Meson SM handle\n"); + return PTR_ERR(handle); + } - memcpy(buffer, shmem_output, min(size, regs.regs[0])); + err = handle->ops.sm_call_read(dev, buffer, size, + MESON_SMC_CMD_EFUSE_READ, offset, size); + if (err < 0) { + pr_err("Failed to read efuse memory (%d)\n", err); + return err; + } - 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(); - - memcpy(shmem_input, buffer, size); - - regs.regs[0] = FN_EFUSE_WRITE; - regs.regs[1] = offset; - regs.regs[2] = size; + struct meson_sm_handle *handle; + struct udevice *dev; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + handle = meson_sm_get_handle(dev); + if (IS_ERR(handle)) { + pr_err("Failed to get Meson SM handle\n"); + return PTR_ERR(handle); + } - smc_call(®s); + err = handle->ops.sm_call_write(dev, buffer, size, + MESON_SMC_CMD_EFUSE_WRITE, offset, size); + if (err < 0) { + pr_err("Failed to write efuse memory (%d)\n", err); + return err; + } - return regs.regs[0]; + return err; } #define SM_CHIP_ID_LENGTH 119 @@ -90,18 +92,35 @@ 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; - - meson_init_shmem(); + struct meson_sm_handle *handle; + struct udevice *dev; + u8 *id_buffer; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + handle = meson_sm_get_handle(dev); + if (IS_ERR(handle)) { + pr_err("Failed to get Meson SM handle\n"); + return PTR_ERR(handle); + } - regs.regs[0] = FN_CHIP_ID; - regs.regs[1] = 0; - regs.regs[2] = 0; + id_buffer = malloc(sizeof(u8) * SM_CHIP_ID_LENGTH); + if (!id_buffer) + return -ENOMEM; - smc_call(®s); + err = handle->ops.sm_call_read(dev, id_buffer, SM_CHIP_ID_LENGTH, + MESON_SMC_CMD_CHIP_ID_GET, 0, 0); + if (err < 0) { + pr_err("Failed to read serial number (%d)\n", err); + free(id_buffer); + return err; + } - 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); + free(id_buffer); return 0; } @@ -141,13 +160,27 @@ int meson_sm_get_reboot_reason(void) int meson_sm_pwrdm_set(size_t index, int cmd) { - struct pt_regs regs; - - regs.regs[0] = FN_PWRDM_SET; - regs.regs[1] = index; - regs.regs[2] = cmd; + struct meson_sm_handle *handle; + struct udevice *dev; + int err; + + dev = meson_get_sm_device(); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + handle = meson_sm_get_handle(dev); + if (IS_ERR(handle)) { + pr_err("Failed to get Meson SM handle\n"); + return PTR_ERR(handle); + } - smc_call(®s); + err = handle->ops.sm_call(dev, MESON_SMC_CMD_PWRDM_SET, NULL, + index, cmd, 0, 0, 0); + if (err) { + pr_err("Failed to %s power domain ind=%zu (%d)\n", cmd == PWRDM_ON ? + "enable" : "disable", index, err); + return err; + } - return regs.regs[0]; + return 0; } -- 2.38.1