1195 lines
34 KiB
C
1195 lines
34 KiB
C
/**
|
|
* @file sdrv_rstgen_drv.c
|
|
* @brief semidrive reset driver
|
|
*
|
|
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
#include <armv7-r/barriers.h>
|
|
#include <types.h>
|
|
#include <bits.h>
|
|
#include <debug.h>
|
|
#include <reg.h>
|
|
#include <regs_base.h>
|
|
#include <part.h>
|
|
|
|
#include "sdrv_rstgen.h"
|
|
#include "sdrv_rstgen_hw.h"
|
|
#include "sdrv_recovery_hw.h"
|
|
#include "sdrv_common.h"
|
|
#include "udelay/udelay.h"
|
|
|
|
#define RSTGEN_POLLs 0x10000
|
|
|
|
/**
|
|
* @brief sdrv rstgen core control
|
|
*
|
|
* Control core processor, set core running on/off.
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] core_idx core index
|
|
* @param[in] run_mode run mode bit
|
|
*/
|
|
static status_t sdrv_rstgen_core_control(paddr_t base, uint32_t core_idx,
|
|
bool run_mode)
|
|
{
|
|
uint32_t core_rst_en = base + CORE_RESET_RS_OFF(core_idx);
|
|
uint32_t core_sw_rst = base + CORE_RESET_CONTROL_OFF(core_idx);
|
|
|
|
/* Check the reset lock bit */
|
|
if (readl(core_rst_en) & (0x1u << CORE_RESET_RS_LOCK))
|
|
return SDRV_RESET_STATUS_LOCK;
|
|
|
|
/* Check core SW reset status */
|
|
if (run_mode && (readl(core_sw_rst) & (0x1u << CORE_RESET_CONTROL_RSTA)))
|
|
return SDRV_STATUS_OK;
|
|
|
|
if (!run_mode && !(readl(core_sw_rst) & (0x1u << CORE_RESET_CONTROL_RSTA)))
|
|
return SDRV_STATUS_OK;
|
|
|
|
/* Set core run mode. */
|
|
RMWREG32(core_sw_rst, CORE_RESET_CONTROL_RUN_MODE, 1, run_mode);
|
|
|
|
/* Wait reset done. */
|
|
while (run_mode != ((readl(core_sw_rst) >> CORE_RESET_CONTROL_RSTA) & 0x1u));
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen core reset
|
|
*
|
|
* Reset core processor.
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] core_idx core index
|
|
*/
|
|
static status_t sdrv_rstgen_core_reset(paddr_t base, uint32_t core_idx)
|
|
{
|
|
uint32_t tms = 0;
|
|
uint32_t core_rst = base + CORE_RESET_CONTROL_OFF(core_idx);
|
|
|
|
uint32_t val = readl(core_rst);
|
|
|
|
if (val & (1 << CORE_RESET_CONTROL_RSTA)) {
|
|
DSB;
|
|
ISB;
|
|
|
|
/* Auto clear reset when the core is already running */
|
|
writel(val | (1 << CORE_RESET_CONTROL_AUTO_CLR_RST_B), core_rst);
|
|
|
|
/* Trigger auto clear reset */
|
|
while (readl(core_rst) & (1 << CORE_RESET_CONTROL_AUTO_CLR_RST_B)) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
/* Set running mode when the core is off */
|
|
writel(val | (1 << CORE_RESET_CONTROL_RUN_MODE), core_rst);
|
|
|
|
/* Trigger real time reset status */
|
|
while (0 == (readl(core_rst) & (1 << CORE_RESET_CONTROL_RSTA))) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen auto clr rst
|
|
*
|
|
* some module .e SEIP , diff with other modules, must auto clr before set
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] module_idx module index
|
|
*/
|
|
static status_t sdrv_rstgen_module_clr_rst(paddr_t base, uint32_t module_idx)
|
|
{
|
|
uint32_t module_rst = base + MODULE_RESET_CONTROL_OFF(module_idx);
|
|
uint32_t val = readl(module_rst);
|
|
|
|
val |= 1 << MODULE_RESET_CONTROL_AUTO_CLR_RST_B;
|
|
|
|
writel(val, module_rst);
|
|
|
|
udelay(2);
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
/**
|
|
* @brief sdrv rstgen module control
|
|
*
|
|
* Reset IP module, each module must be reset before used.
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] module_idx module index
|
|
* @param[in] run_mode 0:module off, 1:module on
|
|
*/
|
|
static status_t sdrv_rstgen_module_control(paddr_t base, uint32_t module_idx,
|
|
bool run_mode)
|
|
{
|
|
uint32_t tms = 0;
|
|
uint32_t module_rst = base + MODULE_RESET_CONTROL_OFF(module_idx);
|
|
uint32_t val = readl(module_rst);
|
|
|
|
if (((val >> MODULE_RESET_CONTROL_RUN_MODE) & 0x1) == run_mode) {
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
if (run_mode) {
|
|
val |= 1 << MODULE_RESET_CONTROL_RUN_MODE;
|
|
}
|
|
else {
|
|
val &= ~(1 << MODULE_RESET_CONTROL_RUN_MODE);
|
|
}
|
|
|
|
writel(val, module_rst);
|
|
|
|
if (run_mode)
|
|
while (!(readl(module_rst) & (0x1u << MODULE_RESET_CONTROL_RSTA))) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
else
|
|
while (readl(module_rst) & (0x1u << MODULE_RESET_CONTROL_RSTA)) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen mission control
|
|
*
|
|
* ALl the missions are reset automatically when SOC is power on.
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] mission_idx mission index
|
|
* @param[in] run_mode 0:misson off, 1:misson on
|
|
*/
|
|
static status_t sdrv_rstgen_mission_control(paddr_t base, uint32_t mission_idx,
|
|
bool run_mode)
|
|
{
|
|
uint32_t tms = 0;
|
|
uint32_t mission_rst = base + MISSION_RESET_CONTROL_OFF(mission_idx);
|
|
|
|
uint32_t val = readl(mission_rst);
|
|
|
|
if (((val >> MISSION_RESET_CONTROL_RUN_MODE) & 0x1) == run_mode) {
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
if (run_mode) {
|
|
val |= (0x1u << MISSION_RESET_CONTROL_RUN_MODE);
|
|
}
|
|
else {
|
|
val &= ~(0x1u << MISSION_RESET_CONTROL_RUN_MODE);
|
|
}
|
|
|
|
writel(val, mission_rst);
|
|
|
|
if (run_mode) {
|
|
while (!(readl(mission_rst) & (1 << MISSION_RESET_CONTROL_RSTA))) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
while ((readl(mission_rst) & (1 << MISSION_RESET_CONTROL_RSTA))) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen latent control
|
|
*
|
|
* ALl the latents are reset automatically when SOC is power on.
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] latent_idx latent index
|
|
* @param[in] run_mode 0:latent on, 1:latent off
|
|
*/
|
|
static status_t sdrv_rstgen_latent_control(paddr_t base, uint32_t latent_idx,
|
|
bool run_mode)
|
|
{
|
|
uint32_t tms = 0;
|
|
uint32_t latent_rst = base + LATENT_RESET_CONTROL_OFF(latent_idx);
|
|
|
|
uint32_t val = readl(latent_rst);
|
|
|
|
if (((val >> LATENT_RESET_CONTROL_RUN_MODE) & 0x1) == run_mode) {
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
if (val & (0x1u << LATENT_RESET_CONTROL_LOCK)) {
|
|
return SDRV_RESET_STATUS_LOCK;
|
|
}
|
|
|
|
if (run_mode) {
|
|
val |= (0x1u << LATENT_RESET_CONTROL_RUN_MODE);
|
|
}
|
|
else {
|
|
val &= ~(0x1u << LATENT_RESET_CONTROL_RUN_MODE);
|
|
}
|
|
|
|
writel(val, latent_rst);
|
|
|
|
if (run_mode) {
|
|
while (!(readl(latent_rst) & (1 << LATENT_RESET_CONTROL_RSTA))) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
while (readl(latent_rst) & (1 << LATENT_RESET_CONTROL_RSTA)) {
|
|
if (tms++ > RSTGEN_POLLs) {
|
|
return SDRV_RESET_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen get core reset status
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] core_idx core index
|
|
* @return 1, the core reset has be released.
|
|
* 0, the core reset hasn't be released.
|
|
*/
|
|
static int32_t sdrv_rstgen_get_core_reset_status(paddr_t base,
|
|
uint32_t core_idx)
|
|
{
|
|
uint32_t core_rst = base + CORE_RESET_CONTROL_OFF(core_idx);
|
|
|
|
return !!(readl(core_rst) & (0x1u << MODULE_RESET_CONTROL_RSTA));
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen get module reset status
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] module_idx module index
|
|
* @return 1, the module reset has be released.
|
|
* 0, the module reset hasn't be released.
|
|
*/
|
|
static int32_t sdrv_rstgen_get_module_reset_status(paddr_t base,
|
|
uint32_t module_idx)
|
|
{
|
|
uint32_t module_rst = base + MODULE_RESET_CONTROL_OFF(module_idx);
|
|
|
|
/* RSTGEN_MODULE_RST_STA, 0 = reset, 1 = release. */
|
|
return !!(readl(module_rst) & (0x1u << MODULE_RESET_CONTROL_RSTA));
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen get mission reset status
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] mission_idx mission index
|
|
* @return 1, the mission reset has be released.
|
|
* 0, the mission reset hasn't be released.
|
|
*/
|
|
static int32_t sdrv_rstgen_get_mission_reset_status(paddr_t base,
|
|
uint32_t mission_idx)
|
|
{
|
|
uint32_t mission_rst = base + MISSION_RESET_CONTROL_OFF(mission_idx);
|
|
|
|
/* RSTGEN_MODULE_RST_STA, 0 = reset, 1 = release. */
|
|
return !!(readl(mission_rst) & (0x1u << MISSION_RESET_CONTROL_RSTA));
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv rstgen get latent reset status
|
|
*
|
|
* @param[in] base sdrv rstgen address
|
|
* @param[in] latent_idx latent index
|
|
* @return 1, the latent reset has be released.
|
|
* 0, the latent reset hasn't be released.
|
|
*/
|
|
static int32_t sdrv_rstgen_get_latent_reset_status(paddr_t base,
|
|
uint32_t latent_idx)
|
|
{
|
|
uint32_t latent_rst = base + LATENT_RESET_CONTROL_OFF(latent_idx);
|
|
|
|
/* RSTGEN_MODULE_RST_STA, 0 = reset, 1 = release. */
|
|
return !!(readl(latent_rst) & (0x1u << LATENT_RESET_CONTROL_RSTA));
|
|
}
|
|
|
|
static void sdrv_rstgen_set_ist_reset_by_mode(paddr_t base, uint32_t index,
|
|
uint32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= IST_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + IST_RESET_CONTROL_OFF, mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static void sdrv_rstgen_set_mission_reset_by_mode(paddr_t base, uint32_t index,
|
|
uint32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= MISSION_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + MISSION_RESET_CONTROL_OFF(index), mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static void sdrv_rstgen_set_latent_reset_by_mode(paddr_t base, uint32_t index,
|
|
int32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= LATENT_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + LATENT_RESET_CONTROL_OFF(index), mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static void sdrv_rstgen_set_module_reset_by_mode(paddr_t base, uint32_t index,
|
|
uint32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= MODULE_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + MODULE_RESET_CONTROL_OFF(index), mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static void sdrv_rstgen_set_core_reset_by_mode(paddr_t base, uint32_t index,
|
|
uint32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= CORE_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + CORE_RESET_CONTROL_OFF(index), mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static void sdrv_rstgen_set_debug_reset_by_mode(paddr_t base, uint32_t index,
|
|
uint32_t mode, uint32_t val)
|
|
{
|
|
if (mode <= DBG_RESET_CONTROL_SLP_MODE) {
|
|
RMWREG32(base + DBG_RESET_CONTROL_OFF, mode, 1, val & 0x1u);
|
|
}
|
|
}
|
|
|
|
static status_t sdrv_rstgen_release_ctl(sdrv_rstgen_t *rst_ctl, uint32_t id,
|
|
bool release)
|
|
{
|
|
int32_t ret = SDRV_STATUS_FAIL;
|
|
|
|
switch (SDRV_RSTGEN_TYPE(id)) {
|
|
case SDRV_RSTGEN_CORE:
|
|
ret = sdrv_rstgen_core_control(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id), release);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MODULE:
|
|
ret = sdrv_rstgen_module_control(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id), release);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MISSION:
|
|
ret = sdrv_rstgen_mission_control(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id), release);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_LATENT:
|
|
ret = sdrv_rstgen_latent_control(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id), release);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Assert a reset signal.
|
|
*
|
|
* The reset singal will stay asserted until reset_deassert() is called.
|
|
*
|
|
* @param[in] rst_sig Reset signal.
|
|
* @return 0 if OK, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_assert(sdrv_rstgen_sig_t *rst_sig)
|
|
{
|
|
if (rst_sig == NULL) {
|
|
return SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
}
|
|
|
|
sdrv_rstgen_t *rst_ctl = rst_sig->rst_ctl;
|
|
uint32_t id = rst_sig->id;
|
|
|
|
if(rst_sig->pre_handler) {
|
|
rst_sig->pre_handler(rst_sig->id);
|
|
}
|
|
|
|
return sdrv_rstgen_release_ctl(rst_ctl, id, false);
|
|
}
|
|
|
|
/**
|
|
* @brief Deassert a reset signal.
|
|
*
|
|
* Release a reset signal.
|
|
*
|
|
* @param[in] rst_sig Reset signal.
|
|
* @return 0 if OK, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_deassert(sdrv_rstgen_sig_t *rst_sig)
|
|
{
|
|
status_t ret = SDRV_STATUS_OK;
|
|
|
|
if (rst_sig == NULL) {
|
|
return SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
}
|
|
|
|
sdrv_rstgen_t *rst_ctl = rst_sig->rst_ctl;
|
|
uint32_t id = rst_sig->id;
|
|
ret = sdrv_rstgen_release_ctl(rst_ctl, id, true);
|
|
|
|
if(rst_sig->post_handler) {
|
|
rst_sig->post_handler(rst_sig->id);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Reset a reset signal.
|
|
*
|
|
* Assert a reset signal, and then deassert it automatically.
|
|
*
|
|
* @param[in] rst_sig Reset signal.
|
|
* @return 0 if OK, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_reset(sdrv_rstgen_sig_t *rst_sig)
|
|
{
|
|
if (rst_sig == NULL) {
|
|
return SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
}
|
|
|
|
int32_t ret = SDRV_STATUS_FAIL;
|
|
sdrv_rstgen_t *sdrv_rst = rst_sig->rst_ctl;
|
|
uint32_t id = rst_sig->id;
|
|
|
|
if(rst_sig->pre_handler) {
|
|
rst_sig->pre_handler(rst_sig->id);
|
|
}
|
|
|
|
switch (SDRV_RSTGEN_TYPE(id)) {
|
|
case SDRV_RSTGEN_CORE:
|
|
ret = sdrv_rstgen_core_reset(sdrv_rst->base, SDRV_RSTGEN_INDEX(id));
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MODULE:
|
|
if (rst_sig->need_clr_rst) {
|
|
ret = sdrv_rstgen_module_clr_rst(sdrv_rst->base, SDRV_RSTGEN_INDEX(id));
|
|
|
|
if (ret == 0) {
|
|
ret = sdrv_rstgen_module_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), true);
|
|
}
|
|
}
|
|
else {
|
|
ret = sdrv_rstgen_module_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), false);
|
|
|
|
if (ret == 0) {
|
|
ret = sdrv_rstgen_module_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), true);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MISSION:
|
|
ret = sdrv_rstgen_mission_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), false);
|
|
|
|
if (ret == 0) {
|
|
ret = sdrv_rstgen_mission_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), true);
|
|
}
|
|
|
|
break;
|
|
|
|
case SDRV_RSTGEN_LATENT:
|
|
ret = sdrv_rstgen_latent_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), false);
|
|
|
|
if (ret == 0) {
|
|
ret = sdrv_rstgen_latent_control(
|
|
sdrv_rst->base, SDRV_RSTGEN_INDEX(id), true);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
ret = SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
break;
|
|
}
|
|
|
|
if(rst_sig->post_handler) {
|
|
rst_sig->post_handler(rst_sig->id);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Global reset.
|
|
*
|
|
* Global reset SF/AP domain
|
|
*
|
|
* @param[in] rst_glb_ctl Global reset controller.
|
|
* @return 0 if OK, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_global_reset(sdrv_rstgen_glb_t *rst_glb_ctl)
|
|
{
|
|
sdrv_rstgen_t *rst_sf_ctl = rst_glb_ctl->rst_sf_ctl;
|
|
|
|
if (rst_sf_ctl == NULL) {
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
RMWREG32(rst_sf_ctl->base + GLOBAL_RESET_CONTROL_OFF,
|
|
GLOBAL_RESET_CONTROL_SW_GLB_RST_EN, 1, 1);
|
|
|
|
RMWREG32(rst_sf_ctl->base + GLOBAL_RESET_CONTROL_OFF,
|
|
GLOBAL_RESET_CONTROL_SW_GLB_RST, 1, 1);
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Check reset signal status.
|
|
*
|
|
* @param[in] rst_sig Reset signal.
|
|
* @return 0 if deasserted, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_status(sdrv_rstgen_sig_t *rst_sig)
|
|
{
|
|
if (rst_sig == NULL) {
|
|
return SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
}
|
|
|
|
sdrv_rstgen_t *rst_ctl = rst_sig->rst_ctl;
|
|
uint32_t id = rst_sig->id;
|
|
int32_t ret = SDRV_STATUS_FAIL;
|
|
|
|
switch (SDRV_RSTGEN_TYPE(id)) {
|
|
case SDRV_RSTGEN_CORE:
|
|
ret = !sdrv_rstgen_get_core_reset_status(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id));
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MISSION:
|
|
ret = !sdrv_rstgen_get_mission_reset_status(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id));
|
|
break;
|
|
|
|
case SDRV_RSTGEN_LATENT:
|
|
ret = !sdrv_rstgen_get_latent_reset_status(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id));
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MODULE:
|
|
ret = !sdrv_rstgen_get_module_reset_status(
|
|
rst_ctl->base, SDRV_RSTGEN_INDEX(id));
|
|
break;
|
|
|
|
default:
|
|
ret = SDRV_RESET_STATUS_WRONG_SIGNAL;
|
|
break;
|
|
}
|
|
|
|
if (ret == 1) {
|
|
ret = SDRV_RESET_STATUS_SIGNAL_ASSERT;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Check global reset status.
|
|
*
|
|
* Global reset status for all the time,
|
|
* including each global reset status before clear or power off.
|
|
* If multiple reset source comes neatly the same time,
|
|
* only the first one will be recorded.
|
|
*
|
|
* @param[in] rst_glb_ctl Global reset controller.
|
|
* @return SF and AP domain global reset status.
|
|
* bit[31:25] for rstgen AP:
|
|
* bit[31] rstgen ap software global reset
|
|
* bit[30] reserved
|
|
* bit[29] efusec security violation
|
|
* bit[28] system panic(vdc function irq)
|
|
* bit[27] sem1/sem2 error
|
|
* bit[26] reserved
|
|
* bit[25] PT sensor interrupt
|
|
* bit[24:0] for rstgen SF:
|
|
* bit[24] wdt6 int reset request
|
|
* bit[23] wdt6 int reset request
|
|
* bit[22] wdt4 int reset request
|
|
* bit[21] wdt4 int reset request
|
|
* bit[20] wdt2 int reset request
|
|
* bit[19] reserved
|
|
* bit[18] wdt5 int reset request
|
|
* bit[17] wdt5 int reset request
|
|
* bit[16] wdt3 int reset request
|
|
* bit[15] wdt3 int reset request
|
|
* bit[14] wdt1 int reset request
|
|
* bit[13] reserved
|
|
* bit[12] ist done fail
|
|
* bit[11] rstgen sf software global reset
|
|
* bit[10] reserved
|
|
* bit[9] wdt2 int reset request (Only for E3104/E3106/E3205/E3206)
|
|
* bit[8] wdt1 int reset request (Only for E3104/E3106/E3205/E3206)
|
|
* bit[7] ist done fail (Only for E3104/E3106/E3205/E3206)
|
|
* bit[6] rstgen sf software global reset (Only for E3104/E3106/E3205/E3206)
|
|
* bit[5] rstgen ap cold reset request
|
|
* bit[4] efusec security violation
|
|
* bit[3] system panic(vdc function irq)
|
|
* bit[2] sem1/sem2 error
|
|
* bit[1] reserved
|
|
* bit[0] PT sensor interrupt
|
|
* Especially, bit[31:10] are invalid for E3104/E3106/E3205/E3206.
|
|
*/
|
|
uint32_t sdrv_rstgen_global_status(sdrv_rstgen_glb_t *rst_glb_ctl)
|
|
{
|
|
uint32_t status = 0;
|
|
sdrv_rstgen_t *rst_sf_ctl = rst_glb_ctl->rst_sf_ctl;
|
|
sdrv_rstgen_t *rst_ap_ctl = rst_glb_ctl->rst_ap_ctl;
|
|
|
|
if (rst_ap_ctl) {
|
|
status = (readl(rst_ap_ctl->base + GLOBAL_RESET_STA_ALL_OFF) & 0x7F) << 25;
|
|
}
|
|
|
|
if (rst_sf_ctl) {
|
|
status |= (readl(rst_sf_ctl->base + GLOBAL_RESET_STA_ALL_OFF) & 0x1FFFFFF);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief clear global reset status.
|
|
*
|
|
* Clear global reset status, otherwise the status will keep until power off.
|
|
*
|
|
* @param[in] rst_glb_ctl Global reset controller.
|
|
*/
|
|
status_t sdrv_rstgen_global_status_clear(sdrv_rstgen_glb_t *rst_glb_ctl)
|
|
{
|
|
sdrv_rstgen_t *rst_sf_ctl = rst_glb_ctl->rst_sf_ctl;
|
|
sdrv_rstgen_t *rst_ap_ctl = rst_glb_ctl->rst_ap_ctl;
|
|
|
|
if ((rst_sf_ctl == NULL) && (rst_ap_ctl == NULL)) {
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
if (rst_ap_ctl) {
|
|
writel(0, rst_ap_ctl->base + GLOBAL_RESET_STA_ALL_OFF);
|
|
}
|
|
|
|
if (rst_sf_ctl) {
|
|
writel(0, rst_sf_ctl->base + GLOBAL_RESET_STA_ALL_OFF);
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Check current global reset status.
|
|
*
|
|
* Global reset status only for the last time.
|
|
* If multiple reset source comes neatly the same time,
|
|
* only the first one will be recorded.
|
|
*
|
|
* @param[in] rst_glb_ctl Global reset controller.
|
|
* @return SF and AP domain current global reset status.
|
|
* bit[31:25] for rstgen AP:
|
|
* bit[31] rstgen ap software global reset
|
|
* bit[30] reserved
|
|
* bit[29] efusec security violation
|
|
* bit[28] system panic(vdc function irq)
|
|
* bit[27] sem1/sem2 error
|
|
* bit[26] reserved
|
|
* bit[25] PT sensor interrupt
|
|
* bit[24:0] for rstgen SF:
|
|
* bit[24] wdt6 int reset request
|
|
* bit[23] wdt6 int reset request
|
|
* bit[22] wdt4 int reset request
|
|
* bit[21] wdt4 int reset request
|
|
* bit[20] wdt2 int reset request
|
|
* bit[19] reserved
|
|
* bit[18] wdt5 int reset request
|
|
* bit[17] wdt5 int reset request
|
|
* bit[16] wdt3 int reset request
|
|
* bit[15] wdt3 int reset request
|
|
* bit[14] wdt1 int reset request
|
|
* bit[13] reserved
|
|
* bit[12] ist done fail
|
|
* bit[11] rstgen sf software global reset
|
|
* bit[10] reserved
|
|
* bit[9] wdt2 int reset request (Only for E3104/E3106/E3205/E3206)
|
|
* bit[8] wdt1 int reset request (Only for E3104/E3106/E3205/E3206)
|
|
* bit[7] ist done fail (Only for E3104/E3106/E3205/E3206)
|
|
* bit[6] rstgen sf software global reset (Only for E3104/E3106/E3205/E3206)
|
|
* bit[5] rstgen ap cold reset request
|
|
* bit[4] efusec security violation
|
|
* bit[3] system panic(vdc function irq)
|
|
* bit[2] sem1/sem2 error
|
|
* bit[1] reserved
|
|
* bit[0] PT sensor interrupt
|
|
* Especially, bit[31:10] are invalid for E3104/E3106/E3205/E3206.
|
|
*/
|
|
uint32_t sdrv_rstgen_current_global_status(sdrv_rstgen_glb_t *rst_glb_ctl)
|
|
{
|
|
uint32_t status = 0;
|
|
sdrv_rstgen_t *rst_sf_ctl = rst_glb_ctl->rst_sf_ctl;
|
|
sdrv_rstgen_t *rst_ap_ctl = rst_glb_ctl->rst_ap_ctl;
|
|
|
|
if (rst_ap_ctl) {
|
|
status = (readl(rst_ap_ctl->base + GLOBAL_RESET_STA_OFF) & 0x7F) << 25;
|
|
}
|
|
|
|
if (rst_sf_ctl) {
|
|
status |= (readl(rst_sf_ctl->base + GLOBAL_RESET_STA_OFF) & 0x1FFFFFF);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Read reset general reg.
|
|
*
|
|
* The data saved in general regs will be not lost until SOC power down.
|
|
*
|
|
* @param[in] rst_gen_reg reset general reg.
|
|
* @return general reg value.
|
|
*/
|
|
uint32_t sdrv_rstgen_read_general(sdrv_rstgen_general_reg_t *rst_gen_reg)
|
|
{
|
|
uint32_t ret = 0;
|
|
sdrv_rstgen_t *rst_ctl = rst_gen_reg->rst_ctl;
|
|
uint32_t id = rst_gen_reg->id;
|
|
|
|
if ((rst_ctl) && (id < SDRV_RSTGEN_GENERAL_REG_NUM)) {
|
|
ret = readl(rst_ctl->base + GENERAL_REG_OFF(id));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Write reset general reg.
|
|
*
|
|
* @param[in] rst_gen_reg reset general reg.
|
|
* @param[in] val write value.
|
|
* @return 0 if success,
|
|
* or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_write_general(sdrv_rstgen_general_reg_t *rst_gen_reg,
|
|
uint32_t val)
|
|
{
|
|
sdrv_rstgen_t *rst_ctl = rst_gen_reg->rst_ctl;
|
|
uint32_t id = rst_gen_reg->id;
|
|
|
|
if ((rst_ctl == NULL) || (id >= SDRV_RSTGEN_GENERAL_REG_NUM)) {
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
writel(val, rst_ctl->base + GENERAL_REG_OFF(id));
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Write reset general reg bit.
|
|
*
|
|
* @param[in] rst_gen_reg reset general reg.
|
|
* @param[in] start write start bit.
|
|
* @param[in] width write bit width.
|
|
* @param[in] val write value.
|
|
* @return 0 if success,
|
|
* or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_write_general_bit(sdrv_rstgen_general_reg_t *rst_gen_reg,
|
|
uint8_t start, uint8_t width, uint32_t val)
|
|
{
|
|
sdrv_rstgen_t *rst_ctl = rst_gen_reg->rst_ctl;
|
|
uint32_t id = rst_gen_reg->id;
|
|
|
|
if ((rst_ctl == NULL) || (id >= SDRV_RSTGEN_GENERAL_REG_NUM)
|
|
|| (start + width > 32)) {
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
RMWREG32(rst_ctl->base + GENERAL_REG_OFF(id), start, width, val);
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Config reset signal assert/deassert in lowpower mode.
|
|
*
|
|
* @param[in] rst_sig Reset signal.
|
|
* @param[in] mode lowpower mode
|
|
* @param[in] val 0:assert, 1:deassert
|
|
*
|
|
* @return 0 if OK, or a negative error code.
|
|
*/
|
|
status_t sdrv_rstgen_lowpower_set(sdrv_rstgen_sig_t *rst_sig,
|
|
enum reset_lowpower_mode mode, uint32_t val)
|
|
{
|
|
sdrv_rstgen_t *rst_ctl = rst_sig->rst_ctl;
|
|
uint32_t id = rst_sig->id;
|
|
uint32_t lp_mode;
|
|
|
|
if (rst_ctl == NULL) {
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
if (mode == RESET_LP_HIB) {
|
|
lp_mode = 1;
|
|
}
|
|
else {
|
|
lp_mode = 2;
|
|
}
|
|
|
|
switch (SDRV_RSTGEN_TYPE(id)) {
|
|
case SDRV_RSTGEN_CORE:
|
|
sdrv_rstgen_set_core_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MODULE:
|
|
sdrv_rstgen_set_module_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_MISSION:
|
|
sdrv_rstgen_set_mission_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_LATENT:
|
|
sdrv_rstgen_set_latent_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_IST:
|
|
sdrv_rstgen_set_ist_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
case SDRV_RSTGEN_DEBUG:
|
|
sdrv_rstgen_set_debug_reset_by_mode(rst_ctl->base, SDRV_RSTGEN_INDEX(id),
|
|
lp_mode, val);
|
|
break;
|
|
|
|
default:
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Config wdt cause global reset enable
|
|
*
|
|
* @param [in] wdt wdt id
|
|
* @param [in] enable true/false
|
|
* @return 0 if success, or a negative error code.
|
|
*/
|
|
#if CONFIG_E3 || CONFIG_D3
|
|
status_t sdrv_rstgen_wdt_reset_enable(reset_wdt_id_e wdt, bool enable)
|
|
{
|
|
switch (wdt) {
|
|
case RESET_WDT1:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 4, 1, 1);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 4, 1, 0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT2:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 12, 1, 1);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 12, 1, 0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT3:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 5, 2, 0x3);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 5, 2, 0x0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT4:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 13, 2, 0x3);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 13, 2, 0x0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT5:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 7, 2, 0x3);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 7, 2, 0x0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT6:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 15, 2, 0x3);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 15, 2, 0x0);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
status_t sdrv_rstgen_wdt_core_reset_enable(reset_wdt_id_e wdt, reset_core_id_e core, bool enable)
|
|
{
|
|
status_t ret = SDRV_STATUS_INVALID_PARAM;
|
|
uint32_t en_bit;
|
|
|
|
if (wdt == RESET_WDT1 || wdt == RESET_WDT3 || wdt == RESET_WDT5) {
|
|
en_bit = CORE_RESET_CONTROL_WDT1_RST_EN;
|
|
}
|
|
else {
|
|
en_bit = CORE_RESET_CONTROL_WDT2_RST_EN;
|
|
}
|
|
|
|
switch (wdt) {
|
|
case RESET_WDT1:
|
|
case RESET_WDT2:
|
|
if (core == RESET_CORE_SF) {
|
|
ret = SDRV_STATUS_OK;
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT3:
|
|
case RESET_WDT4:
|
|
if (core == RESET_CORE_SP0 || core == RESET_CORE_SP1) {
|
|
ret = SDRV_STATUS_OK;
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT5:
|
|
case RESET_WDT6:
|
|
if (core == RESET_CORE_SX0 || core == RESET_CORE_SX1) {
|
|
ret = SDRV_STATUS_OK;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (ret == SDRV_STATUS_OK) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + CORE_RESET_CONTROL_OFF(core),
|
|
en_bit, 1, enable);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_E3 || CONFIG_D3 */
|
|
|
|
#if CONFIG_E3L
|
|
status_t sdrv_rstgen_wdt_reset_enable(reset_wdt_id_e wdt, bool enable)
|
|
{
|
|
switch (wdt) {
|
|
case RESET_WDT1:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 3, 1, 1);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 3, 1, 0);
|
|
}
|
|
break;
|
|
|
|
case RESET_WDT2:
|
|
if (enable) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 11, 1, 1);
|
|
}
|
|
else {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + GLOBAL_RESET_CONTROL_OFF, 11, 1, 0);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return SDRV_STATUS_INVALID_PARAM;
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|
|
|
|
status_t sdrv_rstgen_wdt_core_reset_enable(reset_wdt_id_e wdt, reset_core_id_e core, bool enable)
|
|
{
|
|
status_t ret = SDRV_STATUS_INVALID_PARAM;
|
|
uint32_t en_bit;
|
|
|
|
if (wdt == RESET_WDT1) {
|
|
en_bit = CORE_RESET_CONTROL_WDT1_RST_EN;
|
|
}
|
|
else {
|
|
en_bit = CORE_RESET_CONTROL_WDT2_RST_EN;
|
|
}
|
|
|
|
switch (wdt) {
|
|
case RESET_WDT1:
|
|
case RESET_WDT2:
|
|
if (core == RESET_CORE_SF) {
|
|
ret = SDRV_STATUS_OK;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (ret == SDRV_STATUS_OK) {
|
|
RMWREG32(APB_RSTGEN_SF_BASE + CORE_RESET_CONTROL_OFF(core),
|
|
en_bit, 1, enable);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_E3L */
|
|
|
|
/**
|
|
* @brief recovery btm module.
|
|
*
|
|
* @param[in] base recovery btm module base addr
|
|
*/
|
|
static void sdrv_recovery_btm_module(uint32_t base)
|
|
{
|
|
/* disable G0 */
|
|
writel(0, base + BTM_G0_EN_OFFSET);
|
|
/* disable G1 */
|
|
writel(0, base + BTM_G1_EN_OFFSET);
|
|
/* disable int */
|
|
writel(0, base + BTM_INT_STA_EN_OFFSET);
|
|
writel(0, base + BTM_INT_SIG_EN_OFFSET);
|
|
/* clear int sta */
|
|
writel(0xF, base + BTM_INT_STA_OFFSET);
|
|
}
|
|
|
|
/**
|
|
* @brief recovery epwm module.
|
|
*
|
|
* @param[in] base recovery epwm module base addr
|
|
*/
|
|
static void sdrv_recovery_epwm_module(uint32_t base)
|
|
{
|
|
/* disable cmp module */
|
|
writel(0, base + EPWM_CMP_CTRL_OFFSET);
|
|
/* disable G0 */
|
|
writel(0, base + EPWM_G0_EN_OFFSET);
|
|
/* disable G1 */
|
|
writel(0, base + EPWM_G1_EN_OFFSET);
|
|
/* reset all counter and fifo to 0 */
|
|
writel(0x3FF, base + EPWM_SW_RST_OFFSET);
|
|
/* reset dma config */
|
|
writel(0, base + EPWM_DMA_CTRL_OFFSET);
|
|
/* disable int */
|
|
writel(0, base + EPWM_INT_STA_EN_OFFSET);
|
|
writel(0, base + EPWM_INT_SIG_EN_OFFSET);
|
|
/* clear int sta */
|
|
writel(0xFFFFFFFF, base + EPWM_INT_STA_OFFSET);
|
|
}
|
|
|
|
/**
|
|
* @brief recovery etimer module.
|
|
*
|
|
* @param[in] base recovery etimer module base addr
|
|
*/
|
|
static void sdrv_recovery_etimer_module(uint32_t base)
|
|
{
|
|
/* disable cpt module */
|
|
writel(0, base + ETIMER_CPT_CTRL_OFFSET);
|
|
/* disable cmp module */
|
|
writel(0, base + ETIMER_CMP_CTRL_OFFSET);
|
|
/* disable G0 */
|
|
writel(0, base + ETIMER_G0_EN_OFFSET);
|
|
/* disable G1 */
|
|
writel(0, base + ETIMER_G1_EN_OFFSET);
|
|
/* disable lcnt_a */
|
|
writel(0, base + ETIMER_LCNT_A_EN_OFFSET);
|
|
/* disable lcnt_b */
|
|
writel(0, base + ETIMER_LCNT_B_EN_OFFSET);
|
|
/* disable lcnt_c */
|
|
writel(0, base + ETIMER_LCNT_C_EN_OFFSET);
|
|
/* disable lcnt_d */
|
|
writel(0, base + ETIMER_LCNT_D_EN_OFFSET);
|
|
/* reset dma ctrl to 0 */
|
|
writel(0, base + ETIMER_DMA_CTRL_OFFSET);
|
|
/* reset all counter to 0 */
|
|
writel(0x3F, base + ETIMER_SW_RST_OFFSET);
|
|
/* disable int */
|
|
writel(0, base + ETIMER_INT_STA_EN_OFFSET);
|
|
writel(0, base + ETIMER_INT_SIG_EN_OFFSET);
|
|
/* clear int sta */
|
|
writel(0xFFFFFFFF, base + ETIMER_INT_STA_OFFSET);
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv recovery latent module.
|
|
*
|
|
* Some latent modules (btm/etimer/epwm etc.) will be not reset when core is reset,
|
|
* so these modules should be recovery when core restart.
|
|
*
|
|
* @param[in] recovery_module recovery latent module list
|
|
* @return 0 if success, or a negative error code.
|
|
*/
|
|
status_t sdrv_recovery_module(sdrv_recovery_module_t *recovery_module)
|
|
{
|
|
int i = 0;
|
|
|
|
for (i = 0; i < recovery_module->btm_list->btm_num; i++) {
|
|
sdrv_recovery_btm_module(recovery_module->btm_list->btm_base[i]);
|
|
}
|
|
|
|
for (i = 0; i < recovery_module->etimer_list->etimer_num; i++) {
|
|
sdrv_recovery_etimer_module(recovery_module->etimer_list->etimer_base[i]);
|
|
}
|
|
|
|
for (i = 0; i < recovery_module->epwm_list->epwm_num; i++) {
|
|
sdrv_recovery_epwm_module(recovery_module->epwm_list->epwm_base[i]);
|
|
}
|
|
|
|
return SDRV_STATUS_OK;
|
|
}
|