@@ -105,11 +105,13 @@ struct loadMonStruct {
u32 predDspFreq;
};
- enum SHM_DESCTYPE {
- SHM_CURROPP = 0,
- SHM_OPPINFO = 1,
- SHM_GETOPP = 2, /* Get DSP requested OPP info */
- } ;
+enum SHM_DESCTYPE {
+ SHM_CURROPP = 0,
+ SHM_OPPINFO = 1,
+ SHM_GETOPP = 2, /* Get DSP requested OPP info */
+ SHM_WDTOVF = 3, /* Set the WDT overflow time */
+ SHM_WDTCLOCKS = 4 /* Set/unset F/I WDT clocks flag */
+} ;
/* Structure in shared between DSP and PC for communication.*/
struct SHM {
@@ -133,8 +135,15 @@ struct loadMonStruct {
struct oppRqstStruct oppRequest;
/* load monitor information structure*/
struct loadMonStruct loadMonInfo;
- char dummy[184]; /* padding to 256 byte boundary */
- u32 shm_dbg_var[64]; /* shared memory debug variables */
+#ifdef CONFIG_BRIDGE_WDT3
+ /* Flag for WDT enable/disable F/I clocks */
+ u32 wdt_setclocks;
+ u32 wdt_overflow; /* WDT overflow time */
+ char dummy[176]; /* padding to 256 byte boundary */
+#else
+ char dummy[184]; /* padding to 256 byte boundary */
+#endif
+ u32 shm_dbg_var[64]; /* shared memory debug variables */
} ;
/* Channel Manager: only one created per board: */
@@ -102,6 +102,7 @@
#define DSP_SYSERROR 0x00000020
#define DSP_EXCEPTIONABORT 0x00000300
#define DSP_PWRERROR 0x00000080
+#define DSP_WDTOVERFLOW 0x00000040
/* IVA exception events (IVA MMU fault) */
#define IVA_MMUFAULT 0x00000040
@@ -168,25 +169,27 @@
/* Handy Macros */
#define IsValidProcEvent(x) (((x) == 0) || (((x) & (DSP_PROCESSORSTATECHANGE | \
- DSP_PROCESSORATTACH | \
- DSP_PROCESSORDETACH | \
- DSP_PROCESSORRESTART | \
- DSP_NODESTATECHANGE | \
- DSP_STREAMDONE | \
- DSP_STREAMIOCOMPLETION | \
- DSP_MMUFAULT | \
- DSP_SYSERROR | \
- DSP_PWRERROR)) && \
+ DSP_PROCESSORATTACH | \
+ DSP_PROCESSORDETACH | \
+ DSP_PROCESSORRESTART | \
+ DSP_NODESTATECHANGE | \
+ DSP_STREAMDONE | \
+ DSP_STREAMIOCOMPLETION | \
+ DSP_MMUFAULT | \
+ DSP_SYSERROR | \
+ DSP_PWRERROR | \
+ DSP_WDTOVERFLOW)) && \
!((x) & ~(DSP_PROCESSORSTATECHANGE | \
- DSP_PROCESSORATTACH | \
- DSP_PROCESSORDETACH | \
- DSP_PROCESSORRESTART | \
- DSP_NODESTATECHANGE | \
- DSP_STREAMDONE | \
- DSP_STREAMIOCOMPLETION | \
- DSP_MMUFAULT | \
- DSP_SYSERROR | \
- DSP_PWRERROR))))
+ DSP_PROCESSORATTACH | \
+ DSP_PROCESSORDETACH | \
+ DSP_PROCESSORRESTART | \
+ DSP_NODESTATECHANGE | \
+ DSP_STREAMDONE | \
+ DSP_STREAMIOCOMPLETION | \
+ DSP_MMUFAULT | \
+ DSP_SYSERROR | \
+ DSP_PWRERROR | \
+ DSP_WDTOVERFLOW))))
#define IsValidNodeEvent(x) (((x) == 0) || (((x) & (DSP_NODESTATECHANGE | \
DSP_NODEMESSAGEREADY)) && \
@@ -115,6 +115,9 @@
#define OMAP_DMMU_BASE 0x5D000000
#define OMAP_DMMU_SIZE 0x1000
+#define OMAP_WDT3_BASE 0x49030000
+#define OMAP_WDT3_SIZE 0x1000
+
#define OMAP_PRCM_VDD1_DOMAIN 1
#define OMAP_PRCM_VDD2_DOMAIN 2
@@ -63,6 +63,7 @@
/* TODO -- Remove, once BP defines them */
#define INT_MAIL_MPU_IRQ 26
#define INT_DSP_MMU_IRQ 28
+#define INT_WDT3_MPU_IRQ 36
struct dspbridge_platform_data {
void (*dsp_set_min_opp)(u8 opp_id);
@@ -52,6 +52,18 @@ config BRIDGE_CHECK_ALIGN_128
This can lead to heap corruption. Say Y, to enforce the check for 128
byte alignment, buffers failing this check will be rejected.
+config BRIDGE_WDT3
+ bool "Enable WDT3 interruptions"
+ depends on MPU_BRIDGE
+ default n
+ help
+ WTD3 is managed by DSP and once it is enabled, DSP side bridge is in
+ charge of refreshing the timer before overflow, if the DSP hangs MPU
+ will caught the interrupt and try to recover DSP.
+
+ NOTE: For recovery to happen, a client registered for such events
+ needs to be running as a background process.
+
comment "Bridge Notifications"
depends on MPU_BRIDGE
@@ -1364,7 +1364,8 @@ static DSP_STATUS RequestBridgeResourcesDSP(u32 dwContext, s32 bRequest)
OMAP_CORE_PRM_SIZE);
pResources->dwDmmuBase = ioremap(OMAP_DMMU_BASE,
OMAP_DMMU_SIZE);
- pResources->dwWdTimerDspBase = NULL;
+ pResources->dwWdTimerDspBase = ioremap(OMAP_WDT3_BASE,
+ OMAP_WDT3_BASE);
GT_1trace(curTrace, GT_2CLASS, "dwMemBase[0] 0x%x\n",
pResources->dwMemBase[0]);
old mode 100644
new mode 100755
@@ -1463,7 +1463,7 @@ DSP_STATUS PROC_RegisterNotify(DSP_HPROCESSOR hProcessor, u32 uEventMask,
/* Check if event mask is a valid processor related event */
if (uEventMask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | DSP_MMUFAULT |
- DSP_SYSERROR | DSP_PWRERROR))
+ DSP_SYSERROR | DSP_PWRERROR | DSP_WDTOVERFLOW))
status = DSP_EVALUE;
/* Check if notify type is valid */
@@ -1474,7 +1474,8 @@ DSP_STATUS PROC_RegisterNotify(DSP_HPROCESSOR hProcessor, u32 uEventMask,
/* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
* or DSP_PWRERROR then register event immediately. */
if (uEventMask &
- ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR)) {
+ ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
+ DSP_WDTOVERFLOW)) {
status = NTFY_Register(pProcObject->hNtfy,
hNotification, uEventMask, uNotifyType);
/* Special case alert, special case alert!
@@ -144,6 +144,18 @@ struct MAP_L4PERIPHERAL {
#define L4_PERIPHERAL_SIDETONE_MCBSP3 0x4902a000
#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000
+/* WDT defines */
+#define WDT3_ENABLE 0x1
+#define WDT3_DISABLE 0x0
+
+#define WDT_SYSCONFIG_OFFSET 0x10
+#define WDT_ISR_OFFSET 0x18
+#define WDT_IER_OFFSET 0x1C
+
+#define IVA2_WDT_SYSCFG (L4_PERIPHERAL_IVA2WDT + WDT_SYSCONFIG_OFFSET)
+#define IVA2_WDT_ISR (L4_PERIPHERAL_IVA2WDT + WDT_ISR_OFFSET)
+#define IVA2_WDT_IER (L4_PERIPHERAL_IVA2WDT + WDT_IER_OFFSET)
+
/* define a static array with L4 mappings */
static const struct MAP_L4PERIPHERAL L4PeripheralTable[] = {
{L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX},
@@ -346,6 +358,7 @@ struct WMD_DEV_CONTEXT {
void __iomem *sysctrlbase; /* SysCtrl mapped registers */
void __iomem *prmbase; /* PRM mapped registers */
void __iomem *perbase; /* PER mapped registers */
+ void __iomem *wdt3_base; /* WDT3 mapped registers */
u32 dwAPIClkBase; /* CLK Registers */
u32 dwDSPClkM2Base; /* DSP Clock Module m2 */
u32 dwPublicRhea; /* Pub Rhea */
@@ -384,5 +397,14 @@ extern DSP_STATUS WMD_TLB_DspVAToMpuPA(struct WMD_DEV_CONTEXT *pDevContext,
OUT u32 *ulPhysAddr,
OUT u32 *sizeTlb);
+#ifdef CONFIG_BRIDGE_WDT3
+/*
+ * ======== dsp_wdt_config ========
+ * Purpose:
+ * Enable and Disable wdt3.
+ */
+DSP_STATUS dsp_wdt_config(IN int dsp_WDT);
+#endif
+
#endif /* _TIOMAP_ */
@@ -109,6 +109,11 @@
#define MAX_PM_REQS 32
+/* ----------------------------------- WDT */
+#ifdef CONFIG_BRIDGE_WDT3
+extern u32 wtd3_enable;
+#endif
+
/* IO Manager: only one created per board: */
struct IO_MGR {
/* These four fields must be the first fields in a IO_MGR_ struct: */
@@ -130,6 +135,7 @@ struct IO_MGR {
u32 uSMBufSize; /* Size of a shared memory I/O channel */
bool fSharedIRQ; /* Is this IRQ shared? */
struct DPC_OBJECT *hDPC; /* DPC object handle */
+ struct DPC_OBJECT *hDPC_wdt; /* DPC object handle foe WDT */
struct SYNC_CSOBJECT *hCSObj; /* Critical section object handle */
u32 uWordSize; /* Size in bytes of DSP word */
u16 wIntrVal; /* interrupt value */
@@ -170,11 +176,17 @@ static u32 ReadData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest,
void *pSrc, u32 uSize);
static u32 WriteData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest,
void *pSrc, u32 uSize);
+
static struct workqueue_struct *bridge_workqueue;
#ifndef DSP_TRACEBUF_DISABLED
void PrintDSPDebugTrace(struct IO_MGR *hIOMgr);
#endif
+#ifdef CONFIG_BRIDGE_WDT3
+static irqreturn_t io_isr_wdt3(int irq, IN void *pRefData);
+static void io_wdt3_ovf(IN OUT void *pRefData);
+#endif
+
/* Bus Addr (cached kernel)*/
static DSP_STATUS registerSHMSegs(struct IO_MGR *hIOMgr,
struct COD_MANAGER *hCodMan,
@@ -206,6 +218,9 @@ DSP_STATUS WMD_IO_Create(OUT struct IO_MGR **phIOMgr,
struct CFG_HOSTRES hostRes;
struct CFG_DEVNODE *hDevNode;
struct CHNL_MGR *hChnlMgr;
+#ifdef CONFIG_BRIDGE_WDT3
+ u32 ack_wtd_int;
+#endif
static int ref_count;
u32 devType;
/* Check requirements: */
@@ -273,6 +288,11 @@ DSP_STATUS WMD_IO_Create(OUT struct IO_MGR **phIOMgr,
if (devType == DSP_UNIT) {
/* Create a DPC object: */
status = DPC_Create(&pIOMgr->hDPC, IO_DPC, (void *)pIOMgr);
+#ifdef CONFIG_BRIDGE_WDT3
+ if (DSP_SUCCEEDED(status))
+ status = DPC_Create(&pIOMgr->hDPC_wdt, io_wdt3_ovf,
+ (void *)pIOMgr);
+#endif
if (DSP_SUCCEEDED(status))
status = DEV_GetDevNode(hDevObject, &hDevNode);
@@ -290,12 +310,32 @@ DSP_STATUS WMD_IO_Create(OUT struct IO_MGR **phIOMgr,
if (devType == DSP_UNIT) {
HW_MBOX_initSettings(hostRes.dwMboxBase);
/* Plug the channel ISR:. */
- if ((request_irq(INT_MAIL_MPU_IRQ, IO_ISR, 0,
- "DspBridge\tmailbox", (void *)pIOMgr)) == 0)
- status = DSP_SOK;
- else
- status = DSP_EFAIL;
- }
+ if (request_irq(INT_MAIL_MPU_IRQ, IO_ISR, 0,
+ "DspBridge\tmailbox", (void *)pIOMgr))
+ status = DSP_EFAIL;
+ }
+#ifdef CONFIG_BRIDGE_WDT3
+ if (DSP_SUCCEEDED(status))
+ status = CLK_Enable(SERVICESCLK_wdt3_fck);
+ if (DSP_SUCCEEDED(status))
+ status = CLK_Enable(SERVICESCLK_wdt3_ick);
+ if (DSP_SUCCEEDED(status)) {
+ ack_wtd_int = __raw_readl(hostRes.dwWdTimerDspBase
+ + WDT_ISR_OFFSET);
+ /* ACK ISR if any */
+ __raw_writel(ack_wtd_int, hostRes.dwWdTimerDspBase
+ + WDT_ISR_OFFSET);
+ /* register WDT OVF Interrupt */
+ if (request_irq(INT_WDT3_MPU_IRQ, io_isr_wdt3,
+ IRQF_DISABLED, "DspBridge", (void *)pIOMgr))
+ status = DSP_EFAIL;
+ /* Disable interrupt, enable once DSP is running */
+ disable_irq(INT_WDT3_MPU_IRQ);
+ CLK_Disable(SERVICESCLK_wdt3_ick);
+ CLK_Disable(SERVICESCLK_wdt3_fck);
+ }
+#endif
+
if (DSP_SUCCEEDED(status))
DBG_Trace(DBG_LEVEL1, "ISR_IRQ Object 0x%x \n",
pIOMgr);
@@ -338,6 +378,12 @@ DSP_STATUS WMD_IO_Destroy(struct IO_MGR *hIOMgr)
free_irq(INT_MAIL_MPU_IRQ, (void *)hIOMgr);
if (hIOMgr->hDPC)
(void)DPC_Destroy(hIOMgr->hDPC);
+#ifdef CONFIG_BRIDGE_WDT3
+ /* Freeing WDT3 interrupt */
+ free_irq(INT_WDT3_MPU_IRQ, (void *)hIOMgr);
+ if (hIOMgr->hDPC_wdt)
+ (void)DPC_Destroy(hIOMgr->hDPC_wdt);
+#endif
#ifndef DSP_TRACEBUF_DISABLED
if (hIOMgr->pMsg)
MEM_Free(hIOMgr->pMsg);
@@ -798,6 +844,11 @@ func_cont:
DBG_Trace(DBG_LEVEL7, "** (proc) MAX MSGS IN SHARED MEMORY: "
"0x%x\n", hMsgMgr->uMaxMsgs);
memset((void *) hIOMgr->pSharedMem, 0, sizeof(struct SHM));
+#ifdef CONFIG_BRIDGE_WDT3
+ /* Setting the WDT timeout 6 seconds */
+ IO_SHMsetting(hIOMgr, SHM_WDTOVF, (void *)6);
+#endif
+
}
#ifndef DSP_TRACEBUF_DISABLED
if (DSP_SUCCEEDED(status)) {
@@ -1761,8 +1812,21 @@ DSP_STATUS IO_SHMsetting(IN struct IO_MGR *hIOMgr, IN enum SHM_DESCTYPE desc,
u32 i;
struct dspbridge_platform_data *pdata =
omap_dspbridge_dev->dev.platform_data;
-
+#endif
switch (desc) {
+#ifdef CONFIG_BRIDGE_WDT3
+ case SHM_WDTOVF:
+ /* Update the shared memory with WDT timeout */
+ if (hIOMgr->pSharedMem && (int)hIOMgr->pSharedMem != -1)
+ hIOMgr->pSharedMem->wdt_overflow = (u32)pArgs;
+ else
+ return DSP_EPOINTER;
+ break;
+ case SHM_WDTCLOCKS:
+ hIOMgr->pSharedMem->wdt_setclocks = (u32)pArgs;
+ break;
+#endif
+#ifdef CONFIG_BRIDGE_DVFS
case SHM_CURROPP:
/* Update the shared memory with requested OPP information */
if (pArgs != NULL)
@@ -1810,10 +1874,8 @@ DSP_STATUS IO_SHMsetting(IN struct IO_MGR *hIOMgr, IN enum SHM_DESCTYPE desc,
/* Get the OPP that DSP has requested */
*(u32 *)pArgs = hIOMgr->pSharedMem->oppRequest.rqstOppPt;
break;
- default:
- break;
- }
#endif
+ }
return DSP_SOK;
}
@@ -2076,3 +2138,42 @@ void IO_SM_init(void)
GT_create(&dsp_trace_mask, "DT"); /* DSP Trace Mask */
}
+
+#ifdef CONFIG_BRIDGE_WDT3
+/*
+ * ======== io_wdt3_ovf ========
+ * Deferred procedure call WDT overflow ISR. Carries
+ * out the dispatch of I/O as a non-preemptible event.It can only be
+ * pre-empted by an ISR.
+ */
+void io_wdt3_ovf(IN void *pRefData)
+{
+ struct DEH_MGR *hDehMgr;
+ struct IO_MGR *pIOMgr = (struct IO_MGR *)pRefData;
+ DEV_GetDehMgr(pIOMgr->hDevObject, &hDehMgr);
+ WMD_DEH_Notify(hDehMgr, DSP_WDTOVERFLOW, (u32)pIOMgr);
+}
+
+/*
+ * ======== io_isr_wdt3 ========
+
+ */
+irqreturn_t io_isr_wdt3(int irq, IN void *pRefData)
+{
+ u32 value;
+ struct IO_MGR *hIOMgr = (struct IO_MGR *)pRefData;
+ DBG_Trace(DBG_LEVEL3, "MPU:: WDT overflow ISR\n");
+ /* The pending interrupt event is cleared when the set status bit is
+ * overwritten by a value of 1 by a write command in the WTDi.WISR
+ * register. Reading the WTDi.WISR register and writing the value
+ * back allows a fast acknowledge interrupt process. */
+ if (CLK_Get_UseCnt(BPWR_Clks[4].funClk)) {
+ value = __raw_readl(hIOMgr->hWmdContext->wdt3_base
+ + WDT_ISR_OFFSET);
+ __raw_writel(value, hIOMgr->hWmdContext->wdt3_base
+ + WDT_ISR_OFFSET);
+ }
+ DPC_Schedule(hIOMgr->hDPC_wdt);
+ return IRQ_HANDLED;
+}
+#endif
@@ -1151,6 +1151,7 @@ static DSP_STATUS WMD_DEV_Create(OUT struct WMD_DEV_CONTEXT **ppDevContext,
pDevContext->sysctrlbase = resources.dwSysCtrlBase;
pDevContext->prmbase = resources.dwPrmBase;
pDevContext->perbase = resources.dwPerPmBase;
+ pDevContext->wdt3_base = resources.dwWdTimerDspBase;
}
if (DSP_SUCCEEDED(status)) {
pDevContext->hDevObject = hDevObject;
@@ -2101,3 +2102,50 @@ bool WaitForStart(struct WMD_DEV_CONTEXT *pDevContext, u32 dwSyncAddr)
}
return TRUE;
}
+#ifdef CONFIG_BRIDGE_WDT3
+/*
+ * ======== dsp_wdt_config ========
+ * Enables/disables WDT.
+ */
+DSP_STATUS dsp_wdt_config(IN int dsp_WDT)
+{
+ u32 ack_int;
+ struct DEV_OBJECT *dev_object;
+ struct WMD_DEV_CONTEXT *dev_ctxt;
+ struct IO_MGR *io_mgr;
+
+ dev_object = DEV_GetFirst();
+ if (!dev_object)
+ return DSP_EHANDLE;
+
+ DEV_GetWMDContext(dev_object, &dev_ctxt);
+ if (!dev_ctxt)
+ return DSP_EHANDLE;
+
+ DEV_GetIOMgr(dev_object, &io_mgr);
+ if (!io_mgr)
+ return DSP_EHANDLE;
+
+ switch (dsp_WDT) {
+ case WDT3_ENABLE:
+ DBG_Trace(DBG_LEVEL7, "Enable F/I WDT clocks\n");
+ if (DSP_FAILED(CLK_Enable(SERVICESCLK_wdt3_fck)))
+ return DSP_EFAIL;
+ if (DSP_FAILED(CLK_Enable(SERVICESCLK_wdt3_ick)))
+ return DSP_EFAIL;
+ IO_SHMsetting(io_mgr, SHM_WDTCLOCKS, (void *)1);
+ ack_int = __raw_readl(dev_ctxt->wdt3_base + WDT_ISR_OFFSET);
+ __raw_writel(ack_int, dev_ctxt->wdt3_base + WDT_ISR_OFFSET);
+ enable_irq(INT_WDT3_MPU_IRQ);
+ break;
+ case WDT3_DISABLE:
+ DBG_Trace(DBG_LEVEL7, "Disable F/I WDT clocks\n");
+ disable_irq(INT_WDT3_MPU_IRQ);
+ IO_SHMsetting(io_mgr, SHM_WDTCLOCKS, (void *)0);
+ CLK_Disable(SERVICESCLK_wdt3_ick);
+ CLK_Disable(SERVICESCLK_wdt3_fck);
+ break;
+ }
+ return DSP_SOK;
+}
+#endif
@@ -59,6 +59,11 @@
/* ----------------------------------- Mini Driver */
#include <dspbridge/wmddeh.h>
+/* ----------------------------------- WDT */
+#ifdef CONFIG_BRIDGE_WDT3
+u32 wtd3_enable;
+#endif
+
/* ----------------------------------- specific to this file */
#include "_tiomap.h"
#include "_tiomap_pwr.h"
@@ -158,7 +163,15 @@ DSP_STATUS handle_hibernation_fromDSP(struct WMD_DEV_CONTEXT *pDevContext)
mboxsetting.irqEnable1);
/* Turn off DSP Peripheral clocks and DSP Load monitor timer */
status = DSP_PeripheralClocks_Disable(pDevContext, NULL);
-
+#ifdef CONFIG_BRIDGE_WDT3
+ if (wtd3_enable) {
+ /*
+ * Disable WDT clocks and ISR on BSP commanded
+ * hibernation.
+ */
+ dsp_wdt_config(WDT3_DISABLE);
+ }
+#endif
if (DSP_SUCCEEDED(status)) {
/* Update the Bridger Driver state */
pDevContext->dwBrdState = BRD_DSP_HIBERNATION;
@@ -293,6 +306,15 @@ DSP_STATUS SleepDSP(struct WMD_DEV_CONTEXT *pDevContext, IN u32 dwCmd,
/* Turn off DSP Peripheral clocks */
status = DSP_PeripheralClocks_Disable(pDevContext, NULL);
+#ifdef CONFIG_BRIDGE_WDT3
+ if (wtd3_enable) {
+ /*
+ * Disable WDT clocks and ISR on BSP commanded
+ * hibernation.
+ */
+ dsp_wdt_config(WDT3_DISABLE);
+ }
+#endif
if (DSP_FAILED(status)) {
DBG_Trace(DBG_LEVEL7, "SleepDSP- FAILED\n");
return status;
@@ -26,6 +26,11 @@
#include "_tiomap.h"
#include "_tiomap_pwr.h"
+/* ----------------------------------- WDT */
+#ifdef CONFIG_BRIDGE_WDT3
+extern u32 wtd3_enable;
+#endif
+
#define MAILBOX_FIFOSTATUS(m) (0x80 + 4 * (m))
static inline unsigned int fifo_full(void __iomem *mbox_base, int mbox_id)
@@ -106,6 +111,10 @@ DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext,
#endif
/* Restart the peripheral clocks */
DSP_PeripheralClocks_Enable(pDevContext, NULL);
+#ifdef CONFIG_BRIDGE_WDT3
+ if (wtd3_enable && DSP_FAILED(dsp_wdt_config(WDT3_ENABLE)))
+ pr_err("WDT3 could not be enable\n");
+#endif
/*
* 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
@@ -288,6 +288,15 @@ DBG_Trace(DBG_LEVEL6, "WMD_DEH_Notify: DSP_MMUFAULT, "
"= 0x%x\n", dwErrInfo);
break;
#endif /* CONFIG_BRIDGE_NTFY_PWRERR */
+#ifdef CONFIG_BRIDGE_WDT3
+ case DSP_WDTOVERFLOW:
+ pDehMgr->errInfo.dwErrMask = DSP_WDTOVERFLOW;
+ pDehMgr->errInfo.dwVal1 = 0L;
+ pDehMgr->errInfo.dwVal2 = 0L;
+ pDehMgr->errInfo.dwVal3 = 0L;
+ pr_emerg("WMD_DEH_Notify: DSP_WDTOVERFLOW \n ");
+ break;
+#endif
default:
DBG_Trace(DBG_LEVEL6,
"WMD_DEH_Notify: Unknown Error, errInfo = "
@@ -313,6 +322,13 @@ DBG_Trace(DBG_LEVEL6, "WMD_DEH_Notify: DSP_MMUFAULT, "
(void)DSP_PeripheralClocks_Disable(pDevContext, NULL);
/* Call DSP Trace Buffer */
PrintDspTraceBuffer(hDehMgr->hWmdContext);
+#ifdef CONFIG_BRIDGE_WDT3
+ /*
+ * Avoid the subsequent WDT if it happens once,
+ * also If MMU fault occurs
+ */
+ dsp_wdt_config(WDT3_DISABLE);
+#endif
if (DSP_SUCCEEDED(status1)) {
/* Signal DSP error/exception event. */