Message ID | 20230911163536.20735-9-avromanov@salutedevices.com |
---|---|
State | Superseded |
Delegated to: | Neil Armstrong |
Headers | show |
Series | Add SM uclass and Meson SM driver | expand |
Hi Alexey, On Mon, 11 Sept 2023 at 10:35, Alexey Romanov <avromanov@salutedevices.com> wrote: > > 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(-) Reviewed-by: Simon Glass <sjg@chromium.org> with fix below > > 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); Can you use uclass_first_device_err(UCLASS_SM, ... instead? We should not be looking up devices by name. > + 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.25.1 > Regards, Simon
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; }
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(-)