aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authoromar ramirez <omar.ramirez@ti.com>2011-03-04 15:32:44 -0500
committerPaul Walmsley <paul@pwsan.com>2011-03-10 05:23:56 -0500
commitcc1226e7635011c7dd1e786770ed51ee751800f2 (patch)
tree3f9098c53cf5a2d0f809d8bd22c1fb32ff31f4e7 /arch/arm
parent4d2274c543e78a267989da5f9b12e223cd87839f (diff)
OMAP2+: hwmod: use status bit info for reset line
On OMAP2 and OMAP3 the reset ctrl shift doesn't match the status bit, as it does on OMAP4, when handling the reset lines. This patch adds a new member in the reset info structure, so now it can be added as part of hwmod data, and checked accordingly for OMAP2 or 3; otherwise, there could be cases when the shift masks doesn't match both of the registers, and a successful reset might throw an error message or vice versa. Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com> [paul@pwsan.com: added a warning if st_shift used on OMAP4; renamed 'r' variable; improved some documentation] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c75
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c18
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h5
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h2
4 files changed, 58 insertions, 42 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 2146d9aa507a..005264779f8d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -972,25 +972,29 @@ static int _wait_target_ready(struct omap_hwmod *oh)
972} 972}
973 973
974/** 974/**
975 * _lookup_hardreset - return the register bit shift for this hwmod/reset line 975 * _lookup_hardreset - fill register bit info for this hwmod/reset line
976 * @oh: struct omap_hwmod * 976 * @oh: struct omap_hwmod *
977 * @name: name of the reset line in the context of this hwmod 977 * @name: name of the reset line in the context of this hwmod
978 * @ohri: struct omap_hwmod_rst_info * that this function will fill in
978 * 979 *
979 * Return the bit position of the reset line that match the 980 * Return the bit position of the reset line that match the
980 * input name. Return -ENOENT if not found. 981 * input name. Return -ENOENT if not found.
981 */ 982 */
982static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name) 983static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,
984 struct omap_hwmod_rst_info *ohri)
983{ 985{
984 int i; 986 int i;
985 987
986 for (i = 0; i < oh->rst_lines_cnt; i++) { 988 for (i = 0; i < oh->rst_lines_cnt; i++) {
987 const char *rst_line = oh->rst_lines[i].name; 989 const char *rst_line = oh->rst_lines[i].name;
988 if (!strcmp(rst_line, name)) { 990 if (!strcmp(rst_line, name)) {
989 u8 shift = oh->rst_lines[i].rst_shift; 991 ohri->rst_shift = oh->rst_lines[i].rst_shift;
990 pr_debug("omap_hwmod: %s: _lookup_hardreset: %s: %d\n", 992 ohri->st_shift = oh->rst_lines[i].st_shift;
991 oh->name, rst_line, shift); 993 pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
994 oh->name, __func__, rst_line, ohri->rst_shift,
995 ohri->st_shift);
992 996
993 return shift; 997 return 0;
994 } 998 }
995 } 999 }
996 1000
@@ -1009,21 +1013,22 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name)
1009 */ 1013 */
1010static int _assert_hardreset(struct omap_hwmod *oh, const char *name) 1014static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1011{ 1015{
1012 u8 shift; 1016 struct omap_hwmod_rst_info ohri;
1017 u8 ret;
1013 1018
1014 if (!oh) 1019 if (!oh)
1015 return -EINVAL; 1020 return -EINVAL;
1016 1021
1017 shift = _lookup_hardreset(oh, name); 1022 ret = _lookup_hardreset(oh, name, &ohri);
1018 if (IS_ERR_VALUE(shift)) 1023 if (IS_ERR_VALUE(ret))
1019 return shift; 1024 return ret;
1020 1025
1021 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1026 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1022 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, 1027 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
1023 shift); 1028 ohri.rst_shift);
1024 else if (cpu_is_omap44xx()) 1029 else if (cpu_is_omap44xx())
1025 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg, 1030 return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
1026 shift); 1031 ohri.rst_shift);
1027 else 1032 else
1028 return -EINVAL; 1033 return -EINVAL;
1029} 1034}
@@ -1040,29 +1045,34 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
1040 */ 1045 */
1041static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) 1046static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1042{ 1047{
1043 u8 shift; 1048 struct omap_hwmod_rst_info ohri;
1044 int r; 1049 int ret;
1045 1050
1046 if (!oh) 1051 if (!oh)
1047 return -EINVAL; 1052 return -EINVAL;
1048 1053
1049 shift = _lookup_hardreset(oh, name); 1054 ret = _lookup_hardreset(oh, name, &ohri);
1050 if (IS_ERR_VALUE(shift)) 1055 if (IS_ERR_VALUE(ret))
1051 return shift; 1056 return ret;
1052 1057
1053 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 1058 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1054 r = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, 1059 ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
1055 shift); 1060 ohri.rst_shift,
1056 else if (cpu_is_omap44xx()) 1061 ohri.st_shift);
1057 r = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg, 1062 } else if (cpu_is_omap44xx()) {
1058 shift); 1063 if (ohri.st_shift)
1059 else 1064 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
1065 oh->name, name);
1066 ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
1067 ohri.rst_shift);
1068 } else {
1060 return -EINVAL; 1069 return -EINVAL;
1070 }
1061 1071
1062 if (r == -EBUSY) 1072 if (ret == -EBUSY)
1063 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name); 1073 pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
1064 1074
1065 return r; 1075 return ret;
1066} 1076}
1067 1077
1068/** 1078/**
@@ -1075,21 +1085,22 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
1075 */ 1085 */
1076static int _read_hardreset(struct omap_hwmod *oh, const char *name) 1086static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1077{ 1087{
1078 u8 shift; 1088 struct omap_hwmod_rst_info ohri;
1089 u8 ret;
1079 1090
1080 if (!oh) 1091 if (!oh)
1081 return -EINVAL; 1092 return -EINVAL;
1082 1093
1083 shift = _lookup_hardreset(oh, name); 1094 ret = _lookup_hardreset(oh, name, &ohri);
1084 if (IS_ERR_VALUE(shift)) 1095 if (IS_ERR_VALUE(ret))
1085 return shift; 1096 return ret;
1086 1097
1087 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 1098 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
1088 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, 1099 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
1089 shift); 1100 ohri.st_shift);
1090 } else if (cpu_is_omap44xx()) { 1101 } else if (cpu_is_omap44xx()) {
1091 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg, 1102 return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
1092 shift); 1103 ohri.rst_shift);
1093 } else { 1104 } else {
1094 return -EINVAL; 1105 return -EINVAL;
1095 } 1106 }
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index ec0362574b5e..051213fbc346 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -118,7 +118,8 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
118/** 118/**
119 * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait 119 * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait
120 * @prm_mod: PRM submodule base (e.g. CORE_MOD) 120 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
121 * @shift: register bit shift corresponding to the reset line to deassert 121 * @rst_shift: register bit shift corresponding to the reset line to deassert
122 * @st_shift: register bit shift for the status of the deasserted submodule
122 * 123 *
123 * Some IPs like dsp or iva contain processors that require an HW 124 * Some IPs like dsp or iva contain processors that require an HW
124 * reset line to be asserted / deasserted in order to fully enable the 125 * reset line to be asserted / deasserted in order to fully enable the
@@ -129,27 +130,28 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
129 * -EINVAL upon an argument error, -EEXIST if the submodule was already out 130 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
130 * of reset, or -EBUSY if the submodule did not exit reset promptly. 131 * of reset, or -EBUSY if the submodule did not exit reset promptly.
131 */ 132 */
132int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift) 133int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
133{ 134{
134 u32 mask; 135 u32 rst, st;
135 int c; 136 int c;
136 137
137 if (!(cpu_is_omap24xx() || cpu_is_omap34xx())) 138 if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
138 return -EINVAL; 139 return -EINVAL;
139 140
140 mask = 1 << shift; 141 rst = 1 << rst_shift;
142 st = 1 << st_shift;
141 143
142 /* Check the current status to avoid de-asserting the line twice */ 144 /* Check the current status to avoid de-asserting the line twice */
143 if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, mask) == 0) 145 if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, rst) == 0)
144 return -EEXIST; 146 return -EEXIST;
145 147
146 /* Clear the reset status by writing 1 to the status bit */ 148 /* Clear the reset status by writing 1 to the status bit */
147 omap2_prm_rmw_mod_reg_bits(0xffffffff, mask, prm_mod, OMAP2_RM_RSTST); 149 omap2_prm_rmw_mod_reg_bits(0xffffffff, st, prm_mod, OMAP2_RM_RSTST);
148 /* de-assert the reset control line */ 150 /* de-assert the reset control line */
149 omap2_prm_rmw_mod_reg_bits(mask, 0, prm_mod, OMAP2_RM_RSTCTRL); 151 omap2_prm_rmw_mod_reg_bits(rst, 0, prm_mod, OMAP2_RM_RSTCTRL);
150 /* wait the status to be set */ 152 /* wait the status to be set */
151 omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST, 153 omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
152 mask), 154 st),
153 MAX_MODULE_HARDRESET_WAIT, c); 155 MAX_MODULE_HARDRESET_WAIT, c);
154 156
155 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0; 157 return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 49654c8d18f5..a1fc62a39dbb 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -282,7 +282,8 @@ static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
282 "not suppose to be used on omap4\n"); 282 "not suppose to be used on omap4\n");
283 return 0; 283 return 0;
284} 284}
285static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift) 285static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
286 u8 st_shift)
286{ 287{
287 WARN(1, "prm: omap2xxx/omap3xxx specific function and " 288 WARN(1, "prm: omap2xxx/omap3xxx specific function and "
288 "not suppose to be used on omap4\n"); 289 "not suppose to be used on omap4\n");
@@ -300,7 +301,7 @@ extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
300/* These omap2_ PRM functions apply to both OMAP2 and 3 */ 301/* These omap2_ PRM functions apply to both OMAP2 and 3 */
301extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); 302extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
302extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); 303extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
303extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift); 304extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
304 305
305#endif /* CONFIG_ARCH_OMAP4 */ 306#endif /* CONFIG_ARCH_OMAP4 */
306#endif 307#endif
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 5924ecdfb95a..78f1cc88ff06 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -124,6 +124,7 @@ struct omap_hwmod_dma_info {
124 * struct omap_hwmod_rst_info - IPs reset lines use by hwmod 124 * struct omap_hwmod_rst_info - IPs reset lines use by hwmod
125 * @name: name of the reset line (module local name) 125 * @name: name of the reset line (module local name)
126 * @rst_shift: Offset of the reset bit 126 * @rst_shift: Offset of the reset bit
127 * @st_shift: Offset of the reset status bit (OMAP2/3 only)
127 * 128 *
128 * @name should be something short, e.g., "cpu0" or "rst". It is defined 129 * @name should be something short, e.g., "cpu0" or "rst". It is defined
129 * locally to the hwmod. 130 * locally to the hwmod.
@@ -131,6 +132,7 @@ struct omap_hwmod_dma_info {
131struct omap_hwmod_rst_info { 132struct omap_hwmod_rst_info {
132 const char *name; 133 const char *name;
133 u8 rst_shift; 134 u8 rst_shift;
135 u8 st_shift;
134}; 136};
135 137
136/** 138/**