void mtk_wdt_init(void) { unsigned int tmp; unsigned int interval_val = DRV_Reg32(MTK_WDT_INTERVAL); mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE); printf("UB wdt init\n"); /* Update interval register value and check reboot flag */ if( (interval_val & RGU_TRIGGER_RESET_MASK) == IS_POWER_ON_RESET ) is_rgu_trigger_rst = 0; // Power off and power on reset else is_rgu_trigger_rst = 1; // RGU trigger reset interval_val &= ~(RGU_TRIGGER_RESET_MASK|MAGIC_NUM_MASK); interval_val |= (U_BOOT_MAGIC|IS_POWER_ON_RESET); /* Write back INTERVAL REG */ DRV_WriteReg32(MTK_WDT_INTERVAL, interval_val); /* Setting timeout 10s */ mtk_wdt_set_time_out_value(10); /*set spm_sysrst & pcm_wdt_rst to be reset mode*/ tmp = DRV_Reg32(MTK_WDT_REQ_IRQ_EN); tmp |= MTK_WDT_REQ_IRQ_EN_KEY; tmp &= ~(MTK_WDT_REQ_IRQ_EN_SPM | MTK_WDT_REQ_IRQ_EN_PCM); DRV_WriteReg32(MTK_WDT_REQ_IRQ_EN, tmp); mtk_wdt_mode_config(TRUE, TRUE, FALSE, FALSE, TRUE); mtk_wdt_restart(); }
void mtk_wdt_init(void) { unsigned int tmp; unsigned int nonrst; unsigned int interval_val = DRV_Reg32(MTK_WDT_INTERVAL); mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE); WDTLOG("UB wdt init\n"); /* Update interval register value and check reboot flag */ if( (interval_val & RGU_TRIGGER_RESET_MASK) == IS_POWER_ON_RESET ) is_rgu_trigger_rst = 0; // Power off and power on reset else is_rgu_trigger_rst = 1; // RGU trigger reset interval_val &= ~(RGU_TRIGGER_RESET_MASK|MAGIC_NUM_MASK); interval_val |= (U_BOOT_MAGIC|IS_POWER_ON_RESET); /* Write back INTERVAL REG */ DRV_WriteReg32(MTK_WDT_INTERVAL, interval_val); /* Setting timeout 10s */ mtk_wdt_set_time_out_value(10); #if (!LK_WDT_DISABLE) mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE); mtk_wdt_restart(); #endif /* * E3 ECO * reset will delay 2ms after set SW_WDT in register */ nonrst = DRV_Reg32(MTK_WDT_NONRST_REG); nonrst = (nonrst | (1<<29)); DRV_WriteReg32(MTK_WDT_NONRST_REG, nonrst); dprintf(CRITICAL,"WDT NONRST=0x%x \n\r", DRV_Reg32(MTK_WDT_NONRST_REG)); #if 0 int i=0; //lk wdt test while(1) { i++; mdelay(1000); WDTLOG("UB wdt test %d\n" ,i); /* Dump RGU regisers */ WDTLOG("==== fwq Dump RGU Reg ========\n"); WDTLOG("RGU MODE: %x\n", DRV_Reg32(MTK_WDT_MODE)); WDTLOG("RGU LENGTH: %x\n", DRV_Reg32(MTK_WDT_LENGTH)); WDTLOG("RGU STA: %x\n", DRV_Reg32(MTK_WDT_STATUS)); WDTLOG("RGU INTERVAL: %x\n", DRV_Reg32(MTK_WDT_INTERVAL)); WDTLOG("RGU SWSYSRST: %x\n", DRV_Reg32(MTK_WDT_SWSYSRST)); WDTLOG("==== Dump RGU Reg End ====\n"); if(i<60) { WDTLOG("kick lk ext\n" ); mtk_wdt_restart(); } } #endif }
void mtk_wd_suspend(void) { //mtk_wdt_ModeSelection(KAL_FALSE, KAL_FALSE, KAL_FALSE); // en debug, dis irq, dis ext, low pol, dis wdt mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, FALSE); mtk_wdt_restart(WD_TYPE_NORMAL); aee_sram_printk("[WDT] suspend\n"); printk("[WDT] suspend\n"); }
static int mtk_wk_wdt_config(enum ext_wdt_mode mode, int timeout_val) { mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE); mtk_wdt_set_time_out_value(timeout_val); #ifdef CONFIG_LOCAL_WDT mpcore_wk_wdt_config(0,mode,timeout_val); mpcore_wdt_set_heartbeat(timeout_val - 5);//local 25s time out #endif return 0; }
void mtk_wd_resume(void) { if ( g_wdt_enable == 1 ) { mtk_wdt_set_time_out_value(g_last_time_time_out_value); mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE); mtk_wdt_restart(WD_TYPE_NORMAL); } aee_sram_printk("[WDT] resume(%d)\n", g_wdt_enable); printk("[WDT] resume(%d)\n", g_wdt_enable); }
void mtk_wdt_init(void) { unsigned short interval_val = DRV_Reg16(MTK_WDT_INTERVAL); mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE); printf("UB wdt init\n"); /* Update interval register value and check reboot flag */ if( (interval_val & RGU_TRIGGER_RESET_MASK) == IS_POWER_ON_RESET ) is_rgu_trigger_rst = 0; // Power off and power on reset else is_rgu_trigger_rst = 1; // RGU trigger reset interval_val &= ~(RGU_TRIGGER_RESET_MASK|MAGIC_NUM_MASK); interval_val |= (U_BOOT_MAGIC|IS_POWER_ON_RESET); /* Write back INTERVAL REG */ DRV_WriteReg(MTK_WDT_INTERVAL, interval_val); /* Setting timeout 10s */ mtk_wdt_set_time_out_value(10); mtk_wdt_mode_config(TRUE, FALSE, FALSE, FALSE, TRUE); mtk_wdt_restart(); }
static void mtk_wdt_hw_reset(void) { printf("UB WDT_HW_Reset\n"); // 1. set WDT timeout 1 secs, 1*64*512/32768 = 1sec mtk_wdt_set_time_out_value(1); // 2. enable WDT debug reset enable, generating irq disable, ext reset disable // ext reset signal low, wdt enalbe mtk_wdt_mode_config(TRUE, FALSE, FALSE, FALSE, TRUE); // 3. reset the watch dog timer to the value set in WDT_LENGTH register mtk_wdt_restart(); // 4. system will reset while(1); }
static int set_mode(enum ext_wdt_mode mode) { printk(" support only irq mode-20140522"); switch (mode) { case WDT_DUAL_MODE: break; case WDT_HW_REBOOT_ONLY_MODE: break; case WDT_IRQ_ONLY_MODE: printk("wd set only irq mode for debug\n"); mtk_wdt_mode_config(FALSE, TRUE, TRUE, FALSE, TRUE); break; } return 0; }
/* * Device interface */ static int mtk_wdt_probe(struct platform_device *dev) { int ret=0; unsigned int interval_val; printk("******** MTK WDT driver probe!! ********\n" ); #ifndef __USING_DUMMY_WDT_DRV__ /* FPGA will set this flag */ #ifndef CONFIG_FIQ_GLUE printk("******** MTK WDT register irq ********\n" ); #ifdef CONFIG_KICK_SPM_WDT ret = spm_wdt_register_irq((irq_handler_t)mtk_wdt_isr); #else ret = request_irq(AP_RGU_WDT_IRQ_ID, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_FALLING, "mtk_watchdog", NULL); #endif //CONFIG_KICK_SPM_WDT #else printk("******** MTK WDT register fiq ********\n" ); #ifdef CONFIG_KICK_SPM_WDT ret = spm_wdt_register_fiq(wdt_fiq); #else ret = request_fiq(AP_RGU_WDT_IRQ_ID, wdt_fiq, IRQF_TRIGGER_FALLING, NULL); #endif //CONFIG_KICK_SPM_WDT #endif if(ret != 0) { printk( "mtk_wdt_probe : failed to request irq (%d)\n", ret); return ret; } printk("mtk_wdt_probe : Success to request irq\n"); #ifdef CONFIG_KICK_SPM_WDT spm_wdt_init(); #endif /* Set timeout vale and restart counter */ g_last_time_time_out_value=30; mtk_wdt_set_time_out_value(g_last_time_time_out_value); mtk_wdt_restart(WD_TYPE_NORMAL); /** * Set the reset lenght: we will set a special magic key. * For Power off and power on reset, the INTERVAL default value is 0x7FF. * We set Interval[1:0] to different value to distinguish different stage. * Enter pre-loader, we will set it to 0x0 * Enter u-boot, we will set it to 0x1 * Enter kernel, we will set it to 0x2 * And the default value is 0x3 which means reset from a power off and power on reset */ #define POWER_OFF_ON_MAGIC (0x3) #define PRE_LOADER_MAGIC (0x0) #define U_BOOT_MAGIC (0x1) #define KERNEL_MAGIC (0x2) #define MAGIC_NUM_MASK (0x3) #ifdef CONFIG_MTK_WD_KICKER // Initialize to dual mode printk("mtk_wdt_probe : Initialize to dual mode \n"); mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE); #else // Initialize to disable wdt printk("mtk_wdt_probe : Initialize to disable wdt \n"); mtk_wdt_mode_config(FALSE, FALSE, TRUE, FALSE, FALSE); g_wdt_enable =0; #endif /* Update interval register value and check reboot flag */ interval_val = DRV_Reg32(MTK_WDT_INTERVAL); interval_val &= ~(MAGIC_NUM_MASK); interval_val |= (KERNEL_MAGIC); /* Write back INTERVAL REG */ DRV_WriteReg32(MTK_WDT_INTERVAL, interval_val); #endif mtk_wdt_deglitch_en(); udelay(100); printk("mtk_wdt_probe : done WDT_MODE(%x), MTK_WDT_DEGLITCH_EN(%x)\n",DRV_Reg32(MTK_WDT_MODE),DRV_Reg32(MTK_WDT_DEGLITCH_EN)); printk("mtk_wdt_probe : done MTK_WDT_REQ_MODE(%x)\n",DRV_Reg32(MTK_WDT_REQ_MODE)); printk("mtk_wdt_probe : done MTK_WDT_REQ_IRQ_EN(%x)\n",DRV_Reg32(MTK_WDT_REQ_IRQ_EN)); return ret; }
int mtk_wdt_boot_check(void) { unsigned int wdt_sta = mtk_wdt_check_status(); #if 0 if (wdt_sta == MTK_WDT_STATUS_HWWDT_RST) { /* For E1 bug, that SW reset value is 0xC000, we using "==" to check */ /* Time out reboot always by pass power key */ print ("TO reset, need bypass power key\n"); return WDT_BY_PASS_PWK_REBOOT; } else if (wdt_sta & MTK_WDT_STATUS_SWWDT_RST) { #endif /* * For DA download hope to timeout reboot, and boot to u-boot/kernel configurable reason, * we set both timeout reboot and software reboot can check whether bypass power key. */ if (wdt_sta & (MTK_WDT_STATUS_HWWDT_RST|MTK_WDT_STATUS_SWWDT_RST|MTK_WDT_STATUS_PCMWDT_RST|MTK_WDT_STATUS_SPMWDT_RST)) { if (rgu_mode & MTK_WDT_MODE_AUTO_RESTART) { /* HW/SW reboot, and auto restart is set, means bypass power key */ print ("SW RST with bypass power key\n"); return WDT_BY_PASS_PWK_REBOOT; } else { print ("SW RST without bypass power key\n"); return WDT_NORMAL_REBOOT; } } return WDT_NOT_WDT_REBOOT; } void mtk_wdt_init(void) { #if defined(CONFIG_EMULATION_EARLY_PORTING) print("==== Dump RGU Reg ========\n"); print("RGU MODE: %x\n", DRV_Reg32(MTK_WDT_MODE)); print("RGU LENGTH: %x\n", DRV_Reg32(MTK_WDT_LENGTH)); print("RGU STA: %x\n", DRV_Reg32(MTK_WDT_STATUS)); print("RGU INTERVAL: %x\n", DRV_Reg32(MTK_WDT_INTERVAL)); print("==== Dump RGU Reg End ====\n"); DRV_WriteReg32(0x10007000, 0x22000000); //mt6572 emulation #else unsigned wdt_sta; /* Dump RGU regisers */ print("==== Dump RGU Reg ========\n"); print("RGU MODE: %x\n", DRV_Reg32(MTK_WDT_MODE)); print("RGU EN_FAST: %x\n", DRV_Reg32(MTK_WDT_EN_FAST)); print("RGU LENGTH: %x\n", DRV_Reg32(MTK_WDT_LENGTH)); print("RGU STA: %x\n", DRV_Reg32(MTK_WDT_STATUS)); print("RGU DRAM_CTL: %x\n", DRV_Reg32(MTK_WDT_DRAMC_CTL)); print("RGU INTERVAL: %x\n", DRV_Reg32(MTK_WDT_INTERVAL)); print("RGU FAST_SWSYSRST: %x\n", DRV_Reg32(MTK_WDT_FAST_SWSYSRST)); print("==== Dump RGU Reg End ====\n"); rgu_mode = DRV_Reg32(MTK_WDT_MODE); wdt_sta = mtk_wdt_check_status(); // This function will store the reset reason: Time out/ SW trigger if (((wdt_sta & MTK_WDT_STATUS_HWWDT_RST) || (wdt_sta & MTK_WDT_STATUS_PCMWDT_RST)) && (rgu_mode&MTK_WDT_MODE_AUTO_RESTART)) { /* For E1 bug, that SW reset value is 0xC000, we using "==" to check */ /* Time out reboot always by pass power key */ g_rgu_status = RE_BOOT_BY_WDT_HW; } else if (wdt_sta & MTK_WDT_STATUS_SWWDT_RST) { g_rgu_status = RE_BOOT_BY_WDT_SW; } else { g_rgu_status = RE_BOOT_REASON_UNKNOW; } if(wdt_sta & MTK_WDT_STATUS_IRQWDT_RST) { g_rgu_status |= RE_BOOT_WITH_INTTERUPT; } if(wdt_sta & MTK_WDT_STATUS_SPMWDT_RST) { g_rgu_status |= RE_BOOT_WITH_THERMAL; } if(wdt_sta & MTK_WDT_STATUS_PCMWDT_RST) { g_rgu_status |= RE_BOOT_BY_SPM; } print ("g_rgu_satus:%d\n", g_rgu_status); mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE); // Wirte Mode register will clear status register mtk_wdt_check_trig_reboot_reason(); /* Setting timeout 10s */ mtk_wdt_set_time_out_value(16); #ifdef CFG_APWDT_DISABLE /* Config HW reboot mode */ mtk_wdt_mode_config(TRUE, FALSE, TRUE, FALSE, TRUE); mtk_wdt_restart(); #endif mtk_wdt_reset_deglitch_enable(); #endif }
int mtk_wdt_boot_check(void) { unsigned int wdt_sta = mtk_wdt_check_status(); #if 0 if (wdt_sta == MTK_WDT_STATUS_HWWDT_RST) { /* For E1 bug, that SW reset value is 0xC000, we using "==" to check */ /* Time out reboot always by pass power key */ print ("TO reset, need bypass power key\n"); return WDT_BY_PASS_PWK_REBOOT; } else if (wdt_sta & MTK_WDT_STATUS_SWWDT_RST) { #endif /* * For DA download hope to timeout reboot, and boot to u-boot/kernel configurable reason, * we set both timeout reboot and software reboot can check whether bypass power key. */ if (wdt_sta & (MTK_WDT_STATUS_HWWDT_RST|MTK_WDT_STATUS_SWWDT_RST| MTK_WDT_STATUS_SPM_THERMAL_RST|MTK_WDT_STATUS_SPMWDT_RST| MTK_WDT_STATUS_THERMAL_DIRECT_RST|MTK_WDT_STATUS_SECURITY_RST |MTK_WDT_STATUS_DEBUGWDT_RST)) { if (rgu_mode & MTK_WDT_MODE_AUTO_RESTART) { /* HW/SW reboot, and auto restart is set, means bypass power key */ print ("SW reset with bypass power key flag\n"); return WDT_BY_PASS_PWK_REBOOT; } else { print ("SW reset without bypass power key flag\n"); return WDT_NORMAL_REBOOT; } } return WDT_NOT_WDT_REBOOT; } void mtk_wdt_init(void) { unsigned wdt_sta; unsigned int wdt_dbg_ctrl; unsigned int nonrst; /* Dump RGU regisers */ print("==== Dump RGU Reg ========\n"); print("RGU MODE: %x\n", DRV_Reg32(MTK_WDT_MODE)); print("RGU LENGTH: %x\n", DRV_Reg32(MTK_WDT_LENGTH)); print("RGU STA: %x\n", DRV_Reg32(MTK_WDT_STATUS)); print("RGU INTERVAL: %x\n", DRV_Reg32(MTK_WDT_INTERVAL)); print("RGU SWSYSRST: %x\n", DRV_Reg32(MTK_WDT_SWSYSRST)); print("==== Dump RGU Reg End ====\n"); rgu_mode = DRV_Reg32(MTK_WDT_MODE); wdt_sta = mtk_wdt_check_status(); // This function will store the reset reason: Time out/ SW trigger if ((wdt_sta & MTK_WDT_STATUS_HWWDT_RST)&&(rgu_mode&MTK_WDT_MODE_AUTO_RESTART)) { /* For E1 bug, that SW reset value is 0xC000, we using "==" to check */ /* Time out reboot always by pass power key */ g_rgu_status = RE_BOOT_BY_WDT_HW; } else if (wdt_sta & MTK_WDT_STATUS_SWWDT_RST) { g_rgu_status = RE_BOOT_BY_WDT_SW; } else { g_rgu_status = RE_BOOT_REASON_UNKNOW; } if(wdt_sta & MTK_WDT_STATUS_IRQWDT_RST) { g_rgu_status |= RE_BOOT_WITH_INTTERUPT; } if(wdt_sta & MTK_WDT_STATUS_SPM_THERMAL_RST) { g_rgu_status |= RE_BOOT_BY_SPM_THERMAL; } if(wdt_sta & MTK_WDT_STATUS_SPMWDT_RST) { g_rgu_status |= RE_BOOT_BY_SPM; } if(wdt_sta & MTK_WDT_STATUS_THERMAL_DIRECT_RST) { g_rgu_status |= RE_BOOT_BY_THERMAL_DIRECT; } if(wdt_sta & MTK_WDT_STATUS_DEBUGWDT_RST) { g_rgu_status |= RE_BOOT_BY_DEBUG; } if(wdt_sta & MTK_WDT_STATUS_SECURITY_RST) { g_rgu_status |= RE_BOOT_BY_SECURITY; } print ("RGU: g_rgu_satus:%d\n", g_rgu_status); mtk_wdt_mode_config(FALSE, FALSE, FALSE, FALSE, FALSE); // Wirte Mode register will clear status register mtk_wdt_check_trig_reboot_reason(); /* Setting timeout 10s */ mtk_wdt_set_time_out_value(16); #if (!CFG_APWDT_DISABLE) /* Config HW reboot mode */ mtk_wdt_mode_config(TRUE, TRUE, TRUE, FALSE, TRUE); mtk_wdt_restart(); #endif /* * E3 ECO * reset will delay 2ms after set SW_WDT in register */ nonrst = READ_REG(MTK_WDT_NONRST_REG); nonrst = (nonrst | (1<<29)); WRITE_REG(nonrst, MTK_WDT_NONRST_REG); print("WDT NONRST=0x%x\n", READ_REG(MTK_WDT_NONRST_REG)); // set mcu_lath_en requir by pl owner confirmed by RGU DE /*SW workaround close DEBUG IRQ for C2K*/ nonrst = READ_REG(MTK_WDT_REQ_IRQ_EN); nonrst &= (~(1<<19)); nonrst |= MTK_WDT_REQ_IRQ_KEY; WRITE_REG(nonrst, MTK_WDT_REQ_IRQ_EN); /*disable spm_thermal bit, becaue spm_thermal had been remove from HW*/ nonrst = READ_REG(MTK_WDT_REQ_IRQ_EN); nonrst &= (~(1<<0)); /*disale spm_thermal irq*/ nonrst |= MTK_WDT_REQ_IRQ_KEY; WRITE_REG(nonrst, MTK_WDT_REQ_IRQ_EN); print("WDT IRQ_EN=0x%x\n", READ_REG(MTK_WDT_REQ_IRQ_EN)); nonrst = READ_REG(MTK_WDT_REQ_MODE); nonrst &= (~(1<<0)); /*disale spm_thermal reset*/ nonrst |= 0x33000000; WRITE_REG(nonrst, MTK_WDT_REQ_MODE); print("WDT REQ_EN=0x%x\n", READ_REG(MTK_WDT_REQ_MODE)); wdt_dbg_ctrl = READ_REG(MTK_WDT_DEBUG_CTL); wdt_dbg_ctrl |= MTK_RG_MCU_LATH_EN; wdt_dbg_ctrl |= MTK_DEBUG_CTL_KEY; WRITE_REG(wdt_dbg_ctrl, MTK_WDT_DEBUG_CTL); print("RGU %s:MTK_WDT_DEBUG_CTL(%x)\n", __func__,wdt_dbg_ctrl); }