This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM4376: Issue with Timer Cascading

Part Number: AM4376
Other Parts Discussed in Thread: AMIC120

Tool/software:

Dear TI Team,

I am trying to cascade DMTIMER2 and DMTIMER3 into a 64-bit timer as given in the Section 19.1.3.12 of "AM437x and AMIC120 ARM® Cortex-A9 Processors Technical Reference Manual".

The issue that I am facing at the moment is that the DMTIMER3 is not incrementing for the first 4 overflows of DMTIMER2. Afterwards, it increments each time the DMTIMER2 overflows. Please check the Log_DMTIMER.txt file where I have printed the outputs of the TCCR register of both the timers. DMTIMER2 starts at 164s and overflows after 171s. 

I have also attached the source files (dmtimer.h, hw_dmtimer.h, dmtimer.c) which I have used to configure the timer cascading. The source files are based on the PROCESSOR-SDK-RTOS-AM437X (Version: 06.03.00.106).

DMTimerInit() function from dmtimer.c sets up the relevant registers and starts the timers as shown in the screenshot below:

** DMTimer2 in seconds: 164
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 171
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 164								--> First overflow of DMTIMER2														
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 171								
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 164								--> Second overflow of DMTIMER2					
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 171								
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 164								--> Third overflow of DMTIMER2	
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 171								
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 164								--> Fourth overflow of DMTIMER2	
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 171
** DMTimer3 ticks (TCCR Register): 0x00000000
** DMTimer2 in seconds: 164								--> Fifth overflow of DMTIMER2	
** DMTimer3 ticks (TCCR Register): 0x00000001			--> DMTIMER3 is incremented
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 168
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 169
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 170
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 171
** DMTimer3 ticks (TCCR Register): 0x00000001
** DMTimer2 in seconds: 164
** DMTimer3 ticks (TCCR Register): 0x00000002
** DMTimer2 in seconds: 165
** DMTimer3 ticks (TCCR Register): 0x00000002
** DMTimer2 in seconds: 166
** DMTimer3 ticks (TCCR Register): 0x00000002
** DMTimer2 in seconds: 167
** DMTimer3 ticks (TCCR Register): 0x00000002

8546.dmtimer.hhw_dmtimer.h

/**
 *  \file   dmtimer.c
 *
 *  \brief  This file contains the device abstraction layer APIs for DMTimer.
 *          
 */

/*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*    Redistribution of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include "types.h"

#include <stdio.h>
// PM: ToDo: check which hw_types.h we would like to use - from starterware/hw or from csl
#include "ti/csl/hw_types.h"
//#include "ti/starterware/include/hw/hw_types.h"

#include "dmtimer.h"
/* ========================================================================== */
/*                           Macros & Typedefs                                */
/* ========================================================================== */
/**
* \brief Enumerates Values that can be used while checking status received from
*        function which returns posted write status.
*/
typedef enum dmtimerPostedWriteSts
{
    DMTIMER_POSTED_WRITE_STS_TMAR    = (DMTIMER_TWPS_W_PEND_TMAR_MASK),
    /**< Value used to check the write posted condition for TMAR register.*/
    DMTIMER_POSTED_WRITE_STS_TTGR    = (DMTIMER_TWPS_W_PEND_TTGR_MASK),
    /**< Value used to check the write posted condition for TTGR register.*/
    DMTIMER_POSTED_WRITE_STS_TLDR    = (DMTIMER_TWPS_W_PEND_TLDR_MASK),
    /**< Value used to check the write posted condition for TLDR register.*/
    DMTIMER_POSTED_WRITE_STS_TCRR    = (DMTIMER_TWPS_W_PEND_TCRR_MASK),
    /**< Value used to check the write posted condition for TCRR register.*/    
    DMTIMER_POSTED_WRITE_STS_TCLR    = (DMTIMER_TWPS_W_PEND_TCLR_MASK)
    /**< Value used to check the write posted condition for TCLR register.*/

}dmtimerPostedWriteSts_t;
/**
 * \brief   This macro will check for write POSTED status
 *
 * \param   reg - Register whose status has to be checked as defined by 
 *          # dmtimerPostedWriteSts_t      
 *          'reg' can be the following registers 
 *          DMTIMER_POSTED_WRITE_STS_TCLR - Timer Control register 
 *          DMTIMER_POSTED_WRITE_STS_TCRR - Timer Counter register 
 *          DMTIMER_POSTED_WRITE_STS_TLDR - Timer Load register 
 *          DMTIMER_POSTED_WRITE_STS_TTGR - Timer Trigger register 
 *          DMTIMER_POSTED_WRITE_STS_TMAR - Timer Match register 
 */
#define DMTIMER_WAIT_FOR_WRITE(baseAddr, reg)   \
    if(HW_RD_REG32(baseAddr + DMTIMER_TSICR) & DMTIMER_TSICR_POSTED_MASK)\
        while((reg & DMTIMERGetWritePostedStatus(baseAddr)));
/* ========================================================================== */
/*                         Structure Declarations                             */
/* ========================================================================== */
/* None */
/* ========================================================================== */
/*                          Function Definitions                              */
/* ========================================================================== */

void DMTIMEREnable(uint32_t baseAddr, uint32_t enableDmtimer)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    if (TRUE == enableDmtimer)
    {
        /* Start the timer */
        HW_WR_FIELD32((baseAddr + DMTIMER_TCLR),
            DMTIMER_TCLR_ST,
            DMTIMER_TCLR_ST_START);
    }
    else
    {
        /* Stop the timer */
        HW_WR_FIELD32((baseAddr + DMTIMER_TCLR),
            DMTIMER_TCLR_ST,
            DMTIMER_TCLR_ST_STOP); 
    }    
}

void DMTIMERSetMode(uint32_t baseAddr, dmtimerMode_t modeCfg)
{
    uint32_t regVal = 0;
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    /* Clear the AR and CE field of TCLR */
    regVal = HW_RD_REG32(baseAddr + DMTIMER_TCLR);
    /* to clear the auto reload field - set the one shot mode*/
    HW_SET_FIELD(regVal, DMTIMER_TCLR_AR, DMTIMER_TCLR_AR_ONESHOT);
    HW_SET_FIELD(regVal, DMTIMER_TCLR_CE, DMTIMER_TCLR_CE_DISABLE);
    HW_WR_REG32((baseAddr + DMTIMER_TCLR), regVal);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    /* Set the timer mode in TCLR register */
    regVal = HW_RD_REG32(baseAddr + DMTIMER_TCLR);
    /* Now check the mode that has been sent as  the param  */
    /* this section can be optimized - but for a start this would do */
    switch (modeCfg)
    {
        /* case 1 : one shot with compare enabled */
        case DMTIMER_MODE_CFG_ONESHOT_CMP_ENABLE:
             HW_SET_FIELD(regVal, DMTIMER_TCLR_AR, DMTIMER_TCLR_AR_ONESHOT);
             HW_SET_FIELD(regVal, DMTIMER_TCLR_CE, DMTIMER_TCLR_CE_ENABLE);
             break;
         /* case 2 : one shot with compare disabled */
        case DMTIMER_MODE_CFG_ONESHOT_CMP_DISABLE:
             HW_SET_FIELD(regVal, DMTIMER_TCLR_AR, DMTIMER_TCLR_AR_ONESHOT);
             HW_SET_FIELD(regVal, DMTIMER_TCLR_CE, DMTIMER_TCLR_CE_DISABLE);
             break;
        /* case 3 : auto reload with compare enabled */
        case DMTIMER_MODE_CFG_AUTORLD_CMP_ENABLE:
             HW_SET_FIELD(regVal, DMTIMER_TCLR_AR, DMTIMER_TCLR_AR_AUTO);
             HW_SET_FIELD(regVal, DMTIMER_TCLR_CE, DMTIMER_TCLR_CE_ENABLE);
             break;
        /* case 4 - default: auto reload with compare disabled */
        default:
             HW_SET_FIELD(regVal, DMTIMER_TCLR_AR, DMTIMER_TCLR_AR_AUTO);
             HW_SET_FIELD(regVal, DMTIMER_TCLR_CE, DMTIMER_TCLR_CE_DISABLE);
             break;
    }
    HW_WR_REG32((baseAddr + DMTIMER_TCLR), regVal);
}

void DMTIMERPrescalerClkEnable(uint32_t baseAddr, uint32_t dividerRatio)
{
    uint32_t regVal = 0;
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    /* Clear the dividerRatio field of TCLR */
    regVal = HW_RD_REG32(baseAddr + DMTIMER_TCLR);
    /* this is a 3 bit field having no field definitions */
    regVal &= ~DMTIMER_TCLR_PTV_MASK;
    HW_WR_REG32((baseAddr + DMTIMER_TCLR), regVal);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR );

    /* Set the dividerRatio field and enable the pre-scaler clock */
    regVal = HW_RD_REG32(baseAddr + DMTIMER_TCLR);
    /* Set the prescaler enable bit */
    HW_SET_FIELD(regVal, DMTIMER_TCLR_PRE, DMTIMER_TCLR_PRE_ENABLE);
    /* Move the prescaler clock divider ratio */
    regVal |= (dividerRatio << DMTIMER_TCLR_PTV_SHIFT);
    HW_WR_REG32((baseAddr + DMTIMER_TCLR), regVal);

}

void DMTIMERPrescalerClkDisable(uint32_t baseAddr)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR );

    /* Disable Pre-scaler clock */
    HW_WR_FIELD32((baseAddr + DMTIMER_TCLR),
        DMTIMER_TCLR_PRE,
        DMTIMER_TCLR_PRE_DISABLE);
}

void DMTIMERSetCounterVal(uint32_t baseAddr, uint32_t counter)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr,DMTIMER_POSTED_WRITE_STS_TCRR );

    /* Set the counter value */
    HW_WR_REG32((baseAddr + DMTIMER_TCRR), counter);
}


uint32_t DMTIMERGetCounterVal(uint32_t baseAddr)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCRR);

    /* Read the counter value from TCRR */
    return (HW_RD_REG32(baseAddr + DMTIMER_TCRR));
}


void DMTIMERLoadReloadCount(uint32_t baseAddr, uint32_t reload)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TLDR);

    /* Load the register with the re-load value */
    HW_WR_REG32((baseAddr + DMTIMER_TLDR), reload);
}


uint32_t DMTIMERGetReloadCount(uint32_t baseAddr)
{
    /* Return the contents of TLDR */
    return (HW_RD_REG32(baseAddr + DMTIMER_TLDR));
}

void DMTIMERGpoConfig(uint32_t baseAddr, uint32_t gpoCfg)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    /* Clear the GPO_CFG field of TCLR */
    /* if the GPO_CFG field is cleared - PORGPOCFG drives 0 */
    HW_WR_FIELD32((baseAddr + DMTIMER_TCLR),
        DMTIMER_TCLR_GPO_CFG,
        DMTIMER_TCLR_GPO_CFG_DRIVE0);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    /* Write to the gpoCfg field of TCLR */
    /* Set the GPO_CFG field to whats passed as param */
    HW_WR_FIELD32((baseAddr + DMTIMER_TCLR), DMTIMER_TCLR_GPO_CFG, gpoCfg);

}

void DMTIMERSetCompareVal(uint32_t baseAddr, uint32_t compareVal)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TMAR);

    /* Write the compare value to TMAR */
    HW_WR_REG32((baseAddr + DMTIMER_TMAR), compareVal);
}

uint32_t DMTIMERGetCompareVal(uint32_t baseAddr)
{
    /* Return the TMAR value */
    return (HW_RD_REG32(baseAddr + DMTIMER_TMAR));
}

void DMTIMERIntrTrigger(uint32_t baseAddr, uint32_t intrMask)
{
    /* Trigger the events in IRQSTATUS_RAW register */
    HW_WR_REG32((baseAddr + DMTIMER_IRQSTS_RAW),(intrMask &
                                           (DMTIMER_INTR_MASK_MAT |
                                            DMTIMER_INTR_MASK_OVF |
                                            DMTIMER_INTR_MASK_TCAR)
                                            ));
}

uint32_t DMTIMERIntrRawStatus(uint32_t baseAddr)
{
    /* Return the status of IRQSTATUS_RAW register */
    return (HW_RD_REG32(baseAddr + DMTIMER_IRQSTS_RAW));
}

uint32_t DMTIMERIntrStatus(uint32_t baseAddr)
{
    /* Return the status of IRQSTATUS register */
    return (HW_RD_REG32(baseAddr + DMTIMER_IRQSTS));
}

void DMTIMERIntrClear(uint32_t baseAddr, uint32_t intrMask)
{
    /* Clear the interrupt status from IRQSTATUS register */
    HW_WR_REG32((baseAddr + DMTIMER_IRQSTS),(intrMask &
                                         (DMTIMER_INTR_MASK_TCAR|
                                          DMTIMER_INTR_MASK_OVF |
                                          DMTIMER_INTR_MASK_MAT)));
}

void DMTIMERIntrEnable(uint32_t baseAddr, uint32_t intrMask)
{
    /* Enable the DMTimer interrupts represented by intrMask */
    HW_WR_REG32((baseAddr + DMTIMER_IRQEN_SET),(intrMask &
                                         (DMTIMER_INTR_MASK_TCAR |
                                          DMTIMER_INTR_MASK_OVF |
                                          DMTIMER_INTR_MASK_MAT)));
}

void DMTIMERIntrDisable(uint32_t baseAddr, uint32_t intrMask)
{
    /* Disable the DMTimer interrupts represented by intrMask */
    HW_WR_REG32((baseAddr + DMTIMER_IRQEN_CLR),(intrMask &
                                         (DMTIMER_INTR_MASK_TCAR|
                                          DMTIMER_INTR_MASK_OVF |
                                          DMTIMER_INTR_MASK_MAT)));
}

void DMTIMERTriggerTcrrWrite(uint32_t baseAddr)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TTGR);

    /* Write a value to the register */
    HW_WR_REG32((baseAddr + DMTIMER_TTGR), DMTIMER_TTGR_VALUE_MASK);
}

uint32_t DMTIMERGetIntrEnableStatus(uint32_t baseAddr)
{
    /* Return the status of register IRQENABLE_SET */
    return ( HW_RD_REG32(baseAddr + DMTIMER_IRQEN_SET));
}

void DMTIMERResetEnable(uint32_t baseAddr, uint32_t enableReset)
{
    /* Clear the SFT field of TSICR */
    HW_WR_FIELD32((baseAddr + DMTIMER_TSICR),
        DMTIMER_TSICR_SFT,
        DMTIMER_TSICR_SFT_RESETDISABLE);

    /* Write the option sent by user to SFT field of TSICR */
    HW_WR_FIELD32((baseAddr + DMTIMER_TSICR), DMTIMER_TSICR_SFT, enableReset);
}

void DMTIMERReset(uint32_t baseAddr)
{
    /* Reset the DMTimer module */
    HW_WR_FIELD32((baseAddr + DMTIMER_TIOCP_CFG),
        DMTIMER_TIOCP_CFG_SOFTRESET,
        DMTIMER_TIOCP_CFG_SOFTRESET_INITIATE);

    /* Wait for reset to complete*/
    while(DMTIMER_TIOCP_CFG_SOFTRESET_ONGOING ==
        ((HW_RD_REG32(baseAddr + DMTIMER_TIOCP_CFG) &
          DMTIMER_TIOCP_CFG_SOFTRESET_MASK) >>
         DMTIMER_TIOCP_CFG_SOFTRESET_SHIFT));
}

void DMTIMERContextSave(uint32_t baseAddr, dmtimerContext_t *pContextPtr)
{
    pContextPtr->tldr = HW_RD_REG32(baseAddr + DMTIMER_TLDR);
    pContextPtr->tmar = HW_RD_REG32(baseAddr + DMTIMER_TMAR) ;
    pContextPtr->irqenableset = HW_RD_REG32(baseAddr + DMTIMER_IRQEN_SET);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCRR);

    pContextPtr->tcrr = HW_RD_REG32(baseAddr + DMTIMER_TCRR);
    pContextPtr->tclr = HW_RD_REG32(baseAddr + DMTIMER_TCLR);
}

void DMTIMERContextRestore(uint32_t baseAddr,  dmtimerContext_t *pContextPtr)
{
    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TLDR);

    HW_WR_REG32((baseAddr + DMTIMER_TLDR), pContextPtr->tldr);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TMAR);

    HW_WR_REG32((baseAddr + DMTIMER_TMAR), pContextPtr->tmar);
    HW_WR_REG32((baseAddr + DMTIMER_IRQEN_SET), pContextPtr->irqenableset);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCRR);

    HW_WR_REG32((baseAddr + DMTIMER_TCRR), pContextPtr->tcrr);

    /* Wait for previous write to complete */
    DMTIMER_WAIT_FOR_WRITE(baseAddr, DMTIMER_POSTED_WRITE_STS_TCLR);

    HW_WR_REG32((baseAddr + DMTIMER_TCLR), pContextPtr->tclr);
}

void DMTIMERPostedModeEnable(uint32_t baseAddr, uint32_t enablePostedMode)
{
    /* Clear the POSTED field of TSICR */
    HW_WR_FIELD32((baseAddr + DMTIMER_TSICR),
        DMTIMER_TSICR_POSTED,
        DMTIMER_TSICR_POSTED_INACTIVE);

    if (TRUE == enablePostedMode)
    {    
        /* Set posted mode as active in TSICR */
        HW_WR_FIELD32((baseAddr + DMTIMER_TSICR), DMTIMER_TSICR_POSTED, 
        DMTIMER_TSICR_POSTED_ACTIVE);
    }
    else
    {
        /* Set posted mode as inactive in TSICR */
        HW_WR_FIELD32((baseAddr + DMTIMER_TSICR), DMTIMER_TSICR_POSTED, 
        DMTIMER_TSICR_POSTED_INACTIVE);       
    }        
}

uint32_t DMTIMERGetWritePostedStatus(uint32_t baseAddr)
{
    /* Return the status of TWPS register */
    return (HW_RD_REG32(baseAddr + DMTIMER_TWPS));
}

void DMTimerInit()
{
    uint32_t gBaseAddrTimer2 = SOC_DMTIMER2_REG;
    uint32_t gBaseAddrTimer3 = SOC_DMTIMER3_REG;
    uint32_t regVal;

    /* Clock source selection
    CLK_M_OSC: 0x1   - high frequency 25Mhz input clock
    CLK_32KHz: 0x2
    TCLKIN   : 0x0   - external clock pin - not used*/
    HW_WR_REG32(CM_DPLL_CLKSEL_TIMER2_CLK, 0x1);

    /* PRCM Module clock enable */
    HW_WR_REG32(CM_PER_TIMER2_CLKCTRL, 0x2);
    HW_WR_REG32(CM_PER_TIMER3_CLKCTRL, 0x2);

    /* Configure the timer counters and mode */
    DMTimerCounterSet(gBaseAddrTimer2, TIMER_INITIAL_COUNT1);
    DMTimerCounterSet(gBaseAddrTimer3, TIMER_INITIAL_COUNT);

    /* Load the load register with the reload count value */
    DMTimerReloadSet(gBaseAddrTimer2, TIMER_RLD_COUNT1);
    DMTimerReloadSet(gBaseAddrTimer3, TIMER_RLD_COUNT);

    /* Configure the DMTimer for Auto-reload mode */
    DMTimerModeConfigure(gBaseAddrTimer2, DMTIMER_MODE_CFG_AUTORLD_CMP_DISABLE);
    DMTimerModeConfigure(gBaseAddrTimer3, DMTIMER_MODE_CFG_AUTORLD_CMP_DISABLE);

    /* Disable pre-scalar */
    DMTimerPreScalerClkDisable(gBaseAddrTimer2);
    DMTimerPreScalerClkDisable(gBaseAddrTimer3);

    /* To enable prescaler, the values PRE and PTV of TCLR register need to be configured.
       Prescaler is enabled when bit 5 (PRE) of TCLR is set. Divider ratio is set in PTV (3 bits)
       field of TCLR. Check Section 19.1.3.6 of TRM for the relation between PTV and actual divisor
       values. */
    //DMTimerPreScalerClkEnable(gBaseAddrTimer2, DMTIMER_PRESCALER_CLK_DIV_RATIO_4);

    /* For timer cascading, the LS module must be set to generate only one pulse on the output (PT=0) on
	   overflow (TRG = 01). Check Section 19.1.3.12 of TRM */
    HW_WR_FIELD32((gBaseAddrTimer2 + DMTIMER_TCLR),
				  DMTIMER_TCLR_PT, DMTIMER_TCLR_PT_PULSE);
    HW_WR_FIELD32((gBaseAddrTimer2 + DMTIMER_TCLR),
				  DMTIMER_TCLR_TRG, DMTIMER_TCLR_TRG_OVERFLOW);

    /* Enable the cascade mode to pair DMTIMER2 and DMTIMER3 */
    regVal = HW_RD_REG32(CTRL_TIMER_CASCADE);
    regVal = (regVal | 0x00000001U);
    HW_WR_REG32(CTRL_TIMER_CASCADE, regVal);

    /* Start the DMTimer */
    DMTIMEREnable(gBaseAddrTimer2, TRUE);
    DMTIMEREnable(gBaseAddrTimer3, TRUE);
}

Could you please check the configuration in the above function? It's not clear to me that why the DMTIMER3 does not increment for the first 4 overflows of DMTIMER2.

Any support in this regard will be much appreciated.

Thank you in advance!