Skip to content

Commit de59869

Browse files
arnopomathieupoirier
authored andcommitted
remoteproc: stm32: Allow hold boot management by the SCMI reset controller
The hold boot can be managed by the SCMI controller as a reset. If the "hold_boot" reset is defined in the device tree, use it. Else use the syscon controller directly to access to the register. The support of the SMC call is deprecated but kept for legacy support. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> Link: https://lore.kernel.org/r/20230512093926.661509-3-arnaud.pouliquen@foss.st.com
1 parent ef7129d commit de59869

1 file changed

Lines changed: 55 additions & 21 deletions

File tree

drivers/remoteproc/stm32_rproc.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct stm32_mbox {
7979

8080
struct stm32_rproc {
8181
struct reset_control *rst;
82+
struct reset_control *hold_boot_rst;
8283
struct stm32_syscon hold_boot;
8384
struct stm32_syscon pdds;
8485
struct stm32_syscon m4_state;
@@ -88,7 +89,7 @@ struct stm32_rproc {
8889
struct stm32_rproc_mem *rmems;
8990
struct stm32_mbox mb[MBOX_NB_MBX];
9091
struct workqueue_struct *workqueue;
91-
bool secured_soc;
92+
bool hold_boot_smc;
9293
void __iomem *rsc_va;
9394
};
9495

@@ -413,13 +414,28 @@ static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold)
413414
struct arm_smccc_res smc_res;
414415
int val, err;
415416

417+
/*
418+
* Three ways to manage the hold boot
419+
* - using SCMI: the hold boot is managed as a reset,
420+
* - using Linux(no SCMI): the hold boot is managed as a syscon register
421+
* - using SMC call (deprecated): use SMC reset interface
422+
*/
423+
416424
val = hold ? HOLD_BOOT : RELEASE_BOOT;
417425

418-
if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ddata->secured_soc) {
426+
if (ddata->hold_boot_rst) {
427+
/* Use the SCMI reset controller */
428+
if (!hold)
429+
err = reset_control_deassert(ddata->hold_boot_rst);
430+
else
431+
err = reset_control_assert(ddata->hold_boot_rst);
432+
} else if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ddata->hold_boot_smc) {
433+
/* Use the SMC call */
419434
arm_smccc_smc(STM32_SMC_RCC, STM32_SMC_REG_WRITE,
420435
hold_boot.reg, val, 0, 0, 0, 0, &smc_res);
421436
err = smc_res.a0;
422437
} else {
438+
/* Use syscon */
423439
err = regmap_update_bits(hold_boot.map, hold_boot.reg,
424440
hold_boot.mask, val);
425441
}
@@ -717,34 +733,52 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
717733
dev_info(dev, "wdg irq registered\n");
718734
}
719735

720-
ddata->rst = devm_reset_control_get_by_index(dev, 0);
736+
ddata->rst = devm_reset_control_get_optional(dev, "mcu_rst");
737+
if (!ddata->rst) {
738+
/* Try legacy fallback method: get it by index */
739+
ddata->rst = devm_reset_control_get_by_index(dev, 0);
740+
}
721741
if (IS_ERR(ddata->rst))
722742
return dev_err_probe(dev, PTR_ERR(ddata->rst),
723743
"failed to get mcu_reset\n");
724744

725745
/*
726-
* if platform is secured the hold boot bit must be written by
727-
* smc call and read normally.
728-
* if not secure the hold boot bit could be read/write normally
746+
* Three ways to manage the hold boot
747+
* - using SCMI: the hold boot is managed as a reset
748+
* The DT "reset-mames" property should be defined with 2 items:
749+
* reset-names = "mcu_rst", "hold_boot";
750+
* - using SMC call (deprecated): use SMC reset interface
751+
* The DT "reset-mames" property is optional, "st,syscfg-tz" is required
752+
* - default(no SCMI, no SMC): the hold boot is managed as a syscon register
753+
* The DT "reset-mames" property is optional, "st,syscfg-holdboot" is required
729754
*/
730-
err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz);
731-
if (err) {
732-
dev_err(dev, "failed to get tz syscfg\n");
733-
return err;
734-
}
735755

736-
err = regmap_read(tz.map, tz.reg, &tzen);
737-
if (err) {
738-
dev_err(dev, "failed to read tzen\n");
739-
return err;
756+
ddata->hold_boot_rst = devm_reset_control_get_optional(dev, "hold_boot");
757+
if (IS_ERR(ddata->hold_boot_rst))
758+
return dev_err_probe(dev, PTR_ERR(ddata->rst),
759+
"failed to get hold_boot reset\n");
760+
761+
if (!ddata->hold_boot_rst && IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)) {
762+
/* Manage the MCU_BOOT using SMC call */
763+
err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz);
764+
if (!err) {
765+
err = regmap_read(tz.map, tz.reg, &tzen);
766+
if (err) {
767+
dev_err(dev, "failed to read tzen\n");
768+
return err;
769+
}
770+
ddata->hold_boot_smc = tzen & tz.mask;
771+
}
740772
}
741-
ddata->secured_soc = tzen & tz.mask;
742773

743-
err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot",
744-
&ddata->hold_boot);
745-
if (err) {
746-
dev_err(dev, "failed to get hold boot\n");
747-
return err;
774+
if (!ddata->hold_boot_rst && !ddata->hold_boot_smc) {
775+
/* Default: hold boot manage it through the syscon controller */
776+
err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot",
777+
&ddata->hold_boot);
778+
if (err) {
779+
dev_err(dev, "failed to get hold boot\n");
780+
return err;
781+
}
748782
}
749783

750784
err = stm32_rproc_get_syscon(np, "st,syscfg-pdds", &ddata->pdds);

0 commit comments

Comments
 (0)