Skip to contentSkip to conversation

ARM: OMAP2+: PRM: Fix am437x module reset

PATCH New Dave Gerlach 5 participants 5 messages May 1, 2015 – May 8, 2015

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM: OMAP2+: PRM: Fix am437x module reset

When moving to using the OMAP4+ PRM driver on am437x, we switched to using all omap4 ops for module reset management. However, reset register layout on am437x is more similar to am335x than omap4 because of the the need for an st_shift for the *_RST bits in certain *_RSTST registers, like WKUP_PROC_LRST in the PRCM_RM_WKUP_RSTST. Without this we cannot bring the Wakeup M3 IP out of reset.

Because of this, we must use the am33xx prm ops for the hardreset functionality while continuing to use all other omap4 ops. To accomplish this we split out the common portion of omap44xx_prm_init and add an am437x_prm_init to register the prm_ll_data struct specific to am437x.

---
 arch/arm/mach-omap2/omap_hwmod.c   |  6 +++---
 arch/arm/mach-omap2/prm33xx.c      | 14 +++++++-------
 arch/arm/mach-omap2/prm33xx.h      |  7 +++++++
 arch/arm/mach-omap2/prm44xx.c      | 32 +++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/prm44xx_54xx.h |  1 +
 arch/arm/mach-omap2/prm_common.c   |  2 +-
 6 files changed, 50 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +3 -3
index 982380b..4b13882 100644
@@ -3924,9 +3924,9 @@ void __init omap_hwmod_init(void)
 		soc_ops.enable_module = _omap4_enable_module;
 		soc_ops.disable_module = _omap4_disable_module;
 		soc_ops.wait_target_ready = _omap4_wait_target_ready;
-		soc_ops.assert_hardreset = _omap4_assert_hardreset;
-		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
-		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+		soc_ops.assert_hardreset = _am33xx_assert_hardreset;
+		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
+		soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
 		soc_ops.init_clkdm = _init_clkdm;
 	} else if (cpu_is_ti816x() || soc_is_am33xx()) {
 		soc_ops.enable_module = _omap4_enable_module;
arch/arm/mach-omap2/prm33xx.c +7 -7
index dcb5001..0a43bfe 100644
@@ -64,8 +64,8 @@ static u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
  * 0 if the (sub)module hardreset line is not currently asserted, or
  * -EINVAL upon parameter error.
  */
-static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
-					    u16 rstctrl_offs)
+int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+				     u16 rstctrl_offs)
 {
 	u32 v;
 
@@ -90,8 +90,8 @@ static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
  * place the submodule into reset.  Returns 0 upon success or -EINVAL
  * upon an argument error.
  */
-static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
-				       u16 rstctrl_offs)
+int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
+				u16 rstctrl_offs)
 {
 	u32 mask = 1 << shift;
 
@@ -119,9 +119,9 @@ static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
  * -EINVAL upon an argument error, -EEXIST if the submodule was already out
  * of reset, or -EBUSY if the submodule did not exit reset promptly.
  */
-static int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
-					 s16 inst, u16 rstctrl_offs,
-					 u16 rstst_offs)
+int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
+				  s16 inst, u16 rstctrl_offs,
+				  u16 rstst_offs)
 {
 	int c;
 	u32 mask = 1 << st_shift;
arch/arm/mach-omap2/prm33xx.h +7 -0
index 2bc4ec5..2754e9f 100644
@@ -120,5 +120,12 @@
 #ifndef __ASSEMBLER__
 int am33xx_prm_init(const struct omap_prcm_init_data *data);
 
+int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
+				     u16 rstctrl_offs);
+int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
+				u16 rstctrl_offs);
+int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
+				  s16 inst, u16 rstctrl_offs,
+				  u16 rstst_offs);
 #endif /* ASSEMBLER */
 #endif
arch/arm/mach-omap2/prm44xx.c +31 -1
index 4541700..3fc6971 100644
@@ -24,6 +24,7 @@
 #include "iomap.h"
 #include "common.h"
 #include "vp.h"
+#include "prm33xx.h"
 #include "prm44xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
@@ -705,7 +706,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 
 static const struct omap_prcm_init_data *prm_init_data;
 
-int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+static void omap44xx_prm_init_common(const struct omap_prcm_init_data *data)
 {
 	omap_prm_base_init();
 
@@ -718,7 +719,11 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
 		prm_features |= PRM_HAS_VOLTAGE;
 
 	omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
+}
 
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+{
+	omap44xx_prm_init_common(data);
 	return prm_register(&omap44xx_prm_ll_data);
 }
 
@@ -762,3 +767,28 @@ static void __exit omap44xx_prm_exit(void)
 	prm_unregister(&omap44xx_prm_ll_data);
 }
 __exitcall(omap44xx_prm_exit);
+
+#ifdef CONFIG_SOC_AM43XX
+static struct prm_ll_data am43xx_prm_ll_data = {
+	.read_reset_sources = &omap44xx_prm_read_reset_sources,
+	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
+	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+	.late_init = &omap44xx_prm_late_init,
+	.assert_hardreset	= am33xx_prm_assert_hardreset,
+	.deassert_hardreset	= am33xx_prm_deassert_hardreset,
+	.is_hardreset_asserted	= am33xx_prm_is_hardreset_asserted,
+	.reset_system		= omap4_prminst_global_warm_sw_reset,
+};
+
+int __init am43xx_prm_init(const struct omap_prcm_init_data *data)
+{
+	omap44xx_prm_init_common(data);
+	return prm_register(&am43xx_prm_ll_data);
+}
+
+static void __exit am43xx_prm_exit(void)
+{
+	prm_unregister(&am43xx_prm_ll_data);
+}
+__exitcall(am43xx_prm_exit);
+#endif /* CONFIG_SOC_AM43XX */
arch/arm/mach-omap2/prm44xx_54xx.h +1 -0
index 3f139eb..3e90d6a 100644
@@ -36,6 +36,7 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
+int __init am43xx_prm_init(const struct omap_prcm_init_data *data);
 int __init omap44xx_prm_init(const struct omap_prcm_init_data *data);
 
 #endif
arch/arm/mach-omap2/prm_common.c +1 -1
index 7add799..730fd24 100644
@@ -694,7 +694,7 @@ static struct omap_prcm_init_data dra7_prm_data __initdata = {
 #ifdef CONFIG_SOC_AM43XX
 static struct omap_prcm_init_data am4_prm_data __initdata = {
 	.index = TI_CLKM_PRM,
-	.init = omap44xx_prm_init,
+	.init = am43xx_prm_init,
 	.device_inst_offset = AM43XX_PRM_DEVICE_INST,
 };
 #endif
Signature · 1 line
2.3.6
maintainer
#1 lore raw

PATCH 1/1 ARM: OMAP2+: PRM: Fix am437x module reset

Quoted 30 lines · Dave Gerlach

When moving to using the OMAP4+ PRM driver on am437x, we switched to using all omap4 ops for module reset management. However, reset register layout on am437x is more similar to am335x than omap4 because of the the need for an st_shift for the *_RST bits in certain *_RSTST registers, like WKUP_PROC_LRST in the PRCM_RM_WKUP_RSTST. Without this we cannot bring the Wakeup M3 IP out of reset.

Because of this, we must use the am33xx prm ops for the hardreset functionality while continuing to use all other omap4 ops. To accomplish this we split out the common portion of omap44xx_prm_init and add an am437x_prm_init to register the prm_ll_data struct specific to am437x.

---
 arch/arm/mach-omap2/omap_hwmod.c   |  6 +++---
 arch/arm/mach-omap2/prm33xx.c      | 14 +++++++-------
 arch/arm/mach-omap2/prm33xx.h      |  7 +++++++
 arch/arm/mach-omap2/prm44xx.c      | 32 +++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/prm44xx_54xx.h |  1 +
 arch/arm/mach-omap2/prm_common.c   |  2 +-
 6 files changed, 50 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +0 -0
index 982380b..4b13882 100644
@@ -3924,9 +3924,9 @@ void __init omap_hwmod_init(void)
 		soc_ops.enable_module = _omap4_enable_module;
 		soc_ops.disable_module = _omap4_disable_module;

arch/arm/mach-omap2/omap_hwmod.c void __init omap_hwmod_init(void) · line 3932

Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +3 -3
 		soc_ops.wait_target_ready = _omap4_wait_target_ready;
-		soc_ops.assert_hardreset = _omap4_assert_hardreset;
-		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
-		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+		soc_ops.assert_hardreset = _am33xx_assert_hardreset;
+		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
+		soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
 		soc_ops.init_clkdm = _init_clkdm;
 	} else if (cpu_is_ti816x() || soc_is_am33xx()) {
 		soc_ops.enable_module = _omap4_enable_module;

Can't the above just become then:

		...
	} else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
		...
	} else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
		...
	}
Quoted 49 lines
arch/arm/mach-omap2/prm44xx.c +20 -1
@@ -24,6 +24,7 @@
 #include "iomap.h"
 #include "common.h"
 #include "vp.h"
+#include "prm33xx.h"
 #include "prm44xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
@@ -705,7 +706,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 
 static const struct omap_prcm_init_data *prm_init_data;
 
-int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+static void omap44xx_prm_init_common(const struct omap_prcm_init_data *data)
 {
 	omap_prm_base_init();
 
@@ -718,7 +719,11 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
 		prm_features |= PRM_HAS_VOLTAGE;
 
 	omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
+}
 
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+{
+	omap44xx_prm_init_common(data);
 	return prm_register(&omap44xx_prm_ll_data);
 }
 
@@ -762,3 +767,28 @@ static void __exit omap44xx_prm_exit(void)
 	prm_unregister(&omap44xx_prm_ll_data);
 }
 __exitcall(omap44xx_prm_exit);
+
+#ifdef CONFIG_SOC_AM43XX
+static struct prm_ll_data am43xx_prm_ll_data = {
+	.read_reset_sources = &omap44xx_prm_read_reset_sources,
+	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
+	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+	.late_init = &omap44xx_prm_late_init,
+	.assert_hardreset	= am33xx_prm_assert_hardreset,
+	.deassert_hardreset	= am33xx_prm_deassert_hardreset,
+	.is_hardreset_asserted	= am33xx_prm_is_hardreset_asserted,
+	.reset_system		= omap4_prminst_global_warm_sw_reset,
+};
+
+int __init am43xx_prm_init(const struct omap_prcm_init_data *data)

arch/arm/mach-omap2/prm44xx.c static void __exit omap44xx_prm_exit(void) · line 793

Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10 -0
+{
+	omap44xx_prm_init_common(data);
+	return prm_register(&am43xx_prm_ll_data);
+}
+
+static void __exit am43xx_prm_exit(void)
+{
+	prm_unregister(&am43xx_prm_ll_data);
+}
+__exitcall(am43xx_prm_exit);

I think you can similarly just move this to use prm33xx.c instead of prm44xx.c and keep the functions static that way?

Regards,

Tony

#2 lore raw

PATCH 1/1 ARM: OMAP2+: PRM: Fix am437x module reset

Quoted 105 lines · Tony Lindgren
Quoted 30 lines · Dave Gerlach

When moving to using the OMAP4+ PRM driver on am437x, we switched to using all omap4 ops for module reset management. However, reset register layout on am437x is more similar to am335x than omap4 because of the the need for an st_shift for the *_RST bits in certain *_RSTST registers, like WKUP_PROC_LRST in the PRCM_RM_WKUP_RSTST. Without this we cannot bring the Wakeup M3 IP out of reset.

Because of this, we must use the am33xx prm ops for the hardreset functionality while continuing to use all other omap4 ops. To accomplish this we split out the common portion of omap44xx_prm_init and add an am437x_prm_init to register the prm_ll_data struct specific to am437x.

---
  arch/arm/mach-omap2/omap_hwmod.c   |  6 +++---
  arch/arm/mach-omap2/prm33xx.c      | 14 +++++++-------
  arch/arm/mach-omap2/prm33xx.h      |  7 +++++++
  arch/arm/mach-omap2/prm44xx.c      | 32 +++++++++++++++++++++++++++++++-
  arch/arm/mach-omap2/prm44xx_54xx.h |  1 +
  arch/arm/mach-omap2/prm_common.c   |  2 +-
  6 files changed, 50 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +0 -0
index 982380b..4b13882 100644
@@ -3924,9 +3924,9 @@ void __init omap_hwmod_init(void)
  		soc_ops.enable_module = _omap4_enable_module;
  		soc_ops.disable_module = _omap4_disable_module;

arch/arm/mach-omap2/omap_hwmod.c void __init omap_hwmod_init(void) · line 3932

Quoted 10 lines
arch/arm/mach-omap2/omap_hwmod.c +3 -3
  		soc_ops.wait_target_ready = _omap4_wait_target_ready;
-		soc_ops.assert_hardreset = _omap4_assert_hardreset;
-		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
-		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
+		soc_ops.assert_hardreset = _am33xx_assert_hardreset;
+		soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
+		soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
  		soc_ops.init_clkdm = _init_clkdm;
  	} else if (cpu_is_ti816x() || soc_is_am33xx()) {
  		soc_ops.enable_module = _omap4_enable_module;

Can't the above just become then:

		...
	} else if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
		...
	} else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
		...
	}
Quoted 54 lines
arch/arm/mach-omap2/prm44xx.c +25 -1
@@ -24,6 +24,7 @@
  #include "iomap.h"
  #include "common.h"
  #include "vp.h"
+#include "prm33xx.h"
  #include "prm44xx.h"
  #include "prm-regbits-44xx.h"
  #include "prcm44xx.h"
@@ -705,7 +706,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 
  static const struct omap_prcm_init_data *prm_init_data;
 
-int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+static void omap44xx_prm_init_common(const struct omap_prcm_init_data *data)
  {
  	omap_prm_base_init();
 
@@ -718,7 +719,11 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
  		prm_features |= PRM_HAS_VOLTAGE;
 
  	omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
+}
 
+int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
+{
+	omap44xx_prm_init_common(data);
  	return prm_register(&omap44xx_prm_ll_data);
  }
 
@@ -762,3 +767,28 @@ static void __exit omap44xx_prm_exit(void)
  	prm_unregister(&omap44xx_prm_ll_data);
  }
  __exitcall(omap44xx_prm_exit);
+
+#ifdef CONFIG_SOC_AM43XX
+static struct prm_ll_data am43xx_prm_ll_data = {
+	.read_reset_sources = &omap44xx_prm_read_reset_sources,
+	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
+	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+	.late_init = &omap44xx_prm_late_init,
+	.assert_hardreset	= am33xx_prm_assert_hardreset,
+	.deassert_hardreset	= am33xx_prm_deassert_hardreset,
+	.is_hardreset_asserted	= am33xx_prm_is_hardreset_asserted,
+	.reset_system		= omap4_prminst_global_warm_sw_reset,
+};
+
+int __init am43xx_prm_init(const struct omap_prcm_init_data *data)
+{
+	omap44xx_prm_init_common(data);
+	return prm_register(&am43xx_prm_ll_data);
+}
+
Quoted 8 lines

arch/arm/mach-omap2/prm44xx.c static void __exit omap44xx_prm_exit(void) · line 793

Quoted 5 lines
arch/arm/mach-omap2/prm44xx.c +5 -0
+static void __exit am43xx_prm_exit(void)
+{
+	prm_unregister(&am43xx_prm_ll_data);
+}
+__exitcall(am43xx_prm_exit);

I think you can similarly just move this to use prm33xx.c instead of prm44xx.c and keep the functions static that way?

Yea this code is breaking some of the cleanup work already done for PRM. Sorry for the new bug introduced meanwhile, seems only pruss/wkup-m3 were affected by this issue. I will post a better approach for fixing this problem shortly.

-Tero

maintainer
#3 lore raw

PATCH 1/1 ARM: OMAP2+: PRM: Fix am437x module reset

In reply to Dave Gerlach

Hi Dave

Quoted 7 lines · Dave Gerlach

When moving to using the OMAP4+ PRM driver on am437x, we switched to using all omap4 ops for module reset management. However, reset register layout on am437x is more similar to am335x than omap4 because of the the need for an st_shift for the *_RST bits in certain *_RSTST registers, like WKUP_PROC_LRST in the PRCM_RM_WKUP_RSTST. Without this we cannot bring the Wakeup M3 IP out of reset.

Quoted 7 lines

Because of this, we must use the am33xx prm ops for the hardreset functionality while continuing to use all other omap4 ops. To accomplish this we split out the common portion of omap44xx_prm_init and add an am437x_prm_init to register the prm_ll_data struct specific to am437x.

I'm assuming this has been superseded by Tero's patches. If not, please let me know.

- Paul

#4 lore raw

PATCH 1/1 ARM: OMAP2+: PRM: Fix am437x module reset

Hi Paul,

Quoted 16 lines · Paul Walmsley

Hi Dave

Quoted 12 lines · Dave Gerlach

When moving to using the OMAP4+ PRM driver on am437x, we switched to using all omap4 ops for module reset management. However, reset register layout on am437x is more similar to am335x than omap4 because of the the need for an st_shift for the *_RST bits in certain *_RSTST registers, like WKUP_PROC_LRST in the PRCM_RM_WKUP_RSTST. Without this we cannot bring the Wakeup M3 IP out of reset.

Because of this, we must use the am33xx prm ops for the hardreset functionality while continuing to use all other omap4 ops. To accomplish this we split out the common portion of omap44xx_prm_init and add an am437x_prm_init to register the prm_ll_data struct specific to am437x.

Quoted 5 lines
Quoted 2 lines

I'm assuming this has been superseded by Tero's patches. If not, please let me know.

Yep, thats right. You can drop/ignore this patch, we did miss Tero's PRCM cleanup when this patch was rebased.

regards
Suman