ARM: AM33xx: PRM: Implement REBOOT_COLD
authorAlexander Sverdlin <alexander.sverdlin@siemens.com>
Wed, 21 Feb 2024 15:45:51 +0000 (16:45 +0100)
committerTony Lindgren <tony@atomide.com>
Wed, 28 Feb 2024 07:33:03 +0000 (09:33 +0200)
Historically AM33xx performed warm software reset even though requested
(and default) was REBOOT_COLD. Reflect the de-facto default mode in
/sys/kernel/reboot/mode correctly and implement the real REBOOT_COLD
(if configured explicitly).

Tested-by: Matthias Michel <matthias.michel@siemens.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Message-ID: <20240221154614.3549951-2-alexander.sverdlin@siemens.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/am33xx-restart.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/prm-regbits-33xx.h
arch/arm/mach-omap2/prm.h
arch/arm/mach-omap2/prm33xx.c
arch/arm/mach-omap2/prm_common.c

index bf6419d33565ad4e2e829a952f6bac2d7b5ddeb1..fcf3d557aa7866415dd6c4a23f7db7f230e56bf8 100644 (file)
@@ -18,7 +18,8 @@
  */
 void am33xx_restart(enum reboot_mode mode, const char *cmd)
 {
-       /* TODO: Handle mode and cmd if necessary */
+       /* TODO: Handle cmd if necessary */
+       prm_reboot_mode = mode;
 
        omap_prm_reset_system();
 }
index fde6ccb3df6ebbf10ad2cd728a81ccf98dc8594d..68e0baad2bbf62753edea18630cbd73286bd28ab 100644 (file)
@@ -246,6 +246,12 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
        .init_time      = omap_init_time_of,
        .dt_compat      = am33xx_boards_compat,
        .restart        = am33xx_restart,
+       /*
+        * Historically am33xx supported only REBOOT_WARM even though default
+        * reboot_mode was REBOOT_COLD. Reflect legacy de-facto behaviour in
+        * SYSFS.
+        */
+       .reboot_mode    = REBOOT_WARM,
 MACHINE_END
 #endif
 
index 3748c5266ae128960d8b9af912ec30835674b01f..9b97f8c76cd17114c5414fd05e1c0eead41494bc 100644 (file)
@@ -15,6 +15,7 @@
 #define AM33XX_GFX_MEM_STATEST_MASK                    (0x3 << 4)
 #define AM33XX_GLOBAL_WARM_SW_RST_MASK                 (1 << 1)
 #define AM33XX_RST_GLOBAL_WARM_SW_MASK                 (1 << 0)
+#define AM33XX_RST_GLOBAL_COLD_SW_MASK                 (1 << 1)
 #define AM33XX_PRUSS_MEM_ONSTATE_MASK                  (0x3 << 5)
 #define AM33XX_PRUSS_MEM_RETSTATE_MASK                 (1 << 7)
 #define AM33XX_PRUSS_MEM_STATEST_MASK                  (0x3 << 23)
index fc45a7ed09bb37cdc588d90b99f309ffa322703f..fc53a27eed01345cc8b3b775569fa47c5d787dfa 100644 (file)
@@ -15,6 +15,7 @@
 # ifndef __ASSEMBLER__
 extern struct omap_domain_base prm_base;
 extern u16 prm_features;
+extern enum reboot_mode prm_reboot_mode;
 int omap_prcm_init(void);
 int omap2_prcm_base_init(void);
 # endif
index 4a462310a4b097d2677bdedc57a648d7099ea351..505d685d6792efb9ffa7303be4a6ddae18f5f276 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include "powerdomain.h"
 #include "prm33xx.h"
@@ -318,10 +319,19 @@ static int am33xx_check_vcvp(void)
  *
  * Immediately reboots the device through warm reset.
  */
-static void am33xx_prm_global_warm_sw_reset(void)
+static void am33xx_prm_global_sw_reset(void)
 {
-       am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
-                               AM33XX_RST_GLOBAL_WARM_SW_MASK,
+       /*
+        * Historically AM33xx performed warm reset for all requested reboot_mode.
+        * Keep this behaviour unchanged for all except newly added REBOOT_COLD.
+        */
+       u32 mask = AM33XX_RST_GLOBAL_WARM_SW_MASK;
+
+       if (prm_reboot_mode == REBOOT_COLD)
+               mask = AM33XX_RST_GLOBAL_COLD_SW_MASK;
+
+       am33xx_prm_rmw_reg_bits(mask,
+                               mask,
                                AM33XX_PRM_DEVICE_MOD,
                                AM33XX_PRM_RSTCTRL_OFFSET);
 
@@ -382,7 +392,7 @@ static struct prm_ll_data am33xx_prm_ll_data = {
        .assert_hardreset               = am33xx_prm_assert_hardreset,
        .deassert_hardreset             = am33xx_prm_deassert_hardreset,
        .is_hardreset_asserted          = am33xx_prm_is_hardreset_asserted,
-       .reset_system                   = am33xx_prm_global_warm_sw_reset,
+       .reset_system                   = am33xx_prm_global_sw_reset,
 };
 
 int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
index 3e1e5198bebf7977b7f5f81d3802fa6a83714c5a..ee4588acda503c99b5dd3debb3dfdb2abb9c3dc0 100644 (file)
@@ -66,6 +66,12 @@ struct omap_domain_base prm_base;
 
 u16 prm_features;
 
+/*
+ * Platforms that implement different reboot modes can store the requested
+ * mode here.
+ */
+enum reboot_mode prm_reboot_mode;
+
 /*
  * prm_ll_data: function pointers to SoC-specific implementations of
  * common PRM functions