blob: 8f536334227b9d8b511e22f8263414ad8b2ef1a1 [file] [log] [blame]
lijuangfdf2fa62015-03-11 16:46:41 +08001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above
9* copyright notice, this list of conditions and the following
10* disclaimer in the documentation and/or other materials provided
11* with the distribution.
12* * Neither the name of The Linux Foundation nor the names of its
13* contributors may be used to endorse or promote products derived
14* from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#include <debug.h>
30#include <platform/iomap.h>
31#include <reg.h>
32#include <target.h>
33#include <platform.h>
lijuangfdf2fa62015-03-11 16:46:41 +080034#include <pm8x41.h>
Channagoud Kadabi77f46a32015-08-05 16:13:13 -070035#include <pm8x41_hw.h>
lijuangfdf2fa62015-03-11 16:46:41 +080036#include <scm.h>
lijuangfdf2fa62015-03-11 16:46:41 +080037#include <stdlib.h>
38#include <reboot.h>
Channagoud Kadabi77f46a32015-08-05 16:13:13 -070039#include <qtimer.h>
lijuangfdf2fa62015-03-11 16:46:41 +080040
41#if USER_FORCE_RESET_SUPPORT
42/* Return 1 if it is a force resin triggered by user. */
43uint32_t is_user_force_reset(void)
44{
45 uint8_t poff_reason1 = pm8x41_get_pon_poff_reason1();
46 uint8_t poff_reason2 = pm8x41_get_pon_poff_reason2();
47
48 dprintf(SPEW, "poff_reason1: %d\n", poff_reason1);
49 dprintf(SPEW, "poff_reason2: %d\n", poff_reason2);
50 if (pm8x41_get_is_cold_boot() && (poff_reason1 == KPDPWR_AND_RESIN ||
51 poff_reason2 == STAGE3))
52 return 1;
53 else
54 return 0;
55}
56#endif
57
58unsigned check_reboot_mode(void)
59{
60 uint32_t restart_reason = 0;
61
62 /* Read reboot reason and scrub it */
63 restart_reason = readl(RESTART_REASON_ADDR);
64 writel(0x00, RESTART_REASON_ADDR);
65
66 return restart_reason;
67}
68
69unsigned check_hard_reboot_mode(void)
70{
71 uint8_t hard_restart_reason = 0;
lijuangfdf2fa62015-03-11 16:46:41 +080072
73 /* Read reboot reason and scrub it
74 * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
75 */
Channagoud Kadabicfdd8f92015-08-27 18:15:20 -070076 hard_restart_reason = REG_READ(PON_SOFT_RB_SPARE);
77 REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x1f);
lijuangfdf2fa62015-03-11 16:46:41 +080078
79 return hard_restart_reason;
80}
81
lijuangdc20de12015-02-11 12:09:57 +080082/* Return true if it is triggered by alarm. */
83uint32_t check_alarm_boot(void)
84{
85 /* Check reboot reason and power on reason */
86 if (pm8x41_get_is_cold_boot()) {
87 if (pm8x41_get_pon_reason() == RTC_TRG)
88 return 1;
89 } else {
90 if (readl(RESTART_REASON_ADDR) == ALARM_BOOT)
91 return 1;
92 }
93
94 return 0;
95}
96
lijuangfdf2fa62015-03-11 16:46:41 +080097void reboot_device(unsigned reboot_reason)
98{
99 uint8_t reset_type = 0;
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700100 int ret = 0;
101#if USE_PON_REBOOT_REG
102 uint8_t value;
103#endif
lijuangfdf2fa62015-03-11 16:46:41 +0800104
105 /* Need to clear the SW_RESET_ENTRY register and
106 * write to the BOOT_MISC_REG for known reset cases
107 */
108 if(reboot_reason != DLOAD)
109 scm_dload_mode(NORMAL_MODE);
110
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700111#if USE_PON_REBOOT_REG
112 value = REG_READ(PON_SOFT_RB_SPARE);
Channagoud Kadabicfdd8f92015-08-27 18:15:20 -0700113 value |= reboot_reason;
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700114 REG_WRITE(PON_SOFT_RB_SPARE, value);
115#else
lijuangfdf2fa62015-03-11 16:46:41 +0800116 writel(reboot_reason, RESTART_REASON_ADDR);
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700117#endif
118 /* For Dload cases do a warm reset
119 * For other cases do a hard reset
lijuangfdf2fa62015-03-11 16:46:41 +0800120 */
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700121#if USE_PON_REBOOT_REG
122 if(reboot_reason == DLOAD)
123#else
124 if(reboot_reason == FASTBOOT_MODE || (reboot_reason == DLOAD) || (reboot_reason == RECOVERY_MODE))
125#endif
lijuangfdf2fa62015-03-11 16:46:41 +0800126 reset_type = PON_PSHOLD_WARM_RESET;
127 else
128 reset_type = PON_PSHOLD_HARD_RESET;
129
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700130 pmic_reset_configure(reset_type);
lijuangfdf2fa62015-03-11 16:46:41 +0800131
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700132 /* Force spmi shutdown to avoid spmi lock up on some pmics */
133 ret = is_scm_call_available(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER);
134 if ( ret > 0)
135 {
136 ret = scm_halt_pmic_arbiter();
137 if (ret)
138 dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
139 }
lijuangfdf2fa62015-03-11 16:46:41 +0800140
141 /* Drop PS_HOLD for MSM */
142 writel(0x00, MPM2_MPM_PS_HOLD);
143
144 mdelay(5000);
145
146 dprintf(CRITICAL, "Rebooting failed\n");
147}
148
Channagoud Kadabi77f46a32015-08-05 16:13:13 -0700149void shutdown_device()
150{
151 dprintf(CRITICAL, "Going down for shutdown.\n");
152
153 /* Configure PMIC for shutdown. */
154 pmic_reset_configure(PON_PSHOLD_SHUTDOWN);
155
156 /* Drop PS_HOLD for MSM */
157 writel(0x00, MPM2_MPM_PS_HOLD);
158
159 mdelay(5000);
160
161 dprintf(CRITICAL, "Shutdown failed\n");
162
163 ASSERT(0);
164}