mtk_wdt.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <platform/mt_reg_base.h>
  32. #include <platform/mt_typedefs.h>
  33. #include "mtk_wdt.h"
  34. #include <platform/boot_mode.h>
  35. #include <platform/mt_gpt.h>
  36. #include <platform/mt_pmic.h>
  37. #include <platform/mt_pmic_wrap_init.h>
  38. #include <platform/upmu_common.h>
  39. #include <debug.h>
  40. #include <lk_builtin_dtb.h>
  41. #ifdef DEVICE_TREE_SUPPORT
  42. #include <libfdt.h>
  43. #endif
  44. #include "log_store_lk.h"
  45. #define WDTTAG "[WDT] "
  46. #define WDTLOG(fmt, arg...) dprintf(INFO, WDTTAG fmt, ##arg)
  47. #define WDTCRI(fmt, arg...) dprintf(CRITICAL,WDTTAG fmt, ##arg)
  48. #define WDTMSG(fmt, arg...) dprintf(INFO, fmt, ##arg)
  49. #define WDTERR(fmt, arg...) dprintf(INFO, WDTTAG "%5d: "fmt, __LINE__, ##arg)
  50. #define TOPRGU_DTS_NAME "/toprgu@10007000"
  51. #define TOPRGU_DT_NODE_PROP_NAME "apwdt_en"
  52. #if ENABLE_WDT_MODULE
  53. static unsigned int timeout;
  54. static unsigned int is_rgu_trigger_rst;
  55. static unsigned char rgu_restart_reason = MTK_WDT_NONRST2_BOOT_MASK;
  56. #define WDT_CLR_IRQ 0
  57. static void mtk_wdt_clear_restart_reason(unsigned char mask)
  58. {
  59. u32 tmp;
  60. tmp = DRV_Reg32(MTK_WDT_NONRST_REG2);
  61. tmp &= ~mask;
  62. DRV_WriteReg32(MTK_WDT_NONRST_REG2, tmp);
  63. }
  64. static unsigned char mtk_wdt_get_restart_reason(void)
  65. {
  66. u32 tmp;
  67. tmp = DRV_Reg32(MTK_WDT_NONRST_REG2) & MTK_WDT_NONRST2_BOOT_MASK;
  68. mtk_wdt_clear_restart_reason(MTK_WDT_NONRST2_BOOT_MASK);
  69. return tmp;
  70. }
  71. unsigned char mtk_wdt_restart_reason()
  72. {
  73. if (rgu_restart_reason == MTK_WDT_NONRST2_BOOT_MASK)
  74. rgu_restart_reason = mtk_wdt_get_restart_reason();
  75. return rgu_restart_reason;
  76. }
  77. void mtk_wdt_disable(void)
  78. {
  79. u32 tmp;
  80. tmp = DRV_Reg32(MTK_WDT_MODE);
  81. tmp &= ~MTK_WDT_MODE_ENABLE; /* disable watchdog */
  82. tmp |= (MTK_WDT_MODE_KEY); /* need key then write is allowed */
  83. DRV_WriteReg32(MTK_WDT_MODE, tmp);
  84. }
  85. void mtk_wdt_doe_setup(void)
  86. {
  87. int apwdt_en = 1;
  88. int len = 0, offset = 0;
  89. unsigned int *data = NULL;
  90. void *wdt_fdt = get_lk_overlayed_dtb();
  91. offset = fdt_path_offset(wdt_fdt, TOPRGU_DTS_NAME);
  92. WDTLOG("[WDT] Found " TOPRGU_DTS_NAME " at offset %d\n", offset);
  93. if (offset < 0) {
  94. WDTERR("[WDT] Failed to find " TOPRGU_DTS_NAME " in dtb\n");
  95. apwdt_en = 1;
  96. } else {
  97. data = (unsigned int *)fdt_getprop(wdt_fdt, offset, TOPRGU_DT_NODE_PROP_NAME, &len);
  98. if (len <= 0 || !data) {
  99. WDTERR("[WDT] Fail to found property " TOPRGU_DT_NODE_PROP_NAME "\n");
  100. apwdt_en = 1;
  101. } else
  102. apwdt_en = fdt32_to_cpu(*(unsigned int *)data);
  103. }
  104. if (apwdt_en == 0) {
  105. /* disable wdt timeout */
  106. mtk_wdt_disable();
  107. /* disable all reset source's reset and irq mode */
  108. DRV_WriteReg32(MTK_WDT_REQ_MODE, MTK_WDT_REQ_MODE_KEY);
  109. DRV_WriteReg32(MTK_WDT_REQ_IRQ_EN, MTK_WDT_REQ_IRQ_KEY);
  110. WDTLOG("apwdt is disabled by doe\n");
  111. } else {
  112. WDTLOG("keep original wdt settings\n");
  113. }
  114. }
  115. static void mtk_wdt_clear_all(void)
  116. {
  117. #if WDT_CLR_IRQ
  118. DRV_WriteReg32(MTK_WDT_IRQ_CLR, MTK_WDT_IRQ_CLR_MASK |
  119. MTK_WDT_IRQ_CLR_KEY);
  120. #else
  121. return;
  122. #endif
  123. }
  124. void __attribute__((weak)) pwrap_disable(void)
  125. {
  126. WDTCRI("pwrap do nothing\n");
  127. }
  128. static void mtk_wdt_reset(char bypass_power_key)
  129. {
  130. WDTCRI("%s\n", __func__);
  131. /* Watchdog Rest */
  132. unsigned int wdt_mode_val = 0, nonrst2 = 0;
  133. mtk_wdt_clear_all();
  134. DRV_WriteReg32(MTK_WDT_RESTART, MTK_WDT_RESTART_KEY);
  135. /*set latch register to 0 before sw reset*/
  136. /* DRV_WriteReg32(MTK_WDT_LATCH_CTL, (MTK_WDT_LENGTH_CTL_KEY | 0x0)); */
  137. wdt_mode_val = DRV_Reg32(MTK_WDT_MODE);
  138. /*
  139. * MTK_WDT_MODE_AUTO_RESTART is replaced by MTK_WDT_NONRST2_BYPASS_PWR_KEY
  140. * of NONRST_REG2 for common kernel projects and two stage timeout design
  141. */
  142. nonrst2 = DRV_Reg32(MTK_WDT_NONRST_REG2);
  143. /* clear autorestart bit: autoretart: 1, bypass power key, 0: not bypass power key */
  144. nonrst2 &= ~MTK_WDT_NONRST2_BYPASS_PWR_KEY;
  145. /* make sure WDT mode is hw reboot mode, can not config isr mode */
  146. wdt_mode_val &= (~(MTK_WDT_MODE_IRQ | MTK_WDT_MODE_DUAL_MODE | MTK_WDT_MODE_EXTRA_CNT));
  147. wdt_mode_val = wdt_mode_val | MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTEN;
  148. /* bypass power key reboot. We using auto_restart bit as bypass power key flag */
  149. if (bypass_power_key)
  150. nonrst2 |= MTK_WDT_NONRST2_BYPASS_PWR_KEY;
  151. DRV_WriteReg32(MTK_WDT_MODE, wdt_mode_val);
  152. DRV_WriteReg32(MTK_WDT_NONRST_REG2, nonrst2);
  153. if (!DRV_Reg32(MTK_WDT_STATUS)) {
  154. unsigned int latch_ctrl2 = DRV_Reg32(MTK_WDT_LATCH_CTL2);
  155. latch_ctrl2 &= ~MTK_WDT_LATCH_CTL2_DFD_EN;
  156. latch_ctrl2 |= MTK_WDT_LATCH_CTL2_KEY;
  157. DRV_WriteReg32(MTK_WDT_LATCH_CTL2, latch_ctrl2);
  158. }
  159. gpt_busy_wait_us(100);
  160. WDTCRI("%s: MODE: 0x%x\n", __func__, DRV_Reg32(MTK_WDT_MODE));
  161. WDTCRI("%s: SW reset happen!\n", __func__);
  162. WDTCRI("%s disable pwrap before wdt\n", __func__);
  163. pwrap_disable();
  164. DRV_WriteReg32(MTK_WDT_SWRST, MTK_WDT_SWRST_KEY);
  165. }
  166. unsigned int mtk_wdt_check_status(void)
  167. {
  168. unsigned int status;
  169. status = DRV_Reg32(MTK_WDT_STATUS);
  170. return status;
  171. }
  172. static void mtk_wdt_mode_config(BOOL dual_mode_en,
  173. BOOL irq,
  174. BOOL ext_en,
  175. BOOL ext_pol,
  176. BOOL wdt_en)
  177. {
  178. unsigned int tmp;
  179. mtk_wdt_clear_all();
  180. WDTLOG(" mtk_wdt_mode LK config mode value=%x\n", DRV_Reg32(MTK_WDT_MODE));
  181. tmp = DRV_Reg32(MTK_WDT_MODE);
  182. tmp |= MTK_WDT_MODE_KEY | MTK_WDT_MODE_EXTRA_CNT;
  183. /* Bit 0 : Whether enable watchdog or not */
  184. if (wdt_en == TRUE)
  185. tmp |= MTK_WDT_MODE_ENABLE;
  186. else
  187. tmp &= ~MTK_WDT_MODE_ENABLE;
  188. /* Bit 1 : Configure extern reset signal polarity. */
  189. if (ext_pol == TRUE)
  190. tmp |= MTK_WDT_MODE_EXT_POL;
  191. else
  192. tmp &= ~MTK_WDT_MODE_EXT_POL;
  193. /* Bit 2 : Whether enable external reset signal */
  194. if (ext_en == TRUE)
  195. tmp |= MTK_WDT_MODE_EXTEN;
  196. else
  197. tmp &= ~MTK_WDT_MODE_EXTEN;
  198. /* Bit 3 : Whether generating interrupt instead of reset signal */
  199. if (irq == TRUE)
  200. tmp |= MTK_WDT_MODE_IRQ;
  201. else
  202. tmp &= ~MTK_WDT_MODE_IRQ;
  203. /* Bit 6 : Whether enable debug module reset */
  204. if (dual_mode_en == TRUE)
  205. tmp |= MTK_WDT_MODE_DUAL_MODE;
  206. else
  207. tmp &= ~MTK_WDT_MODE_DUAL_MODE;
  208. DRV_WriteReg32(MTK_WDT_MODE, tmp);
  209. /*
  210. * MTK_WDT_MODE_AUTO_RESTART is replaced by MTK_WDT_NONRST2_BYPASS_PWR_KEY
  211. * of NONRST_REG2 for common kernel projects and two stage timeout design
  212. */
  213. DRV_WriteReg32(MTK_WDT_NONRST_REG2, DRV_Reg32(MTK_WDT_NONRST_REG2) |
  214. MTK_WDT_NONRST2_BYPASS_PWR_KEY);
  215. /* dual_mode(1); //always dual mode */
  216. /* mdelay(100); */
  217. WDTLOG(" mtk_wdt_mode_config LK mode value=%x, tmp:%x\n", DRV_Reg32(MTK_WDT_MODE), tmp);
  218. }
  219. #if 0
  220. static void mtk_wdt_mode_config(BOOL debug_en,
  221. BOOL irq,
  222. BOOL ext_en,
  223. BOOL ext_pol,
  224. BOOL wdt_en)
  225. {
  226. unsigned short tmp;
  227. tmp = DRV_Reg32(MTK_WDT_MODE);
  228. tmp |= MTK_WDT_MODE_KEY;
  229. /* Bit 0 : Whether enable watchdog or not */
  230. if (wdt_en == TRUE)
  231. tmp |= MTK_WDT_MODE_ENABLE;
  232. else
  233. tmp &= ~MTK_WDT_MODE_ENABLE;
  234. /* Bit 1 : Configure extern reset signal polarity. */
  235. if (ext_pol == TRUE)
  236. tmp |= MTK_WDT_MODE_EXT_POL;
  237. else
  238. tmp &= ~MTK_WDT_MODE_EXT_POL;
  239. /* Bit 2 : Whether enable external reset signal */
  240. if (ext_en == TRUE)
  241. tmp |= MTK_WDT_MODE_EXTEN;
  242. else
  243. tmp &= ~MTK_WDT_MODE_EXTEN;
  244. /* Bit 3 : Whether generating interrupt instead of reset signal */
  245. if (irq == TRUE)
  246. tmp |= MTK_WDT_MODE_IRQ;
  247. else
  248. tmp &= ~MTK_WDT_MODE_IRQ;
  249. /* Bit 6 : Whether enable debug module reset */
  250. if (debug_en == TRUE)
  251. tmp |= MTK_WDT_MODE_DEBUG_EN;
  252. else
  253. tmp &= ~MTK_WDT_MODE_DEBUG_EN;
  254. DRV_WriteReg32(MTK_WDT_MODE, tmp);
  255. }
  256. #endif
  257. void mtk_wdt_set_time_out_value(UINT32 value)
  258. {
  259. /*
  260. * TimeOut = BitField 15:5
  261. * Key = BitField 4:0 = 0x08
  262. */
  263. /* sec * 32768 / 512 = sec * 64 = sec * 1 << 6 */
  264. timeout = (unsigned int)(value * (1 << 6));
  265. timeout = timeout << 5;
  266. DRV_WriteReg32(MTK_WDT_LENGTH, (timeout | MTK_WDT_LENGTH_KEY));
  267. }
  268. void mtk_wdt_restart(void)
  269. {
  270. /* Reset WatchDogTimer's counting value to time out value */
  271. /* ie., keepalive() */
  272. DRV_WriteReg32(MTK_WDT_RESTART, MTK_WDT_RESTART_KEY);
  273. }
  274. static void mtk_wdt_sw_reset(void)
  275. {
  276. WDTLOG("WDT SW RESET\n");
  277. /* DRV_WriteReg32 (0x70025000, 0x2201); */
  278. /* DRV_WriteReg32 (0x70025008, 0x1971); */
  279. /* DRV_WriteReg32 (0x7002501C, 0x1209); */
  280. mtk_wdt_reset(1);/* NOTE here, this reset will cause by pass power key */
  281. /* system will reset */
  282. while (1) {
  283. WDTLOG("SW reset fail ...\n");
  284. };
  285. }
  286. static void mtk_wdt_hw_reset(void)
  287. {
  288. WDTLOG("WDT_HW_Reset\n");
  289. /* 1. set WDT timeout 1 secs, 1*64*512/32768 = 1sec */
  290. mtk_wdt_set_time_out_value(1);
  291. /* 2. enable WDT debug reset enable, generating irq disable, ext reset disable */
  292. /* ext reset signal low, wdt enalbe */
  293. mtk_wdt_mode_config(TRUE, FALSE, FALSE, FALSE, TRUE);
  294. /* 3. reset the watch dog timer to the value set in WDT_LENGTH register */
  295. mtk_wdt_restart();
  296. /* 4. system will reset */
  297. while (1);
  298. }
  299. const char *mtk_wdt_get_last_stage(void)
  300. {
  301. unsigned int reg;
  302. unsigned int last_stage;
  303. /* check reboot source */
  304. reg = DRV_Reg32(MTK_WDT_NONRST_REG2);
  305. last_stage = (reg >> MTK_WDT_NONRST2_LAST_STAGE_OFS) & RGU_STAGE_MASK;
  306. if (last_stage == RGU_STAGE_PRELOADER)
  307. return "rst from: pl";
  308. else if (last_stage == RGU_STAGE_LK)
  309. return "rst from: lk";
  310. else if (last_stage == RGU_STAGE_KERNEL)
  311. return "rst from: kernel";
  312. else if (last_stage == RGU_STAGE_DA)
  313. return "rst from: DA";
  314. return "rst from: unknown";
  315. }
  316. static void mtk_wdt_mark_stage(unsigned int stage)
  317. {
  318. unsigned int reg = DRV_Reg32(MTK_WDT_NONRST_REG2);
  319. reg = (reg & ~(RGU_STAGE_MASK << MTK_WDT_NONRST2_STAGE_OFS))
  320. | (stage << MTK_WDT_NONRST2_STAGE_OFS);
  321. DRV_WriteReg32(MTK_WDT_NONRST_REG2, reg);
  322. }
  323. void mtk_wdt_select_eint(unsigned int ext_debugkey_io_eint)
  324. {
  325. unsigned int eint = ext_debugkey_io_eint;
  326. eint = (eint << MTK_WDT_EXT_EINT_SHF) & MTK_WDT_EXT_EINT_MASK;
  327. DRV_WriteReg32(MTK_WDT_EXT_REQ_CON, eint | MTK_WDT_EXT_EINT_EN);
  328. }
  329. int mtk_wdt_request_en_set(int mark_bit, WD_REQ_CTL en)
  330. {
  331. unsigned int tmp;
  332. if ((mark_bit != MTK_WDT_STATUS_SSPM_RST) &&
  333. (mark_bit != MTK_WDT_STATUS_SYSRST_RST) &&
  334. (mark_bit != MTK_WDT_STATUS_EINT_RST) &&
  335. (mark_bit != MTK_WDT_STATUS_SPM_THERMAL_RST))
  336. return -1;
  337. tmp = DRV_Reg32(MTK_WDT_REQ_MODE);
  338. tmp |= MTK_WDT_REQ_MODE_KEY;
  339. if (en == WD_REQ_EN) {
  340. tmp |= (mark_bit);
  341. if (mark_bit & MTK_WDT_STATUS_SYSRST_RST) {
  342. DRV_WriteReg32(MTK_WDT_SYSDBG_DEG_EN1,
  343. MTK_WDT_SYSDBG_DEG_EN1_KEY);
  344. DRV_WriteReg32(MTK_WDT_SYSDBG_DEG_EN2,
  345. MTK_WDT_SYSDBG_DEG_EN2_KEY);
  346. }
  347. } else if (en == WD_REQ_DIS) {
  348. tmp &= ~(mark_bit);
  349. if (mark_bit & MTK_WDT_STATUS_SYSRST_RST) {
  350. DRV_WriteReg32(MTK_WDT_SYSDBG_DEG_EN1, 0);
  351. DRV_WriteReg32(MTK_WDT_SYSDBG_DEG_EN2, 0);
  352. }
  353. }
  354. DRV_WriteReg32(MTK_WDT_REQ_MODE, tmp);
  355. return 0;
  356. }
  357. int mtk_wdt_request_mode_set(int mark_bit, WD_REQ_MODE mode)
  358. {
  359. unsigned int tmp;
  360. if ((mark_bit != MTK_WDT_STATUS_SSPM_RST) &&
  361. (mark_bit != MTK_WDT_STATUS_SYSRST_RST) &&
  362. (mark_bit != MTK_WDT_STATUS_EINT_RST) &&
  363. (mark_bit != MTK_WDT_STATUS_SPM_THERMAL_RST))
  364. return -1;
  365. tmp = DRV_Reg32(MTK_WDT_REQ_IRQ_EN);
  366. tmp |= MTK_WDT_REQ_IRQ_KEY;
  367. if (mode == WD_REQ_IRQ_MODE)
  368. tmp |= (mark_bit);
  369. else if (mode == WD_REQ_RST_MODE)
  370. tmp &= ~(mark_bit);
  371. DRV_WriteReg32(MTK_WDT_REQ_IRQ_EN, tmp);
  372. return 0;
  373. }
  374. int mtk_wdt_swsysret_config(int bit, int set_value)
  375. {
  376. unsigned int wdt_sys_val;
  377. wdt_sys_val = DRV_Reg32(MTK_WDT_SWSYSRST);
  378. wdt_sys_val |= MTK_WDT_SWSYS_RST_KEY;
  379. switch (bit) {
  380. case MTK_WDT_SWSYS_RST_GPU_RST:
  381. if (set_value == 1)
  382. wdt_sys_val |= MTK_WDT_SWSYS_RST_GPU_RST;
  383. if (set_value == 0)
  384. wdt_sys_val &= ~MTK_WDT_SWSYS_RST_GPU_RST;
  385. break;
  386. }
  387. DRV_WriteReg32(MTK_WDT_SWSYSRST, wdt_sys_val);
  388. return 0;
  389. }
  390. #ifdef MTK_ENTER_FASTBOOT_VIA_RGU
  391. int mtk_wdt_fastboot_check(void)
  392. {
  393. int is_fastboot = 0;
  394. if (mtk_wdt_restart_reason() == MTK_WDT_NONRST2_BOOT_BOOTLOADER)
  395. is_fastboot = 1;
  396. return is_fastboot;
  397. }
  398. /* set fastboot rgu bit. 1: fastboot mode. 0: non-fastboot mode */
  399. void mtk_wdt_fastboot_set(int fastboot_en)
  400. {
  401. unsigned int reg = DRV_Reg32(MTK_WDT_NONRST_REG2) &
  402. ~(MTK_WDT_NONRST2_BOOT_MASK);
  403. if (fastboot_en) {
  404. reg = reg | MTK_WDT_NONRST2_BOOT_BOOTLOADER;
  405. DRV_WriteReg32(MTK_WDT_NONRST_REG2, reg);
  406. }
  407. }
  408. #endif
  409. /**
  410. * For Power off and power on reset, the INTERVAL default value is 0x7FF.
  411. * We set Interval[1:0] to different value to distinguish different stage.
  412. * Enter pre-loader, we will set it to 0x0
  413. * Enter u-boot, we will set it to 0x1
  414. * Enter kernel, we will set it to 0x2
  415. * And the default value is 0x3 which means reset from a power off and power on reset
  416. */
  417. #define POWER_OFF_ON_MAGIC (0x3)
  418. #define PRE_LOADER_MAGIC (0x0)
  419. #define U_BOOT_MAGIC (0x1)
  420. #define KERNEL_MAGIC (0x2)
  421. #define MAGIC_NUM_MASK (0x3)
  422. /**
  423. * If the reset is trigger by RGU(Time out or SW trigger), we hope the system can boot up directly;
  424. * we DO NOT hope we must press power key to reboot system after reset.
  425. * This message should tell pre-loader and u-boot, and we use Interval[2] to store this information.
  426. * And this information will be cleared when enter kernel.
  427. */
  428. #define IS_POWER_ON_RESET (0x1<<2)
  429. #define RGU_TRIGGER_RESET_MASK (0x1<<2)
  430. void mtk_wdt_init(void)
  431. {
  432. unsigned int tmp;
  433. unsigned int interval_val = DRV_Reg32(MTK_WDT_INTERVAL);
  434. rgu_restart_reason = mtk_wdt_restart_reason();
  435. /* mark stage */
  436. mtk_wdt_mark_stage(RGU_STAGE_LK);
  437. mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE);
  438. WDTLOG("wdt init\n");
  439. /* Update interval register value and check reboot flag */
  440. if ((interval_val & RGU_TRIGGER_RESET_MASK) == IS_POWER_ON_RESET)
  441. is_rgu_trigger_rst = 0; /* Power off and power on reset */
  442. else
  443. is_rgu_trigger_rst = 1; /* RGU trigger reset */
  444. interval_val &= ~(RGU_TRIGGER_RESET_MASK|MAGIC_NUM_MASK);
  445. interval_val |= (U_BOOT_MAGIC|IS_POWER_ON_RESET);
  446. /* Write back INTERVAL REG */
  447. DRV_WriteReg32(MTK_WDT_INTERVAL, interval_val);
  448. /* Setting timeout 10s */
  449. mtk_wdt_set_time_out_value(10);
  450. /*set SPM_SCPSYS_rst to be enable to be disable*/
  451. tmp = DRV_Reg32(MTK_WDT_REQ_MODE);
  452. tmp |= MTK_WDT_REQ_MODE_KEY;
  453. tmp |= MTK_WDT_REQ_MODE_SPM_SCPSYS;
  454. tmp |= MTK_WDT_REQ_MODE_THERMAL;
  455. DRV_WriteReg32(MTK_WDT_REQ_MODE, tmp);
  456. /*set thermal_ctl_rst & SPM_SCPSYS_rst to be reset mode*/
  457. tmp = DRV_Reg32(MTK_WDT_REQ_IRQ_EN);
  458. tmp |= MTK_WDT_REQ_IRQ_KEY;
  459. tmp &= ~(MTK_WDT_REQ_IRQ_THERMAL_EN | MTK_WDT_REQ_IRQ_SPM_SCPSYS_EN);
  460. DRV_WriteReg32(MTK_WDT_REQ_IRQ_EN, tmp);
  461. #ifdef WDT_ENABLED
  462. mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE);
  463. mtk_wdt_restart();
  464. #endif
  465. #if 0
  466. int i = 0;
  467. /* lk wdt test */
  468. while (1) {
  469. i++;
  470. mdelay(1000);
  471. WDTLOG("wdt test %d\n", i);
  472. /* Dump RGU regisers */
  473. WDTLOG("==== fwq Dump RGU Reg ========\n");
  474. WDTLOG("RGU MODE: %x\n", DRV_Reg32(MTK_WDT_MODE));
  475. WDTLOG("RGU LENGTH: %x\n", DRV_Reg32(MTK_WDT_LENGTH));
  476. WDTLOG("RGU STA: %x\n", DRV_Reg32(MTK_WDT_STATUS));
  477. WDTLOG("RGU INTERVAL: %x\n", DRV_Reg32(MTK_WDT_INTERVAL));
  478. WDTLOG("RGU SWSYSRST: %x\n", DRV_Reg32(MTK_WDT_SWSYSRST));
  479. WDTLOG("==== Dump RGU Reg End ====\n");
  480. if (i < 60) {
  481. WDTLOG("kick lk ext\n");
  482. mtk_wdt_restart();
  483. }
  484. }
  485. #endif
  486. }
  487. BOOL mtk_is_rgu_trigger_reset(void)
  488. {
  489. if (is_rgu_trigger_rst)
  490. return TRUE;
  491. return FALSE;
  492. }
  493. extern BOOT_ARGUMENT *g_boot_arg;
  494. int mtk_wdt_boot_check(void)
  495. {
  496. int boot_reason;
  497. if (g_boot_arg->maggic_number == BOOT_ARGUMENT_MAGIC) {
  498. boot_reason = g_boot_arg->boot_reason;
  499. WDTLOG("WDT get boot reason is %d from pre-loader\n", boot_reason);
  500. if (boot_reason == BR_WDT) {
  501. return WDT_NORMAL_REBOOT;
  502. } else if (boot_reason == BR_WDT_BY_PASS_PWK || BR_KERNEL_PANIC == boot_reason || BR_WDT_SW == boot_reason || BR_WDT_HW == boot_reason) {
  503. return WDT_BY_PASS_PWK_REBOOT;
  504. } else {
  505. return WDT_NOT_WDT_REBOOT;
  506. }
  507. }
  508. return WDT_NOT_WDT_REBOOT;
  509. }
  510. void mtk_arch_reset(char mode)
  511. {
  512. WDTLOG("mtk_arch_reset\n");
  513. mtk_wdt_reset(mode);
  514. while (1);
  515. }
  516. void mtk_arch_full_reset(void)
  517. {
  518. #ifdef MTK_PMIC_FULL_RESET
  519. /* save pl lk log to expdb before pmic full reset*/
  520. save_pllk_log();
  521. WDTCRI("mtk_arch_full_reset\n");
  522. /* PMIC full reset will happen (reset immediately) inside. */
  523. pmic_cold_reset();
  524. while (1);
  525. #else
  526. WDTCRI("mtk_arch_full_reset: PMIC full reset is not supported.\n");
  527. #endif
  528. }
  529. void wdt_check_exception(void)
  530. {
  531. unsigned int reg = DRV_Reg32(MTK_WDT_NONRST_REG);
  532. DRV_WriteReg32(MTK_WDT_NONRST_REG, 0);
  533. if (((reg & (~MTK_WDT_STATUS_SWWDT_RST)) || DRV_Reg32(MTK_WDT_STATUS)) && (g_boot_mode != FASTBOOT))
  534. mtk_arch_full_reset();
  535. }
  536. void rgu_swsys_reset(WD_SYS_RST_TYPE reset_type)
  537. {
  538. if (reset_type == WD_MD_RST) {
  539. unsigned int wdt_dbg_ctrl;
  540. wdt_dbg_ctrl = DRV_Reg32(MTK_WDT_SWSYSRST);
  541. wdt_dbg_ctrl |= MTK_WDT_SWSYS_RST_KEY;
  542. wdt_dbg_ctrl |= 0x80;/* 1<<7 */
  543. DRV_WriteReg32(MTK_WDT_SWSYSRST, wdt_dbg_ctrl);
  544. udelay(1000);
  545. wdt_dbg_ctrl = DRV_Reg32(MTK_WDT_SWSYSRST);
  546. wdt_dbg_ctrl |= MTK_WDT_SWSYS_RST_KEY;
  547. wdt_dbg_ctrl &= (~0x80);/* ~(1<<7) */
  548. DRV_WriteReg32(MTK_WDT_SWSYSRST, wdt_dbg_ctrl);
  549. dprintf(CRITICAL, "fwq rgu lk md reset\n");
  550. }
  551. }
  552. void rgu_release_rg_mcu_pwr_on(void)
  553. {
  554. unsigned int wdt_dbg_ctrl;
  555. wdt_dbg_ctrl = DRV_Reg32(MTK_WDT_DEBUG_CTL);
  556. wdt_dbg_ctrl &= (~MTK_RG_MCU_PWR_ON);
  557. wdt_dbg_ctrl |= MTK_DEBUG_CTL_KEY;
  558. DRV_WriteReg32(MTK_WDT_DEBUG_CTL, wdt_dbg_ctrl);
  559. WDTLOG("RGU %s:MTK_WDT_DEBUG_CTL(%x)\n", __func__, wdt_dbg_ctrl);
  560. }
  561. void rgu_release_rg_mcu_pwr_iso_dis(void)
  562. {
  563. unsigned int wdt_dbg_ctrl;
  564. wdt_dbg_ctrl = DRV_Reg32(MTK_WDT_DEBUG_CTL);
  565. wdt_dbg_ctrl &= (~MTK_RG_MCU_PWR_ISO_DIS);
  566. wdt_dbg_ctrl |= MTK_DEBUG_CTL_KEY;
  567. DRV_WriteReg32(MTK_WDT_DEBUG_CTL, wdt_dbg_ctrl);
  568. WDTLOG("RGU %s:MTK_WDT_DEBUG_CTL(%x)\n", __func__, wdt_dbg_ctrl);
  569. }
  570. #else
  571. void mtk_wdt_init(void)
  572. {
  573. WDTLOG("WDT Dummy init called\n");
  574. }
  575. BOOL mtk_is_rgu_trigger_reset(void)
  576. {
  577. WDTLOG("Dummy mtk_is_rgu_trigger_reset called\n");
  578. return FALSE;
  579. }
  580. void mtk_arch_reset(char mode)
  581. {
  582. WDTLOG("WDT Dummy arch reset called\n");
  583. }
  584. void mtk_arch_full_reset(void)
  585. {
  586. WDTLOG("WDT Dummy arch full reset called\n");
  587. }
  588. void wdt_check_exception(void)
  589. {
  590. WDTLOG("WDT Dummy check exception called\n");
  591. }
  592. int mtk_wdt_boot_check(void)
  593. {
  594. WDTLOG("WDT Dummy mtk_wdt_boot_check called\n");
  595. return WDT_NOT_WDT_REBOOT;
  596. }
  597. unsigned char mtk_wdt_restart_reason()
  598. {
  599. WDTLOG("WDT Dummy mtk_wdt_restart_reason called\n");
  600. }
  601. void mtk_wdt_disable(void)
  602. {
  603. WDTLOG("WDT Dummy mtk_wdt_disable called\n");
  604. }
  605. const char *mtk_wdt_get_last_stage(void)
  606. {
  607. return "rst from: not supported";
  608. }
  609. void mtk_wdt_restart(void)
  610. {
  611. WDTLOG("WDT Dummy mtk_wdt_restart called\n");
  612. }
  613. static void mtk_wdt_sw_reset(void)
  614. {
  615. WDTLOG("WDT Dummy mtk_wdt_sw_reset called\n");
  616. }
  617. static void mtk_wdt_hw_reset(void)
  618. {
  619. WDTLOG("WDT Dummy mtk_wdt_hw_reset called\n");
  620. }
  621. void rgu_swsys_reset(WD_SYS_RST_TYPE reset_type)
  622. {
  623. WDTLOG("WDT Dummy rgu_swsys_reset called\n");
  624. }
  625. void rgu_release_rg_mcu_pwr_on(void)
  626. {
  627. WDTLOG("WDT Dummy %s called\n", __func__);
  628. }
  629. void rgu_release_rg_mcu_pwr_iso_dis(void)
  630. {
  631. WDTLOG("WDT Dummy %s called\n", __func__);
  632. }
  633. #endif