blob: 0621cb492d461405eb902c1e087aedacaf5aeacc [file] [log] [blame]
/*******************************************************************************
* 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*/
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;
}