/******************************************************************************* | |
* 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; | |
} | |