| /******************************************************************************* | |
| * Copyright (C) 2016, ZXIC Corporation. | |
| * | |
| * File Name: | |
| * File Mark: | |
| * Description: | |
| * Others: | |
| * Version: 1.0 | |
| * Author: zxic | |
| * Date: 2016.12.15 | |
| * modify | |
| ********************************************************************************/ | |
| /**************************************************************************** | |
| * Include files | |
| ****************************************************************************/ | |
| #include <malloc.h> | |
| #include <errno.h> | |
| #include <asm/io.h> | |
| #include <linux/mtd/mtd.h> | |
| #include <asm-generic/ioctl.h> | |
| #include <config.h> | |
| #include <common.h> | |
| #include <command.h> | |
| #include <boot_mode.h> | |
| #include <watchdog.h> | |
| #include <asm/arch/lsp_crpm.h> | |
| /**************************************************************************** | |
| * Local Macros | |
| ****************************************************************************/ | |
| /*used in wdt*/ | |
| #define WDT_DIABLE (0x44495341) /*ascii: DISA*/ | |
| #define WDT_OFF (0x57445446) //ascii:WDTF | |
| /*open and close wdt function for long time operation in boot.*/ | |
| #define RM_WDT_BASE (0x00148000) | |
| #define RM_WDT_START_REG (0x0014801C) /* Watchdog start or stop register */ | |
| #define WDT_RESET_TYPE (TOP_SYSCLK_BASE+0x2c) | |
| #define RM_MOD_RST (TOP_SYSCLK_BASE+0x74) | |
| #define reg32(addr) (*(volatile unsigned long *)(addr)) | |
| /**************************************************************************** | |
| * Local Types | |
| ****************************************************************************/ | |
| /**************************************************************************** | |
| * Global Value | |
| ****************************************************************************/ | |
| /**************************************************************************** | |
| * Local Funcs | |
| ****************************************************************************/ | |
| int wdt_open(void) | |
| { | |
| reg32(RM_WDT_START_REG) = 0x12340001;//open | |
| return 0; | |
| } | |
| int wdt_close(void) | |
| { | |
| reg32(RM_WDT_START_REG) = 0x12340000;//close | |
| return 0; | |
| } | |
| void wdt_restart(void) | |
| { | |
| volatile u32 tmp = 0; | |
| //reset | |
| reg32(WDT_RESET_TYPE) |= (0x3); | |
| //reg32(RM_MOD_RST) &=~(0x3<<12); | |
| //reg32(RM_MOD_RST) |=(0x3<<12); | |
| //clk sel default, clk div | |
| tmp =reg32(RM_WDT_BASE + 0x04); | |
| tmp &=~(0xff<<8); | |
| tmp |=(31<<8); | |
| reg32(RM_WDT_BASE + 0x04) = 0x12340000|tmp; | |
| /*set value int */ | |
| reg32(RM_WDT_BASE + 0x14) = 0x12340000|0x8; | |
| /*set load value*/ | |
| reg32(RM_WDT_BASE + 0x08) = 0x12340000|0x10; | |
| /*refresh config*/ | |
| tmp =reg32(RM_WDT_BASE + 0x18); | |
| tmp ^=0x3f; | |
| reg32(RM_WDT_BASE + 0x18) = 0x12340000|tmp; | |
| /*wait for refresh ack*/ | |
| while(1) | |
| { | |
| if(((reg32(RM_WDT_BASE + 0x10)>>4)&0x3f) == tmp) | |
| break; | |
| } | |
| /*start wdt*/ | |
| do{ | |
| reg32(RM_WDT_START_REG) =0x12340001; | |
| }while(1); | |
| } | |
| int wdt_get_reboot_reason(void) | |
| { | |
| if(reg32(WDT_REBOOT_RECORD_BASE) == 1) | |
| printf( "[sys_entry_wdt]: PS watchdog reset! global_cnt = %d; core_cnt = %d\n", (int)reg32(WDT_REBOOT_RECORD_BASE+0x8), (int)reg32(WDT_REBOOT_RECORD_BASE+0xc)); | |
| else if(reg32(WDT_REBOOT_RECORD_BASE) == 2) | |
| printf( "[sys_entry_wdt]: AP watchdog reset! global_cnt = %d; core_cnt = %d\n", (int)reg32(WDT_REBOOT_RECORD_BASE+0x8), (int)reg32(WDT_REBOOT_RECORD_BASE+0xc)); | |
| else if(reg32(WDT_REBOOT_RECORD_BASE) == 3) | |
| printf( "[sys_entry_wdt]: PHY watchdog reset! global_cnt = %d; core_cnt = %d\n", (int)reg32(WDT_REBOOT_RECORD_BASE+0x8), (int)reg32(WDT_REBOOT_RECORD_BASE+0xc)); | |
| else if(reg32(WDT_REBOOT_RECORD_BASE) == 4) | |
| printf( "[sys_entry_wdt]: Rpm watchdog reset! global_cnt = %d; core_cnt = %d\n", (int)reg32(WDT_REBOOT_RECORD_BASE+0x8), (int)reg32(WDT_REBOOT_RECORD_BASE+0xc)); | |
| else | |
| printf( "[sys_entry_wdt]: watchdog no reset!\n"); | |
| return 0; | |
| } | |
| int wdt_init(void) | |
| { | |
| unsigned int *poweron_type = (unsigned int *)POWERON_TYPE_ADDR; //ÁÙʱʹÓà | |
| /*ap wdt disbale*/ | |
| /*¸ù¾ÝÆô¶¯ÀàÐÍ£¬¹Ø±Õ²»¼ÓÔØºËµÄwatchdog*/ | |
| #ifndef CONFIG_ZX297520V3E_WATCH_CAP | |
| reg32(WDT_AP_SWITCH_ADDR) = WDT_DIABLE; // larry | |
| #endif | |
| //reg32(WDT_NV_ADDR) = WDT_OFF; | |
| if(*poweron_type == POWER_ON_FOTA) | |
| { | |
| /*turn off PS PHY AP watchdog monitor and close m0 wdt*/ | |
| reg32(WDT_NV_ADDR) = WDT_OFF; | |
| reg32(WDT_PS_SWITCH_ADDR) = WDT_DIABLE; | |
| reg32(WDT_PHY_SWITCH_ADDR) = WDT_DIABLE; | |
| reg32(WDT_AP_SWITCH_ADDR) = WDT_DIABLE; | |
| printf( "[sys_entry]: turn off PS PHY AP watchdog monitor and close m0 wdt! \n"); | |
| } | |
| else if(*poweron_type == POWER_ON_CHARGING) | |
| { | |
| /*turn off PHY watchdog monitor*/ | |
| reg32(WDT_PHY_SWITCH_ADDR) = WDT_DIABLE; | |
| printf( "[sys_entry]: turn off PHY watchdog monitor! \n"); | |
| } | |
| return 0; | |
| } | |