From 8b83409b23c8e7a1e43c1c986003042a23dd5977 Mon Sep 17 00:00:00 2001
From: Dongkangjia <dongkangjia@ti.com>
Date: Tue, 14 Mar 2023 10:49:27 +0800
Subject: [PATCH] add j784s4 m2m support

---
 .../packages/ti/drv/dss/dss.h                 |    6 +-
 .../packages/ti/drv/dss/dss_component.mk      |    5 +-
 .../dss/examples/dss_m2m_test/dss_m2m_test.c  |  684 +++++++
 .../examples/dss_m2m_test/dss_m2m_test_cfg.h  |  230 +++
 .../drv/dss/examples/dss_m2m_test/main_rtos.c |  189 ++
 .../ti/drv/dss/examples/dss_m2m_test/makefile |   12 +
 .../drv/dss/examples/dss_m2m_test/makefile.mk |   52 +
 .../packages/ti/drv/dss/include/dss_m2m.h     |  403 ++++
 .../ti/drv/dss/src/drv/common/dss_init.c      |    6 +-
 .../ti/drv/dss/src/drv/m2m/dss_m2mApi.c       | 1753 +++++++++++++++++
 .../ti/drv/dss/src/drv/m2m/dss_m2mDctrl.c     |  379 ++++
 .../ti/drv/dss/src/drv/m2m/dss_m2mDisp.c      |  575 ++++++
 .../ti/drv/dss/src/drv/m2m/dss_m2mDrv.h       |  138 ++
 .../ti/drv/dss/src/drv/m2m/dss_m2mPriv.h      |  416 ++++
 .../ti/drv/dss/src/drv/m2m/src_files_m2m.mk   |    1 +
 .../ti/drv/dss/src/drv/src_files_drv.mk       |    2 +-
 tiovx/build_flags.mak                         |    2 +-
 tiovx/kernels_j7/hwa/display_m2m/concerto.mak |    2 +-
 .../platform/j784s4/rtos/common/app_init.c    |    5 +-
 .../platform/j784s4/rtos/concerto_r5f_inc.mak |    1 +
 20 files changed, 4848 insertions(+), 13 deletions(-)
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test.c
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test_cfg.h
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/main_rtos.c
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile.mk
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/include/dss_m2m.h
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mApi.c
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDctrl.c
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDisp.c
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDrv.h
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mPriv.h
 create mode 100755 pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/src_files_m2m.mk

diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss.h b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss.h
index 07ae2e98..a7ded995 100755
--- a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss.h
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss.h
@@ -70,7 +70,7 @@
 #include <ti/drv/dss/soc/dss_soc.h>
 #include <ti/drv/dss/include/dss_disp.h>
 #include <ti/drv/dss/include/dss_dctrl.h>
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined(SOC_J784S4)
 #include <ti/drv/dss/include/dss_m2m.h>
 #endif
 
@@ -89,7 +89,7 @@ extern "C" {
 /** \brief Display controller driver ID used at the time of FVID2 create. */
 #define DSS_DCTRL_DRV_ID                    (FVID2_DSS_DRV_BASE + 0x01U)
 
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined(SOC_J784S4)
 /** \brief Display M2M driver ID used at the time of FVID2 create. */
 #define DSS_M2M_DRV_ID                      (FVID2_DSS_DRV_BASE + 0x02U)
 #endif
@@ -106,7 +106,7 @@ extern "C" {
 /** \brief IOCTL base address for the SOC specific display controller driver
  *   IOCTLs. */
 #define DSS_DCTRL_SOC_IOCTL_BASE            (DSS_DCTRL_IOCTL_BASE + 0x40U)
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined (SOC_J784S4)
 /** \brief IOCTL base address for the Display M2M Driver IOCTLs. */
 #define DSS_M2M_IOCTL_BASE                  (FVID2_DSS_DRV_IOCTL_BASE + 0x200U)
 #endif
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss_component.mk b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss_component.mk
index fcc7bda7..8f299c3e 100755
--- a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss_component.mk
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/dss_component.mk
@@ -40,10 +40,11 @@ drvdss_am65xx_CORELIST = mpu1_0
 drvdss_j721e_CORELIST  = mcu2_0
 drvdss_j721s2_CORELIST  = mcu2_0
 drvdss_j784s4_CORELIST  = mcu2_0
-drvdssm2m_SOCLIST         = j721e j721s2
-drvdssm2m_BOARDLIST       = j721e_evm j721s2_evm
+drvdssm2m_SOCLIST         = j721e j721s2 j784s4
+drvdssm2m_BOARDLIST       = j721e_evm j721s2_evm j784s4_evm
 drvdssm2m_j721e_CORELIST  = mcu2_0
 drvdssm2m_j721s2_CORELIST = mcu2_0
+drvdssm2m_j784s4_CORELIST = mcu2_0
 drvdss_RTOS_LIST       = $(DEFAULT_RTOS_LIST)
 
 define DRV_DSS_RTOS_BOARDLIST_RULE
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test.c
new file mode 100755
index 00000000..4e899ae0
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test.c
@@ -0,0 +1,684 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021 - 2022
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2m_test.c
+ *
+ *  \brief DSS sample application that does conversion frames for two instances
+ *         of M2M Driver.
+ *         This sample application demonstrates following:
+ *              - YUV422 -> YUV420 conversion
+ *              - Single channel conversion (through single M2M DRV instance)
+ *                  - controlled through 'APP_DSS_M2M_CH_NUM'
+ *              - Runtime loading of buffers (in this case YUV422)
+ *          Refer to 'dss_m2m_test_cfg' file for more details about
+ *          reconfigurability of this application.
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+
+#include <stdio.h>
+#include <string.h>
+#include <dss_m2m_test_cfg.h>
+
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+int32_t Dss_displayM2MTest(void);
+static int32_t App_init(M2MApp_AppObj *appObj);
+static int32_t App_deInit(M2MApp_AppObj *appObj);
+static int32_t App_create(M2MApp_AppObj *appObj);
+static int32_t App_delete(M2MApp_AppObj *appObj);
+static int32_t App_runTest(M2MApp_AppObj *appObj);
+static int32_t App_initParams(M2MApp_AppObj *appObj);
+static int32_t App_allocAndQueueFrames(M2MApp_InstParams *appObj);
+static int32_t App_pipeCbFxn(Fvid2_Handle handle, void *appData);
+extern void App_wait(uint32_t wait_in_ms);
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+
+M2MApp_AppObj gM2MAppObj;
+uint32_t gTestStopTime, gTestStartTime;
+
+/* This buffer will be used to store RGB or Y */
+static uint8_t gOutFrms[(APP_DSS_M2M_CH_NUM * APP_DSS_M2M_DSS_PIPE_NUM)][(APP_DSS_M2M_OUT_FRAME_PITCH * APP_DSS_M2M_OUT_FRAME_HEIGHT)] __attribute__(( aligned(128), section(".data_buffer")));
+/* This buffer will be used to store UV */
+static uint8_t gOutUVComp[(APP_DSS_M2M_CH_NUM * APP_DSS_M2M_DSS_PIPE_NUM)][(APP_DSS_M2M_OUT_FRAME_PITCH * APP_DSS_M2M_OUT_FRAME_HEIGHT)] __attribute__(( aligned(128), section(".data_buffer")));
+/* ========================================================================== */
+/*                          Function Definitions                              */
+/* ========================================================================== */
+int32_t Dss_displayM2MTest(void)
+{
+    int32_t retVal = FVID2_SOK;
+    M2MApp_AppObj *appObj;
+
+    appObj = &gM2MAppObj;
+    /* Initialize application object to '0' and the set only required parameters */
+    Fvid2Utils_memset(appObj, 0U, sizeof(M2MApp_AppObj));
+
+    retVal = App_initParams(appObj);
+    if (FVID2_SOK != retVal)
+    {
+        App_consolePrintf("\nERROR: App_initParams() Failed!!!\n");
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        retVal += App_init(appObj);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: App_init() Failed!!!\n");
+        }
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        retVal += App_create(appObj);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: App_create() Failed!!!\n");
+        }
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        retVal += App_runTest(appObj);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: App_runTest() Failed!!!\n");
+        }
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        retVal += App_delete(appObj);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: App_delete() Failed!!!\n");
+        }
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        retVal += App_deInit(appObj);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: App_deInit() Failed!!!\n");
+        }
+    }
+
+
+    return retVal;
+}
+static int32_t App_initParams(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t loopCnt, pipeIdx, planeIdx, layerIdx;
+    M2MApp_InstParams *instObj;
+    SemaphoreP_Params semParams;
+    Dss_DispParams *dispParams;
+    CSL_DssWbPipeCfg *wbPipeCfg;
+    Dss_DctrlOverlayParams *ovrParams;
+    Dss_DctrlOverlayLayerParams *layerParams;
+
+    appObj->numInst            = APP_DSS_M2M_CH_NUM;
+    appObj->numFramesToConvert = APP_DSS_M2M_FRAMES_WB;
+    appObj->numFramesWb        = 0U;
+    for (loopCnt = 0U ; loopCnt < appObj->numInst ; loopCnt++)
+    {
+        instObj                     = &appObj->instParams[loopCnt];
+        instObj->instIdx            = loopCnt;
+        instObj->appObj             = appObj;
+        Dss_m2mCreateParamsInit(&instObj->createParams);
+        Fvid2CbParams_init(&instObj->cbParams);
+        instObj->cbParams.cbFxn         = &App_pipeCbFxn;
+        instObj->cbParams.appData       = instObj;
+        instObj->numPipe                = APP_DSS_M2M_DSS_PIPE_NUM;
+        instObj->createParams.numPipe   = APP_DSS_M2M_DSS_PIPE_NUM;
+        instObj->createParams.overlayId = APP_DSS_M2M_DSS_OVERLAY_ID;
+        /* Initialize Display pipeline parameters */
+        for (pipeIdx = 0U ; pipeIdx < APP_DSS_M2M_DSS_PIPE_NUM ; pipeIdx++)
+        {
+            instObj->createParams.pipeId[pipeIdx] = APP_DSS_M2M_DSS_PIPE_ID;
+            instObj->pipeCfg[pipeIdx].pipeId      = APP_DSS_M2M_DSS_PIPE_ID;
+            instObj->mFlagCfg[pipeIdx].pipeId     = APP_DSS_M2M_DSS_PIPE_ID;
+            instObj->cscCfg[pipeIdx].pipeId       = APP_DSS_M2M_DSS_PIPE_ID;
+            dispParams = &instObj->pipeCfg[pipeIdx].cfgParams;
+            Dss_dispParamsInit(dispParams);
+            dispParams->pipeCfg.pipeType = CSL_DSS_VID_PIPE_TYPE_VID;
+            dispParams->pipeCfg.inFmt.width = APP_DSS_M2M_IN_FRAME_WIDTH;
+            dispParams->pipeCfg.inFmt.height = APP_DSS_M2M_IN_FRAME_HEIGHT;
+            for(planeIdx = 0U ; planeIdx < FVID2_MAX_PLANES; planeIdx++)
+            {
+                dispParams->pipeCfg.inFmt.pitch[planeIdx] = APP_DSS_M2M_IN_FRAME_PITCH;
+            }
+            dispParams->pipeCfg.inFmt.dataFormat  = APP_DSS_M2M_IN_FRAME_FORMAT;
+            dispParams->pipeCfg.outWidth          = APP_DSS_M2M_IN_FRAME_WIDTH;
+            dispParams->pipeCfg.outHeight         = APP_DSS_M2M_IN_FRAME_HEIGHT;
+            dispParams->pipeCfg.scEnable          = FALSE;
+            dispParams->alphaCfg.globalAlpha      = 0xFFU;
+            dispParams->alphaCfg.preMultiplyAlpha = FALSE;
+            dispParams->layerPos.startX           = 0U;
+            dispParams->layerPos.startY           = 0U;
+
+            Dss_dispPipeMflagParamsInit(&instObj->mFlagCfg[pipeIdx].mFlagCfg);
+
+            CSL_dssCscCoeffInit(&instObj->cscCfg[pipeIdx].csc);
+        }
+        /* Initialize WB pipeline parameters */
+        Dss_m2mPipeCfgParamsInit(&instObj->wbCfg);
+        wbPipeCfg = &instObj->wbCfg.pipeCfg;
+        /* Dont' need to set dataFormat as this is fixed to 'FVID2_DF_ARGB48_12121212'
+           and is set in 'Dss_m2mPipeCfgParamsInit()' */
+        wbPipeCfg->inFmt.width       = APP_DSS_M2M_IN_FRAME_WIDTH;
+        wbPipeCfg->inFmt.height      = APP_DSS_M2M_IN_FRAME_HEIGHT;
+        wbPipeCfg->outFmt.width      = APP_DSS_M2M_OUT_FRAME_WIDTH;
+        wbPipeCfg->outFmt.height     = APP_DSS_M2M_OUT_FRAME_HEIGHT;
+        wbPipeCfg->outFmt.dataFormat = APP_DSS_M2M_OUT_FRAME_FORMAT;
+        if ( (wbPipeCfg->inFmt.width != wbPipeCfg->outFmt.width) || (wbPipeCfg->inFmt.height != wbPipeCfg->outFmt.height))
+        {
+            wbPipeCfg->scEnable = TRUE;
+        }
+        else
+        {
+            wbPipeCfg->scEnable = FALSE;
+        }
+        wbPipeCfg->outFmt.ccsFormat  = FVID2_CCSF_BITS8_PACKED;
+        wbPipeCfg->inPos.startX      = 0U;
+        wbPipeCfg->inPos.startY      = 0U;
+        for(planeIdx = 0U ; planeIdx < FVID2_MAX_PLANES; planeIdx++)
+        {
+            wbPipeCfg->outFmt.pitch[planeIdx] = APP_DSS_M2M_OUT_FRAME_PITCH;
+        }
+        CSL_dssWbPipeDmaCfgInit(&instObj->wbDmaCfg);
+        Dss_m2mMFlagParamsInit(&instObj->wbMflagCfg);
+        CSL_dssCscCoeffInit(&instObj->wbCscCfg);
+        Dss_m2mStatusInit(&instObj->wbStatus);
+
+        /* Initialize Display overlay parameters */
+        ovrParams = &instObj->ovrCfg;
+        Dss_dctrlOverlayParamsInit(ovrParams);
+        ovrParams->overlayId = APP_DSS_M2M_DSS_OVERLAY_ID;
+        ovrParams->colorbarEnable = FALSE;
+        ovrParams->overlayCfg.colorKeyEnable = FALSE;
+        ovrParams->overlayCfg.colorKeySel = CSL_DSS_OVERLAY_TRANS_COLOR_DEST;
+        ovrParams->overlayCfg.backGroundColor = 0xc8c800U;
+
+        layerParams = &instObj->layerCfg;
+        Dss_dctrlOverlayLayerParamsInit(layerParams);
+        layerParams->overlayId = APP_DSS_M2M_DSS_OVERLAY_ID;
+        /* Set all layer to invalid first and then update only used ones */
+        for(layerIdx = 0U ; layerIdx < CSL_DSS_VID_PIPE_ID_MAX ; layerIdx++)
+        {
+            layerParams->pipeLayerNum[layerIdx] = CSL_DSS_OVERLAY_LAYER_INVALID;
+        }
+        layerParams->pipeLayerNum[instObj->createParams.pipeId[0U]] =
+                                                    CSL_DSS_OVERLAY_LAYER_NUM_0;
+        if(APP_DSS_M2M_DSS_PIPE_NUM > 1U)
+        {
+            for(layerIdx = 1U ; layerIdx < APP_DSS_M2M_DSS_PIPE_NUM ; layerIdx++)
+            {
+                layerParams->pipeLayerNum[instObj->createParams.pipeId[0U]] = layerIdx;
+            }
+        }
+
+        Dss_dctrlGlobalDssParamsInit(&instObj->globalParams);
+
+        /* Create sync semaphore */
+        /* Allocate instance semaphore */
+        SemaphoreP_Params_init(&semParams);
+        semParams.mode   = SemaphoreP_Mode_BINARY;
+        instObj->syncSem = SemaphoreP_create(0U, &semParams);
+        if (instObj->syncSem == NULL)
+        {
+            retVal = FVID2_EFAIL;
+            App_consolePrintf("\nERROR: Semaphore create failed!!!\n");
+        }
+    }
+
+    return retVal;
+}
+
+void App_consolePrintf(const char *pcString, ...)
+{
+    char printBuffer[APP_PRINT_BUFFER_SIZE];
+    va_list arguments;
+
+    /* Start the var args processing. */
+    va_start(arguments, pcString);
+    vsnprintf (printBuffer, sizeof(printBuffer), pcString, arguments);
+#if !defined (QT_BUILD)
+    UART_printf(printBuffer);
+#else
+    printf(printBuffer);
+#endif
+    /* End the var args processing. */
+    va_end(arguments);
+}
+
+static int32_t App_init(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+    Fvid2_InitPrms  initPrms;
+
+    Fvid2InitPrms_init(&initPrms);
+    initPrms.printFxn = &App_consolePrintf;
+    retVal = Fvid2_init(&initPrms);
+    if(retVal != FVID2_SOK)
+    {
+        App_consolePrintf("\nERROR: FVID2 Init Failed!!!\r\n");
+    }
+
+    Dss_initParamsInit(&appObj->initParams);
+    appObj->initParams.socParams.irqParams.dssCommonRegionId                    = CSL_DSS_COMM_REG_ID_1;
+    appObj->initParams.socParams.irqParams.numValidIrq                          = DSS_EVT_MGR_INST_ID_MAX;
+    appObj->initParams.socParams.irqParams.irqNum[DSS_EVT_MGR_INST_ID_FUNC]     = 53U;
+    appObj->initParams.socParams.irqParams.irqNum[DSS_EVT_MGR_INST_ID_SAFETY]   = 55U;
+    appObj->initParams.socParams.irqParams.irqNum[DSS_EVT_MGR_INST_ID_SECURITY] = 57U;
+    appObj->initParams.socParams.dpInitParams.isHpdSupported                    = FALSE;
+    Dss_init(&appObj->initParams);
+
+    if (FVID2_SOK == retVal)
+    {
+        App_consolePrintf("App_init() - DONE !!!\r\n");
+    }
+
+    return retVal;
+}
+
+static int32_t App_deInit(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+
+    retVal += Dss_deInit();
+    retVal += Fvid2_deInit(NULL);
+    if(retVal != FVID2_SOK)
+    {
+         App_consolePrintf("\nERROR: App_deInit failed!!!\r\n");
+    }
+    else
+    {
+         App_consolePrintf("App_deInit() - DONE !!!\r\n");
+    }
+
+    return retVal;
+}
+
+static int32_t App_create(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t instIdx, pipeIdx;
+    M2MApp_InstParams *instObj;
+
+    /* Create DSS M2M Driver instance */
+    for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+    {
+        instObj = &appObj->instParams[instIdx];
+        instObj->drvHandle = Fvid2_create(DSS_M2M_DRV_ID,
+                                             APP_DSS_M2M_INST,
+                                             &instObj->createParams,
+                                             &instObj->createStatus,
+                                             &instObj->cbParams);
+        if((NULL == instObj->drvHandle) ||
+           (instObj->createStatus.retVal != FVID2_SOK))
+        {
+            retVal = instObj->createStatus.retVal;
+            App_consolePrintf("\nERROR: Display M2M DRV Create Failed!!!\r\n");
+        }
+        /* Call Driver IOCTLs */
+        if (FVID2_SOK == retVal)
+        {
+            for (pipeIdx = 0U ;
+                 pipeIdx < instObj->createParams.numPipe ;
+                 pipeIdx++)
+            {
+                retVal += Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_M2M_SET_PIPE_PARAMS,
+                            &instObj->pipeCfg[pipeIdx],
+                            NULL);
+                retVal += Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_M2M_SET_PIPE_MFLAG_PARAMS,
+                            &instObj->mFlagCfg[pipeIdx],
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: Display Pipe IOCTL Failed!!!\r\n");
+                    break;
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_DCTRL_SET_OVERLAY_PARAMS,
+                            &instObj->ovrCfg,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_DCTRL_SET_OVERLAY_PARAMS Failed!!!\r\n");
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_DCTRL_SET_LAYER_PARAMS,
+                            &instObj->layerCfg,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_DCTRL_SET_LAYER_PARAMS Failed!!!\r\n");
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_DCTRL_SET_GLOBAL_DSS_PARAMS,
+                            &instObj->globalParams,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_DCTRL_SET_GLOBAL_DSS_PARAMS Failed!!!\r\n");
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_M2M_SET_WB_PIPE_PARAMS,
+                            &instObj->wbCfg,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_M2M_SET_WB_PIPE_PARAMS Failed!!!\r\n");
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_M2M_SET_WB_PIPE_MFLAG_PARAMS,
+                            &instObj->wbMflagCfg,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_M2M_SET_WB_PIPE_MFLAG_PARAMS Failed!!!\r\n");
+                }
+            }
+            if (FVID2_SOK == retVal)
+            {
+                retVal = Fvid2_control(
+                            instObj->drvHandle,
+                            IOCTL_DSS_M2M_SET_WB_PIPE_DMA_CFG,
+                            &instObj->wbDmaCfg,
+                            NULL);
+                if (FVID2_SOK != retVal)
+                {
+                    App_consolePrintf("\nERROR: IOCTL_DSS_M2M_SET_WB_PIPE_DMA_CFG Failed!!!\r\n");
+                }
+            }
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t App_delete(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t instIdx;
+    Fvid2_FrameList inFrmList, outFrmList;
+    M2MApp_InstParams *instObj;
+
+    for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+    {
+        instObj = &appObj->instParams[instIdx];
+        /* Dequeue all the request from the driver */
+        while (1U)
+        {
+            retVal = Fvid2_getProcessedRequest(instObj->drvHandle,
+                                               &inFrmList,
+                                               &outFrmList,
+                                               FVID2_TIMEOUT_NONE);
+            if (retVal == FVID2_ENO_MORE_BUFFERS)
+            {
+                retVal = FVID2_SOK;
+                break;
+            }
+            else if (FVID2_SOK != retVal)
+            {
+                App_consolePrintf("\nERROR: Fvid2_getProcessedRequest Failed!!!\r\n");
+                break;
+            }
+            else
+            {
+                /* Do nothing here */
+            }
+        }
+
+        retVal = FVID2_SOK;
+
+        retVal = Fvid2_delete(instObj->drvHandle, NULL);
+        if(FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: M2M Driver Delete Failed!!!\r\n");
+            break;
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t App_runTest(M2MApp_AppObj *appObj)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t instIdx;
+    M2MApp_InstParams *instObj;
+    Fvid2_FrameList inFrmList, outFrmList;
+
+    for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+    {
+        instObj = &appObj->instParams[instIdx];
+        /* Start the driver before queuing */
+        retVal = Fvid2_start(instObj->drvHandle, NULL);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: Fvid2_start Failed!!!\r\n");
+            break;
+        }
+
+        /* Allocate and submit frames for processing */
+        App_allocAndQueueFrames(instObj);
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        while (appObj->numFramesWb < appObj->numFramesToConvert)
+        {
+            if (FVID2_SOK == retVal)
+            {
+                for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+                {
+                    instObj = &appObj->instParams[instIdx];
+                    /* Wait for Semaphore */
+                    (void) SemaphoreP_pend(instObj->syncSem, SemaphoreP_WAIT_FOREVER);
+                    /* Get processed frames */
+                    retVal = Fvid2_getProcessedRequest(instObj->drvHandle,
+                                                       &inFrmList,
+                                                       &outFrmList,
+                                                       FVID2_TIMEOUT_NONE);
+                    if(FVID2_SOK != retVal)
+                    {
+                        App_consolePrintf("\nERROR: Fvid2_processRequest Failed!!!\r\n");
+                        break;
+                    }
+                    /* Submit back frames for processing */
+                    retVal = Fvid2_processRequest(instObj->drvHandle,
+                                                  &inFrmList,
+                                                  &outFrmList,
+                                                  FVID2_TIMEOUT_NONE);
+                    if(FVID2_SOK != retVal)
+                    {
+                        App_consolePrintf("\nERROR: Fvid2_processRequest Failed!!!\r\n");
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+    {
+        instObj = &appObj->instParams[instIdx];
+        /* Stop the driver before queuing */
+        retVal = Fvid2_stop(instObj->drvHandle, NULL);
+        if (FVID2_SOK != retVal)
+        {
+            App_consolePrintf("\nERROR: Fvid2_stop Failed!!!\r\n");
+            break;
+        }
+    }
+
+    for (instIdx = 0U ; instIdx < appObj->numInst ; instIdx++)
+    {
+        /* Get status */
+        retVal += Fvid2_control(instObj->drvHandle,
+                                IOCTL_DSS_M2M_GET_CURRENT_STATUS,
+                                &instObj->wbStatus,
+                                NULL);
+        if (FVID2_SOK == retVal)
+        {
+            App_consolePrintf(
+                "\n\r==========================================================\r\n");
+            App_consolePrintf("Display M2M Status: %d\r\n", instIdx);
+            App_consolePrintf(
+                "==========================================================\r\n");
+            App_consolePrintf("Input Format: 0x%x\r\n", APP_DSS_M2M_IN_FRAME_FORMAT);
+            App_consolePrintf("Output Format: 0x%x\r\n", APP_DSS_M2M_OUT_FRAME_FORMAT);
+            App_consolePrintf("Frames Submitted: %d\r\n", instObj->wbStatus.queueCount);
+            App_consolePrintf("Frames Got Back After Processing: %d\r\n", instObj->wbStatus.dequeueCount);
+            App_consolePrintf("Frames Processed: %d\r\n", instObj->wbStatus.wbFrmCount);
+            App_consolePrintf("Frames Underflow Count: %d\r\n", instObj->wbStatus.underflowCount);
+            App_consolePrintf(
+                "==========================================================\r\n");
+        }
+        else
+        {
+            App_consolePrintf("\nERROR: Fvid2_control(IOCTL_DSS_M2M_GET_CURRENT_STATUS) Failed!!!\r\n");
+            break;
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t App_allocAndQueueFrames(M2MApp_InstParams *instObj)
+{
+    int32_t  retVal = FVID2_SOK;
+    uint32_t pipeIdx;
+    Fvid2_Frame *frm;
+    Fvid2_FrameList inFrmList, outFrmList;
+    char uartInput = '0';
+
+    App_consolePrintf("Load Image using loadRaw command and then press '1'\n");
+    App_consolePrintf("Command is:\n");
+    App_consolePrintf("loadRaw(0x%x, 0, \"C:\\\\display_yuyv422_prog_packed_1920_1080.tigf\", 32, false);\n",
+              APP_DSS_M2M_DDR_LOAD_ADDRESS);
+    do
+    {
+        scanf("%c", &uartInput);
+    } while ('1' != uartInput);
+
+    Fvid2FrameList_init(&inFrmList);
+    for (pipeIdx = 0U ; pipeIdx < instObj->numPipe ; pipeIdx++)
+    {
+        frm = inFrmList.frames[pipeIdx];
+        /* init Fvid2_Frame to 0's  */
+        frm = (Fvid2_Frame *) &instObj->inFrames[pipeIdx];
+        frm->chNum = instObj->createParams.pipeId[pipeIdx];
+        frm->addr[0U] = (uint64_t)(APP_DSS_M2M_DDR_LOAD_ADDRESS +
+               (pipeIdx * APP_DSS_M2M_IN_FRAME_PITCH * APP_DSS_M2M_IN_FRAME_HEIGHT));
+        inFrmList.frames[pipeIdx] = frm;
+    }
+    inFrmList.numFrames = instObj->numPipe;
+    frm = (Fvid2_Frame *) &instObj->outFrames[0U];
+    /* init Fvid2_Frame to 0's  */
+    frm->addr[0U] = (uint64_t)&(gOutFrms[(instObj->instIdx * APP_DSS_M2M_CH_NUM)][0U]);
+    frm->addr[1U] = (uint64_t)&(gOutUVComp[(instObj->instIdx * APP_DSS_M2M_CH_NUM)][0U]);
+    outFrmList.frames[0U] = frm;
+    outFrmList.numFrames = 1U;
+    retVal = Fvid2_processRequest(instObj->drvHandle,
+                                  &inFrmList,
+                                  &outFrmList,
+                                  FVID2_TIMEOUT_NONE);
+    if(FVID2_SOK != retVal)
+    {
+        App_consolePrintf("\nERROR: Fvid2_processRequest Failed!!!\r\n");
+    }
+
+    return retVal;
+}
+
+static int32_t App_pipeCbFxn(Fvid2_Handle handle, void *appData)
+{
+    int32_t retVal = FVID2_SOK;
+    M2MApp_InstParams *instObj;
+
+    GT_assert(DssTrace, (appData != NULL));
+
+    instObj = (M2MApp_InstParams *)appData;
+    instObj->appObj->numFramesWb++;
+    /* Post semaphore */
+    (void) SemaphoreP_post(instObj->syncSem);
+
+    return retVal;
+}
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test_cfg.h b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test_cfg.h
new file mode 100755
index 00000000..048f3377
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/dss_m2m_test_cfg.h
@@ -0,0 +1,230 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2m_test_cfg.h
+ *
+ *  \brief DSS Display M2M Test Configuration Header file.
+ */
+
+#ifndef DSS_DISPLAY_TEST_CFG_H_
+#define DSS_DISPLAY_TEST_CFG_H_
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <stdint.h>
+#include <stdio.h>
+#include "ti/osal/osal.h"
+#include "ti/osal/TaskP.h"
+
+#include <ti/board/board.h>
+#include <ti/drv/dss/examples/utils/app_utils.h>
+#include <ti/drv/sciclient/sciclient.h>
+#include <ti/csl/soc.h>
+#include <ti/drv/pm/pmlib.h>
+#include <ti/drv/uart/UART.h>
+#include <ti/drv/uart/UART_stdio.h>
+#include <ti/drv/dss/examples/utils/app_utils_prf.h>
+
+#include <ti/drv/dss/dss.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+/**< Application name */
+#define APP_NAME                        "DSS_M2M_APP"
+
+/**< Driver instance to use */
+#define APP_DSS_M2M_INST                ((uint32_t)DSS_M2M_WB_PIPELINE_ID_0)
+
+/**< Number of channels i.e number of driver instances to be opened */
+#define APP_DSS_M2M_CH_NUM                           ((uint32_t)1U)
+
+/**< Number of display pipelines to use */
+#define APP_DSS_M2M_DSS_PIPE_NUM                     ((uint32_t)1U)
+
+/**< ID of display pipeline to use */
+#define APP_DSS_M2M_DSS_PIPE_ID                      (CSL_DSS_VID_PIPE_ID_VID1)
+
+/**< ID of display overlay to use */
+#define APP_DSS_M2M_DSS_OVERLAY_ID                   (CSL_DSS_OVERLAY_ID_1)
+
+/**< Number of frames to convert */
+#define APP_DSS_M2M_FRAMES_WB                      ((uint32_t)1000U)
+
+/**< Buffer load address for runtime loading buffers */
+#define APP_DSS_M2M_DDR_LOAD_ADDRESS               (0x82000000U)
+
+/**< Input Frame Attribute: Format */
+#define APP_DSS_M2M_IN_FRAME_FORMAT                     (FVID2_DF_YUV422I_YUYV)
+/**< Input Frame Attribute: Width in pixels */
+#define APP_DSS_M2M_IN_FRAME_WIDTH                      ((uint32_t)1920U)
+/**< Input Frame Attribute: Height in pixels */
+#define APP_DSS_M2M_IN_FRAME_HEIGHT                     ((uint32_t)1080U)
+/**< Input Frame Attribute: Bytes per pixel */
+#define APP_DSS_M2M_IN_FRAME_BPP                        ((uint32_t)2U)
+/**< Input Frame Attribute: Pitch in bytes */
+#define APP_DSS_M2M_IN_FRAME_PITCH                      ((uint32_t)\
+                            (APP_DSS_M2M_IN_FRAME_WIDTH * APP_DSS_M2M_IN_FRAME_BPP))
+
+/**< Output Frame Attribute: Format */
+#define APP_DSS_M2M_OUT_FRAME_FORMAT                     (FVID2_DF_YUV420SP_UV)
+/**< Output Frame Attribute: Width in pixels */
+#define APP_DSS_M2M_OUT_FRAME_WIDTH                      ((uint32_t)1920U)
+/**< Output Frame Attribute: Height in pixels */
+#define APP_DSS_M2M_OUT_FRAME_HEIGHT                     ((uint32_t)1080U)
+/**< Output Frame Attribute: Bytes per pixel */
+#define APP_DSS_M2M_OUT_FRAME_BPP                        (1U)
+/**< Output Frame Attribute: Pitch in bytes */
+#define APP_DSS_M2M_OUT_FRAME_PITCH                      ((uint32_t)\
+                            (APP_DSS_M2M_OUT_FRAME_WIDTH * APP_DSS_M2M_OUT_FRAME_BPP))
+
+/* Print buffer character limit for prints- UART or CCS Console */
+#define APP_PRINT_BUFFER_SIZE                   ((uint32_t)4000)
+
+/** \brief Log enable for DSS M2M Sample application */
+#define DssM2MAppTrace                       ((uint32_t) GT_INFO   |\
+                                              (uint32_t) GT_TraceState_Enable)
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+typedef struct M2MApp_AppObj_t M2MApp_AppObj;
+
+/**
+ *  \brief Display application test parameters.
+ *  The test case execution happens based on values of this structure
+ */
+typedef struct
+{
+    uint32_t instIdx;
+    /**< Instance index in application object */
+    Fvid2_Handle drvHandle;
+    /**< FVID2 display driver handle */
+    uint32_t numPipe;
+    /**< Number of Display pipe used */
+    Dss_WbCreateParams createParams;
+    /**< WB pipe create parameters */
+    Dss_WbCreateStatus createStatus;
+    /**< WB pipe create status */
+    Fvid2_CbParams cbParams;
+    /**< Callback parameters */
+    Dss_WbStatus wbStatus;
+    /**< WB pipe status */
+    SemaphoreP_Handle syncSem;
+    /**< Semaphore for ISR */
+    Dss_WbPipeCfgParams wbCfg;
+    /**< WB pipe configuration */
+    CSL_DssWbPipeDmaCfg wbDmaCfg;
+    /**< WB pipe DMA configuration */
+    Dss_WbPipeMflagParams wbMflagCfg;
+    /**< WB pipe MFlag configuration */
+    CSL_DssCscCoeff wbCscCfg;
+    /**< WB pipe CSC configuration */
+    Dss_PipeCfgParams pipeCfg[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< Display pipe configuration */
+    Dss_PipeMflagParams mFlagCfg[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< Display pipe MFlag configuration */
+    Dss_PipeCscParams cscCfg[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< Display pipe CSC configuration */
+    Dss_DctrlOverlayParams ovrCfg;
+    /**< Display Overlay configuration */
+    Dss_DctrlOverlayLayerParams layerCfg;
+    /**< Display Layer configuration */
+    Dss_DctrlGlobalDssParams globalParams;
+    /**< Display Global configuration */
+   M2MApp_AppObj *appObj;
+   /**< Reference to Application Object  */
+   Fvid2_Frame inFrames[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+   /**< FVID2 Frames that will be used for capture. */
+   Fvid2_Frame outFrames[1U];
+   /**< FVID2 Frames that will be used for capture. */
+} M2MApp_InstParams;
+
+/**
+ *  \brief Display application object.
+ *  The test case execution happens based on values of this structure
+ */
+struct M2MApp_AppObj_t
+{
+    uint32_t numInst;
+    /**< Number of driver instances to open */
+    M2MApp_InstParams instParams[APP_DSS_M2M_CH_NUM];
+    /**< Instance object */
+    Dss_InitParams initParams;
+    /**< DSS Initialization Parameters */
+    uint32_t numFramesToConvert;
+    /**< Number of frames to convert for a given configuration */
+    volatile uint32_t numFramesWb;
+   /**< Number of frames wrote-back */
+};
+/* ========================================================================== */
+/*                  Internal/Private Function Declarations                   */
+/* ========================================================================== */
+
+
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+
+void App_consolePrintf(const char *pcString, ...);
+
+/* ========================================================================== */
+/*                              Global Variables                              */
+/* ========================================================================== */
+
+
+/* ========================================================================== */
+/*      Internal Function Declarations (Needed for other static inlines)      */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                       Static Function Definitions                          */
+/* ========================================================================== */
+
+/* None */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef DSS_DISPLAY_TEST_CFG_H_ */
+
+/* @} */
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/main_rtos.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/main_rtos.c
new file mode 100755
index 00000000..22d82467
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/main_rtos.c
@@ -0,0 +1,189 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file main_rtos.c
+ *
+ *  \brief Main file for RTOS builds
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <ti/board/board.h>
+#include <ti/drv/dss/examples/utils/app_utils.h>
+#include <ti/drv/sciclient/sciclient.h>
+#include <ti/csl/soc.h>
+#include <ti/drv/pm/pmlib.h>
+#include "dss_m2m_test_cfg.h"
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* Test application stack size */
+#define DISP_APP_TSK_STACK_MAIN         (10U * 1024U)
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+
+static void taskFxn(void* a0, void* a1);
+extern int32_t Dss_displayM2MTest(void);
+static void App_clkRateSet(uint32_t moduleId,
+                           uint32_t clkId,
+                           uint64_t clkRateHz);
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+
+/* Test application stack */
+static uint8_t gDispAppTskStackMain[DISP_APP_TSK_STACK_MAIN];
+
+/* ========================================================================== */
+/*                          Function Definitions                              */
+/* ========================================================================== */
+
+int main(void)
+{
+    TaskP_Handle task;
+    TaskP_Params taskParams;
+
+    OS_init();
+
+    /* Initialize the task params */
+    TaskP_Params_init(&taskParams);
+    /* Set the task priority higher than the default priority (1) */
+    taskParams.priority = 2;
+    taskParams.stack = gDispAppTskStackMain;
+    taskParams.stacksize = sizeof(gDispAppTskStackMain);
+
+    task = TaskP_create(&taskFxn, &taskParams);
+    if(NULL == task)
+    {
+        OS_stop();
+    }
+
+    OS_start();    /* does not return */
+
+    return(0);
+}
+
+static void taskFxn(void* a0, void* a1)
+{
+    int32_t retVal = CSL_PASS;
+    uint64_t clkFreq = 0U;
+    Board_initCfg boardCfg;
+
+    boardCfg = BOARD_INIT_PINMUX_CONFIG |
+                BOARD_INIT_UNLOCK_MMR |
+                BOARD_INIT_UART_STDIO;
+    Board_init(boardCfg);
+
+    Sciclient_init(NULL);
+    retVal += Sciclient_pmSetModuleState(TISCI_DEV_DSS0,
+                                   TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
+                                   TISCI_MSG_FLAG_AOP,
+                                   SCICLIENT_SERVICE_WAIT_FOREVER);
+    retVal += Sciclient_pmSetModuleState(TISCI_DEV_DSS_DSI0,
+                                   TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
+                                   TISCI_MSG_FLAG_AOP,
+                                   SCICLIENT_SERVICE_WAIT_FOREVER);
+    retVal += Sciclient_pmSetModuleState(TISCI_DEV_DSS_EDP0,
+                                   TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
+                                   TISCI_MSG_FLAG_AOP,
+                                   SCICLIENT_SERVICE_WAIT_FOREVER);
+
+    /* set DSS VP4 clocks */
+    App_clkRateSet(TISCI_DEV_DSS0,
+                   TISCI_DEV_DSS0_DSS_INST0_DPI_3_IN_2X_CLK,
+                   148500000U);
+    /* Get the DSS VP4 clock frequencies */
+    retVal += PMLIBClkRateGet(TISCI_DEV_DSS0,
+                              TISCI_DEV_DSS0_DSS_INST0_DPI_0_IN_2X_CLK,
+                              &clkFreq);
+    App_consolePrintf("\n TISCI_DEV_DSS0_DSS_INST0_DPI_0_IN_2X_CLK = %lld Hz\n", clkFreq);
+    retVal += PMLIBClkRateGet(TISCI_DEV_DSS0,
+                              TISCI_DEV_DSS0_DSS_INST0_DPI_1_IN_2X_CLK,
+                              &clkFreq);
+    App_consolePrintf("\n TISCI_DEV_DSS0_DSS_INST0_DPI_1_IN_2X_CLK = %lld Hz\n", clkFreq);
+    retVal += PMLIBClkRateGet(TISCI_DEV_DSS0,
+                              TISCI_DEV_DSS0_DSS_INST0_DPI_2_IN_2X_CLK,
+                              &clkFreq);
+    App_consolePrintf("\n TISCI_DEV_DSS0_DSS_INST0_DPI_2_IN_2X_CLK = %lld Hz\n", clkFreq);
+    retVal += PMLIBClkRateGet(TISCI_DEV_DSS0,
+                              TISCI_DEV_DSS0_DSS_INST0_DPI_3_IN_2X_CLK,
+                              &clkFreq);
+    App_consolePrintf("\n TISCI_DEV_DSS0_DSS_INST0_DPI_3_IN_2X_CLK = %lld Hz\n", clkFreq);
+    if (retVal == CSL_PASS)
+    {
+        Dss_displayM2MTest();
+    }
+
+    return;
+}
+
+
+void App_wait(uint32_t wait_in_ms)
+{
+    TaskP_sleep(wait_in_ms);
+}
+
+static void App_clkRateSet(uint32_t moduleId,
+                           uint32_t clkId,
+                           uint64_t clkRateHz)
+{
+    int32_t status;
+    uint64_t currClkFreqHz;
+
+    status = PMLIBClkRateGet(moduleId, clkId, &currClkFreqHz);
+    if ((status == CSL_PASS) &&
+        (currClkFreqHz != clkRateHz))
+    {
+        status = PMLIBClkRateSet(moduleId, clkId, clkRateHz);
+        if (status == CSL_PASS)
+        {
+            App_consolePrintf("\nPMLIBClkRateSet Passed for clock Id = %d\n", clkId);
+        }
+        else
+        {
+            App_consolePrintf("\nPMLIBClkRateSet failed for clock Id = %d\n", clkId);
+        }
+    }
+}
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile
new file mode 100755
index 00000000..6cc880f9
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile
@@ -0,0 +1,12 @@
+#
+# This file is the makefile for building DSS display test app for TI RTOS
+#
+ifeq ($(RULES_MAKE), )
+include $(PDK_INSTALL_PATH)/ti/build/Rules.make
+else
+include $(RULES_MAKE)
+endif
+
+APP_NAME = dss_m2m_testapp_$(BUILD_OS_TYPE)
+
+include makefile.mk
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile.mk b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile.mk
new file mode 100755
index 00000000..c779e39c
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/examples/dss_m2m_test/makefile.mk
@@ -0,0 +1,52 @@
+#
+# This file is the makefile for building DSS display test app for both TI RTOS
+# and baremetal
+#
+
+SRCDIR = .
+INCDIR = .
+
+# List all the external components/interfaces, whose interface header files
+#  need to be included for this component
+INCLUDE_EXTERNAL_INTERFACES = pdk
+
+ifeq ($(BUILD_OS_TYPE),tirtos)
+  CFLAGS_OS_DEFINES = -DUSE_BIOS
+  INCLUDE_EXTERNAL_INTERFACES += xdc bios
+  COMP_LIST_COMMON = $(PDK_COMMON_TIRTOS_COMP)
+  # Enable XDC build for application by providing XDC CFG File per core
+  XDC_CFG_FILE_$(CORE) = $(PDK_INSTALL_PATH)/ti/build/$(SOC)/sysbios_$(ISA).cfg
+endif
+
+ifeq ($(BUILD_OS_TYPE),freertos)
+  CFLAGS_OS_DEFINES = -DFREERTOS
+  INCLUDE_EXTERNAL_INTERFACES += freertos
+  COMP_LIST_COMMON += $(PDK_COMMON_FREERTOS_COMP)
+endif
+
+# List all the specific components required by the application
+COMP_LIST_COMMON += fvid2 dss
+
+# Common source files and CFLAGS across all platforms and cores
+PACKAGE_SRCS_COMMON = .
+SRCS_COMMON += main_rtos.c
+SRCS_COMMON += dss_m2m_test.c
+CFLAGS_LOCAL_COMMON += $(PDK_CFLAGS) $(DSS_CFLAGS) $(CFLAGS_OS_DEFINES)
+
+# Core/SoC/platform specific source files and CFLAGS
+# Example:
+#   SRCS_<core/SoC/platform-name> =
+#   CFLAGS_LOCAL_<core/SoC/platform-name> =
+
+# Include common make files
+ifeq ($(MAKERULEDIR), )
+#Makerule path not defined, define this and assume relative path from ROOTDIR
+  MAKERULEDIR := $(ROOTDIR)/ti/build/makerules
+  export MAKERULEDIR
+endif
+include $(MAKERULEDIR)/common.mk
+
+# OBJs and libraries are built by using rule defined in rules_<target>.mk
+#     and need not be explicitly specified here
+
+# Nothing beyond this point
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/include/dss_m2m.h b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/include/dss_m2m.h
new file mode 100755
index 00000000..fc0f51df
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/include/dss_m2m.h
@@ -0,0 +1,403 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \ingroup  DRV_DSS_MODULE
+ *  \defgroup DRV_DSS_M2M_MODULE Display Write-back Driver
+ *            This is DSS Display Write-back driver documentation
+ *
+ *  @{
+ */
+
+/**
+ *  \file dss_m2m.h
+ *
+ *  \brief DSS Display Write-back Driver interface file.
+ */
+
+#ifndef DSS_M2M_H_
+#define DSS_M2M_H_
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+
+/* None */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+/*
+ *  Display M2M driver IOCTLs.
+ */
+
+/**
+ *  \ingroup  DRV_DSS_M2M_MODULE
+ *  \defgroup DRV_DSS_M2M_IOCTL Display IOCTLs
+ *  @{
+ *
+ * These are display FVID2 APIs that can be called by the application.
+ * Display M2M driver supports additional IOCTLs from other modules/drivers
+ * and those are follows:
+ * 1. IOCTLs from Display Controller Driver (Refer to \ref DRV_DSS_DCTRL_IOCTL):
+ *      - IOCTL_DSS_DCTRL_SET_OVERLAY_PARAMS
+ *      - IOCTL_DSS_DCTRL_SET_LAYER_PARAMS
+ *      - IOCTL_DSS_DCTRL_SET_GLOBAL_DSS_PARAMS
+ *          - These Global Parameters are common across multiple driver handles
+ *            across multiple DSS drivers like DISP, DCTRL and M2M.
+ */
+
+/**
+ * \brief Command to set DSS display M2M pipeline parameters.
+ *
+ *  This IOCTL is used to program the DSS display parameters. Refer to structure
+ *  #Dss_WbPipeCfgParams for details on DSS parameters.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_WbPipeCfgParams
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ */
+#define IOCTL_DSS_M2M_SET_WB_PIPE_PARAMS          (DSS_M2M_IOCTL_BASE + 0x0001U)
+
+/**
+ * \brief Command to set MFLAG parameters for WB pipe.
+ *
+ *  This IOCTL can be used to set the MFLAG parameters for the given WB pipe.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_WbPipeMflagParams
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ *
+ */
+#define IOCTL_DSS_M2M_SET_WB_PIPE_MFLAG_PARAMS   (DSS_M2M_IOCTL_BASE + 0x0002U)
+
+/**
+ * \brief Command to get the display status.
+ *
+ *  This IOCTL can be used to get the display status like number of frames
+ *  displayed, repeated, queued. dequeued, etc.
+ *  Note: These counters will be reset either at the time of driver create or
+ *  while starting the display operation. See respective counter comments for
+ *  details.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_WbStatus
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ *
+ */
+#define IOCTL_DSS_M2M_GET_CURRENT_STATUS      (DSS_M2M_IOCTL_BASE + 0x0003U)
+
+/**
+ * \brief Command to program the CSC coefficients for WB Pipe.
+ *  By default BT 601 coefficients are set.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #CSL_DssCscCoeff
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ */
+#define IOCTL_DSS_M2M_SET_WB_PIPE_CSC_COEFF      (DSS_M2M_IOCTL_BASE + 0x0004U)
+
+/**
+ * \brief Command to program the write-back pipe DMA configuration parameters
+ *
+ * \param cmdArgs       [IN]  Pointer of type #CSL_DssWbPipeDmaCfg
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ */
+#define IOCTL_DSS_M2M_SET_WB_PIPE_DMA_CFG       (DSS_M2M_IOCTL_BASE + 0x0005U)
+
+/**
+ * \brief Command to set DSS display pipeline parameters.
+ *
+ *  This IOCTL is used to program the DSS display parameters. Refer to structure
+ *  #Dss_PipeCfgParams for details on DSS parameters.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_PipeCfgParams
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ */
+#define IOCTL_DSS_M2M_SET_PIPE_PARAMS          (DSS_M2M_IOCTL_BASE + 0x0006U)
+
+/**
+ * \brief Command to set MFLAG parameters for video pipe.
+ *
+ *  This IOCTL can be used to set the MFLAG parameters for the given video pipe.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_PipeMflagParams
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ *
+ */
+#define IOCTL_DSS_M2M_SET_PIPE_MFLAG_PARAMS   (DSS_M2M_IOCTL_BASE + 0x0007U)
+
+/**
+ * \brief Command to program the CSC coefficients for Video Pipe.
+ *  By default BT 601 coefficients are set.
+ *
+ * \param cmdArgs       [IN]  Pointer of type #Dss_PipeCscParams
+ * \param cmdArgsStatus [OUT] NULL
+ *
+ * \return  FVID2_SOK if successful, else suitable error code
+ */
+#define IOCTL_DSS_M2M_SET_PIPE_CSC_COEFF      (DSS_M2M_IOCTL_BASE + 0x0008U)
+/* @} */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+/**
+ *  \brief Structure containing video write-back pipe configuration.
+ */
+typedef struct
+{
+    CSL_DssWbPipeCfg pipeCfg;
+    /**< Configuration for WB pipeline
+     *   See \ref CSL_DssWbPipeCfg for details
+     *   Note: Only 'CSL_DSS_WB_PIPE_MODE_M2M' mode
+     *         supported for "pipeCfg.wbMode" */
+} Dss_WbPipeCfgParams;
+
+/**
+ *  \brief Structure containing Video write-back Pipe Mflag Information.
+ *   This structure is used as an argument to
+ *   IOCTL_DSS_M2M_SET_WB_PIPE_MFLAG_PARAMS.
+ */
+typedef struct
+{
+    CSL_DssWbPipeMFlagCfg mFlagCfg;
+    /**< MFlag configuration parameters for WB pipeline
+     *   See \ref CSL_DssWbPipeMFlagCfg for details */
+} Dss_WbPipeMflagParams;
+
+/**
+ *  \brief Structure containing current status of the display M2M driver.
+ *   This structure is used as an argument to IOCTL_DSS_M2M_GET_CURRENT_STATUS.
+ */
+typedef struct
+{
+    uint32_t queueCount;
+    /**< Counter to keep track of how many requests are queued to the driver.
+     *   Note: This counter will be reset at the time of driver create */
+    uint32_t dequeueCount;
+    /**< Counter to keep track of how many requests are dequeued from the
+     *   driver.
+     *   Note: This counter will be reset at the time of driver create */
+    uint32_t wbFrmCount;
+    /**< Counter to keep track of how many frames are wrote back to memory.
+     *   Note: This counter will be reset at the time of display start */
+    uint32_t underflowCount;
+    /**< Counter to keep track of number of underflows
+     *   Note: This counter will be reset at the time of driver create */
+} Dss_WbStatus;
+
+/**
+ *  \brief Structure containing display driver create arguments, used when
+ *   calling Fvid2_create(). Application shall maintain same create time
+ *   configurations between multiple driver handles for same WB pipe-line.
+ */
+typedef struct
+{
+    uint32_t numPipe;
+    /**< Number of Display pipe-lines used for given M2M/WB pipeline.
+     *   This should be set to '1' (as done in Dss_m2mCreateParamsInit()) */
+    uint32_t pipeId[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< ID DSS pipeline to use. Application shall only set pipe IDs which are used.
+     *   See \ref CSL_DssVidPipeId for details */
+    uint32_t overlayId;
+    /**< ID DSS overlay to use.
+     *   See \ref CSL_DssOverlayId for details */
+} Dss_WbCreateParams;
+
+/**
+ *  \brief DSS M2M driver create status. Returned after calling Fvid2_create().
+ */
+typedef struct
+{
+    int32_t retVal;
+    /**< Create status, FVID2_SOK on success, else failure. */
+} Dss_WbCreateStatus;
+
+/**
+ *  \brief Structure containing video pipe configuration.
+ *   This structure is used as an argument to
+ *   IOCTL_DSS_M2M_SET_PIPE_PARAMS.
+ */
+typedef struct
+{
+    uint32_t pipeId;
+    /**< Display Pipe-line ID */
+    Dss_DispParams cfgParams;
+    /**< Configuration for Display pipeline
+     *   See \ref Dss_DispParams for details */
+} Dss_PipeCfgParams;
+
+/**
+ *  \brief Structure containing Video Pipe Mflag Information.
+ *   This structure is used as an argument to
+ *   IOCTL_DSS_M2M_SET_PIPE_MFLAG_PARAMS.
+ */
+typedef struct
+{
+    uint32_t pipeId;
+    /**< Display Pipe-line ID */
+    Dss_DispPipeMflagParams mFlagCfg;
+    /**< MFlag configuration parameters for display pipeline
+     *   See \ref Dss_DispPipeMflagParams for details */
+} Dss_PipeMflagParams;
+
+/**
+ *  \brief Structure containing Video Pipe CSC Information.
+ *   This structure is used as an argument to
+ *   IOCTL_DSS_M2M_SET_PIPE_CSC_COEFF.
+ */
+typedef struct
+{
+    uint32_t pipeId;
+    /**< Display Pipe-line ID */
+    CSL_DssCscCoeff csc;
+    /**< MFlag configuration parameters for WB pipeline
+     *   See \ref CSL_DssCscCoeff for details */
+} Dss_PipeCscParams;
+/* ========================================================================== */
+/*                  Internal/Private Function Declarations                    */
+/* ========================================================================== */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+/**
+ *  \brief Dss_WbCreateParams structure init function.
+ *
+ *  \param  createParams  [IN]Pointer to #Dss_WbCreateParams structure.
+ *
+ *  \return None
+ */
+static inline void Dss_m2mCreateParamsInit(Dss_WbCreateParams *createParams);
+
+/**
+ *  \brief Dss_WbPipeCfgParams structure init function.
+ *
+ *  \param  cfgParams     [IN]Pointer to #Dss_WbPipeCfgParams structure.
+ *
+ *  \return None
+ */
+static inline void Dss_m2mPipeCfgParamsInit(Dss_WbPipeCfgParams *cfgParams);
+
+/**
+ *  \brief Dss_WbPipeMflagParams structure init function.
+ *
+ *  \param  mFlagParams   [IN]Pointer to #Dss_WbPipeMflagParams structure.
+ *
+ *  \return None
+ */
+static inline void Dss_m2mMFlagParamsInit(Dss_WbPipeMflagParams *mFlagParams);
+
+/**
+ *  \brief Dss_WbStatus structure init function.
+ *
+ *  \param  status       [IN]Pointer to #Dss_WbStatus structure.
+ *
+ *  \return None
+ */
+static inline void Dss_m2mStatusInit(Dss_WbStatus *status);
+/* ========================================================================== */
+/*                       Static Function Definitions                          */
+/* ========================================================================== */
+static inline void Dss_m2mCreateParamsInit(Dss_WbCreateParams *createParams)
+{
+    uint32_t loopCnt = 0U;
+
+    if(NULL != createParams)
+    {
+        createParams->numPipe = 1U;
+        for (loopCnt = 0U ;
+             loopCnt < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+             loopCnt++)
+        {
+            createParams->pipeId[loopCnt] = CSL_DSS_VID_PIPE_ID_MAX;
+        }
+        createParams->overlayId = CSL_DSS_OVERLAY_ID_1;
+    }
+}
+
+static inline void Dss_m2mPipeCfgParamsInit(Dss_WbPipeCfgParams *cfgParams)
+{
+    if(NULL != cfgParams)
+    {
+        CSL_dssWbPipeCfgInit(&(cfgParams->pipeCfg));
+        /* dataFormat is fixed as Display pipe/overlay can only output in
+           ARGB48 format */
+        cfgParams->pipeCfg.inFmt.dataFormat = FVID2_DF_ARGB48_12121212;
+        /* Set mode to M2M mode */
+        cfgParams->pipeCfg.wbMode = CSL_DSS_WB_PIPE_MODE_M2M;
+    }
+}
+
+static inline void Dss_m2mMFlagParamsInit(Dss_WbPipeMflagParams *mFlagParams)
+{
+    if(NULL != mFlagParams)
+    {
+        CSL_dssWbPipeMFlagCfgInit(&(mFlagParams->mFlagCfg));
+    }
+}
+
+static inline void Dss_m2mStatusInit(Dss_WbStatus *status)
+{
+    if(NULL != status)
+    {
+        status->queueCount     = 0U;
+        status->dequeueCount   = 0U;
+        status->wbFrmCount     = 0U;
+        status->underflowCount = 0U;
+    }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef DSS_M2M_H_ */
+
+/* @} */
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/common/dss_init.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/common/dss_init.c
index 5bdc8698..29b593f4 100755
--- a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/common/dss_init.c
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/common/dss_init.c
@@ -47,7 +47,7 @@
 #include <ti/drv/dss/src/drv/common/dss_evtMgr.h>
 #include <ti/drv/dss/src/drv/dctrl/dss_dctrlDrv.h>
 #include <ti/drv/dss/src/drv/disp/dss_dispDrv.h>
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined (SOC_J784S4)
 #include <ti/drv/dss/src/drv/m2m/dss_m2mDrv.h>
 #endif
 
@@ -167,7 +167,7 @@ int32_t Dss_init(const Dss_InitParams *initParams)
         }
         retVal += Dss_dispDrvInit(numInst, dispInitParams);
     }
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined (SOC_J784S4)
     if(FVID2_SOK == retVal)
     {
         /* Initialize display M2M driver */
@@ -182,7 +182,7 @@ int32_t Dss_deInit(void)
 {
     int32_t retVal = FVID2_SOK;
 
-#if defined (SOC_J721E) || defined (SOC_J721S2)
+#if defined (SOC_J721E) || defined (SOC_J721S2) || defined (SOC_J784S4)
     retVal += Dss_m2mDrvDeInit();
 #endif
     retVal += Dss_dispDrvDeInit();
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mApi.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mApi.c
new file mode 100755
index 00000000..53a626b3
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mApi.c
@@ -0,0 +1,1753 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2018 - 2022
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_dispApi.c
+ *
+ *  \brief File containing the DSS display driver implementation.
+ *
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+
+#include <ti/drv/dss/dss.h>
+#include <ti/drv/dss/src/drv/common/dss_evtMgr.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispDrv.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispPriv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlDrv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlPriv.h>
+#include <ti/drv/dss/src/drv/m2m/dss_m2mDrv.h>
+#include <dss_soc_priv.h>
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+/**
+ *  Below ifdef __cplusplus is added so that C++ build passes without
+ *  typecasting. This is because the prototype is build as C type
+ *  whereas this file is build as CPP file. Hence we get C++ build error.
+ *  Also if typecasting is used, then we get MisraC error Rule 11.1.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+DssM2MDrv_CommonObj gDssM2mCommonObj;
+
+Dss_EvtMgrClientInfo gDss_M2MEvtMgrClientInfo[DSS_DISP_EVT_MGR_MAX_CLIENTS];
+/* ========================================================================== */
+/*                  Internal/Private Function Declarations                    */
+/* ========================================================================== */
+static int32_t Dss_m2mDrvCreateInstQueues(DssM2MDrv_VirtContext *context);
+
+static int32_t Dss_m2mDrvDeleteInstQueues(DssM2MDrv_VirtContext *context);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+static uint32_t Dss_m2mDrvWbPipeCfgChk(const Dss_WbPipeCfgParams *instCfg,
+                                       const Dss_WbPipeCfgParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+static uint32_t Dss_m2mDrvWbDmaCfgChk(const CSL_DssWbPipeDmaCfg *instCfg,
+                                      const CSL_DssWbPipeDmaCfg *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+static uint32_t Dss_m2mDrvWbMFlagCfgChk(const Dss_WbPipeMflagParams *instCfg,
+                                        const Dss_WbPipeMflagParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+static uint32_t Dss_m2mDrvWbCscCfgChk(const CSL_DssCscCoeff *instCfg,
+                                      const CSL_DssCscCoeff *progCfg);
+
+static int32_t Dss_m2mDrvPrgramWbPipe(DssM2MDrv_VirtContext *context);
+/*
+ * Display IOCTLs
+ */
+static int32_t Dss_m2mDrvIoctlStart(DssM2MDrv_VirtContext *context);
+
+static int32_t Dss_m2mDrvIoctlStop(DssM2MDrv_VirtContext *context);
+
+static int32_t Dss_m2mDrvIoctlSetWbPipeParams(DssM2MDrv_VirtContext *context,
+                                       const Dss_WbPipeCfgParams *pipeCfg);
+
+static int32_t Dss_m2mDrvIoctlSetmFlagParams(DssM2MDrv_VirtContext *context,
+                                      const Dss_WbPipeMflagParams *mFlagParams);
+
+static int32_t Dss_m2mDrvIoctlGetCurrentStatus(DssM2MDrv_VirtContext *context,
+                                               Dss_WbStatus *status);
+
+static int32_t Dss_m2mDrvIoctlSetWbPipeCsc(DssM2MDrv_VirtContext *context,
+                                    const CSL_DssCscCoeff *csc);
+
+static int32_t Dss_m2mDrvIoctlSetDmaCfg(DssM2MDrv_VirtContext *context,
+                                        const CSL_DssWbPipeDmaCfg *dmaCfg);
+
+static void Dss_wbPipeCbFxn(const uint32_t *event,
+                            uint32_t numEvents,
+                            void *arg);
+
+static void Dss_wbPipeDmaCompletionCbFxn(DssM2MDrv_InstObj *instObj);
+
+static int32_t Dss_m2mValidateM2mPipeParams(const Dss_WbPipeCfgParams *wbPipeParams);
+
+/* ========================================================================== */
+/*                          Function Definitions                              */
+/* ========================================================================== */
+/* FVID2 independent functions: Init and deinit*/
+int32_t Dss_m2mDrvInit(const Dss_InitParams *initParams)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_CommonObj *m2mObj;
+    uint32_t loopCnt = 0U, contextCnt = 0U, eventGroup, pipeIdx = 0U;
+    uint32_t numEvents, evtMgrId, numHandle;
+    DssM2MDrv_VirtContext *virtContext;
+    DssM2MDrv_InstObj *instObj;
+    SemaphoreP_Params semParams;
+    const Dss_SocInfo *socInfo;
+    Dss_EvtMgrClientInfo *pClientInfo;
+    uint32_t enabledEvents[DSS_EVT_MGR_MAX_CLIENT_EVENTS];
+
+    m2mObj = &gDssM2mCommonObj;
+    GT_assert(DssTrace, (NULL != m2mObj));
+
+    /* Reset full driver object to '0' and set only required parameters */
+    Fvid2Utils_memset(m2mObj, 0U, sizeof(DssM2MDrv_CommonObj));
+    socInfo = Dss_getSocInfo();
+    Fvid2Utils_memcpy(&m2mObj->socInfo,
+                      socInfo,
+                      sizeof(Dss_SocInfo));
+    for(loopCnt = 0U ; loopCnt < DSS_DISP_EVT_MGR_MAX_CLIENTS ; loopCnt++)
+    {
+        pClientInfo = &gDss_M2MEvtMgrClientInfo[loopCnt];
+        Fvid2Utils_memset(pClientInfo, 0U, sizeof (Dss_EvtMgrClientInfo));
+    }
+
+    m2mObj->getTimeStamp = NULL;
+    m2mObj->isRegistered = (uint32_t)FALSE;
+
+    /* Allocate instance semaphore */
+    SemaphoreP_Params_init(&semParams);
+    semParams.mode           = SemaphoreP_Mode_BINARY;
+    m2mObj->lockSem = SemaphoreP_create(1U, &semParams);
+    if (m2mObj->lockSem == NULL)
+    {
+        GT_0trace(DssTrace, GT_ERR, "Instance semaphore create failed!!\r\n");
+        retVal = FVID2_EALLOC;
+    }
+
+    for (loopCnt = 0U ; loopCnt < DSSM2M_NUM_WB_PIPELINE ; loopCnt++)
+    {
+        m2mObj->numVirtContUsed[loopCnt] = 0U;
+        instObj                          = &m2mObj->instObj[loopCnt];
+        instObj->drvInstId               = loopCnt;
+        instObj->inUse                   = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+        instObj->commonObjRef            = m2mObj;
+        instObj->wbRegs                  = socInfo->wbRegs[loopCnt];
+        instObj->commRegs                = NULL;
+        instObj->numPipe                 = 0U;
+        for (pipeIdx = 0U ;
+             pipeIdx < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+             pipeIdx++)
+        {
+            instObj->pipeRegs[pipeIdx] = NULL;
+            instObj->pipeId[pipeIdx]   = CSL_DSS_VID_PIPE_ID_MAX;
+        }
+        instObj->ovrRegs                 = NULL;
+        instObj->overlayId               = CSL_DSS_OVERLAY_ID_MAX;
+        instObj->pathCfgDone             = (uint32_t) FALSE;
+        for (contextCnt = 0U ;
+             contextCnt < DSSM2M_NUM_VIRTUAL_CONTEXT ;
+             contextCnt++)
+        {
+            virtContext            = &m2mObj->virtContext[loopCnt][contextCnt];
+            for (pipeIdx = 0U ;
+                 pipeIdx < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+                 pipeIdx++)
+            {
+                virtContext->pipeId[pipeIdx] = CSL_DSS_VID_PIPE_ID_MAX;
+            }
+            virtContext->numPipe   = 0U;
+            virtContext->overlayId = CSL_DSS_OVERLAY_ID_MAX;
+            virtContext->contextId = contextCnt;
+            virtContext->state     = DSSM2M_DRV_STATE_IDLE;
+            virtContext->inUse     = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+            virtContext->instObj   = instObj;
+        }
+        /* Register WB Pipeline Events */
+        Dss_convModuletoEventGroup(&eventGroup,
+                                   instObj->drvInstId,
+                                   DSS_EVENT_GROUP_TYPE_WB_PIPE);
+        GT_assert(DssTrace, (DSS_EVENT_GROUP_INVALID != eventGroup));
+
+        Dss_getEnabledWbPipeFuncEvents(&enabledEvents[0U], &numEvents);
+        evtMgrId = Dss_getEvtMgrFuncIntrId();
+        numHandle = instObj->numRegEvtHandle;
+        instObj->evtGroupHandle[instObj->numRegEvtHandle] =
+                    Dss_evtMgrRegister(
+                        evtMgrId,
+                        eventGroup,
+                        (const uint32_t *)&enabledEvents[0U],
+                        numEvents,
+                        Dss_wbPipeCbFxn,
+                        (void *)&gDss_M2MEvtMgrClientInfo[numHandle]);
+        /* Enable Events */
+        retVal = Dss_evtMgrEnable(instObj->evtGroupHandle[instObj->numRegEvtHandle]);
+        instObj->numRegEvtHandle++;
+        if (FVID2_SOK != retVal)
+        {
+            GT_0trace(DssTrace, GT_ERR,
+                "Registering/Enabling to DSS Event manager failed\r\n");
+        }
+    }
+
+    if (FVID2_SOK == retVal)
+    {
+        /* Initialize Driver operations */
+        Fvid2DrvOps_init(&m2mObj->fvidDrvOps);
+        m2mObj->fvidDrvOps.drvId                  = DSS_M2M_DRV_ID;
+        m2mObj->fvidDrvOps.createFxn              = &Dss_m2mCreate;
+        m2mObj->fvidDrvOps.deleteFxn              = &Dss_m2mDelete;
+        m2mObj->fvidDrvOps.controlFxn             = &Dss_m2mControl;
+        m2mObj->fvidDrvOps.processRequestFxn      = &Dss_m2mProcessRequest;
+        m2mObj->fvidDrvOps.getProcessedRequestFxn = &Dss_m2mGetProcessedRequest;
+
+        retVal = Fvid2_registerDriver(&m2mObj->fvidDrvOps);
+        if (FVID2_SOK != retVal)
+        {
+            GT_0trace(DssTrace, GT_ERR,
+                "Registering to FVID2 driver manager failed\r\n");
+            /* Un-initialize the internal objects if error occurs: deInit() */
+        }
+        else
+        {
+            /* Init successful */
+            m2mObj->isRegistered = (uint32_t) TRUE;
+        }
+    }
+
+
+    return (retVal);
+}
+
+int32_t Dss_m2mDrvDeInit(void)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_CommonObj *m2mObj;
+    uint32_t loopCnt = 0U, contextCnt = 0U, eventIdx = 0U, pipeIdx = 0U;
+    DssM2MDrv_VirtContext *virtContext;
+    DssM2MDrv_InstObj *instObj;
+
+    m2mObj = &gDssM2mCommonObj;
+    GT_assert(DssTrace, (NULL != m2mObj));
+
+    if (m2mObj->lockSem != NULL)
+    {
+        /* Delete semaphore */
+        (void)SemaphoreP_delete(m2mObj->lockSem);
+    }
+    for (loopCnt = 0U ; loopCnt < DSSM2M_NUM_WB_PIPELINE ; loopCnt++)
+    {
+        instObj                          = &m2mObj->instObj[loopCnt];
+        instObj->inUse                   = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+        instObj->commonObjRef            = NULL;
+        instObj->commRegs                = NULL;
+        for (pipeIdx = 0U ;
+             pipeIdx < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+             pipeIdx++)
+        {
+            instObj->pipeRegs[pipeIdx] = NULL;
+            instObj->pipeId[pipeIdx]   = CSL_DSS_VID_PIPE_ID_MAX;
+        }
+        instObj->numPipe                 = 0U;
+        instObj->ovrRegs                 = NULL;
+        instObj->wbRegs                  = NULL;
+        instObj->pathCfgDone             = (uint32_t) FALSE;
+        for (contextCnt = 0U ;
+             contextCnt < DSSM2M_NUM_VIRTUAL_CONTEXT ;
+             contextCnt++)
+        {
+            virtContext            = &m2mObj->virtContext[loopCnt][contextCnt];
+            virtContext->numPipe   = 0U;
+            virtContext->state     = DSSM2M_DRV_STATE_UNINIT;
+            virtContext->inUse     = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+            virtContext->instObj   = NULL;
+        }
+        /* Unregister event groups and delete object */
+        for(eventIdx = 0U ; eventIdx < instObj->numRegEvtHandle ; eventIdx++)
+        {
+            retVal += Dss_evtMgrUnRegister(instObj->evtGroupHandle[eventIdx]);
+            instObj->numRegEvtHandle--;
+        }
+    }
+
+    /* unregister driver */
+    retVal = Fvid2_unRegisterDriver(&m2mObj->fvidDrvOps);
+    if (retVal != FVID2_SOK)
+    {
+        GT_0trace(DssTrace, GT_ERR,
+            "Unregistering from FVID2 driver manager failed\r\n");
+    }
+
+    return (retVal);
+}
+
+/* FVID2 Functions */
+Fdrv_Handle Dss_m2mCreate(uint32_t drvId,
+                          uint32_t instId,
+                          void *createArgs,
+                          void *createStatusArgs,
+                          const Fvid2_DrvCbParams *fdmCbParams)
+{
+    Fdrv_Handle drvHandle = NULL;
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_CommonObj *m2mObj;
+    Dss_WbCreateParams *createParams;
+    Dss_WbCreateStatus *createStatus;
+    DssM2MDrv_VirtContext *virtContext;
+    DssM2MDrv_InstObj *instObj;
+    uint32_t loopCnt = 0U;
+
+    m2mObj = &gDssM2mCommonObj;
+    GT_assert(DssTrace, (NULL != m2mObj));
+
+    /* Check for NULL pointers and invalid arguments */
+    if ((NULL == createStatusArgs) ||
+        (NULL == fdmCbParams) ||
+        (DSS_M2M_DRV_ID != drvId) ||
+        (DSS_M2M_WB_PIPELINE_ID_MAX <= instId))
+    {
+        GT_0trace(DssTrace, GT_ERR, "Invalid arguments\r\n");
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        createParams = (Dss_WbCreateParams *)createArgs;
+        createStatus = (Dss_WbCreateStatus *)createStatusArgs;
+        /* Get free Virtual Context */
+        for (loopCnt = 0U ; loopCnt < DSSM2M_NUM_VIRTUAL_CONTEXT ; loopCnt++)
+        {
+            if (m2mObj->virtContext[instId][loopCnt].inUse ==
+                                DSSM2M_DRV_USAGE_STATUS_NOT_USED)
+            {
+                break;
+            }
+        }
+        if (DSSM2M_NUM_VIRTUAL_CONTEXT <= loopCnt)
+        {
+            retVal = FVID2_EALLOC;
+            GT_0trace(DssTrace, GT_ERR, "No more instances to allocate...\r\n");
+        }
+        else
+        {
+            virtContext = &m2mObj->virtContext[instId][loopCnt];
+            instObj = virtContext->instObj;
+            GT_assert(DssTrace, (NULL != instObj->commonObjRef));
+
+            if(NULL != instObj->commonObjRef->lockSem)
+            {
+                /* Take the instance semaphore */
+                (void) SemaphoreP_pend(instObj->commonObjRef->lockSem,
+                                       SemaphoreP_WAIT_FOREVER);
+            }
+
+            for (loopCnt = 0U ;
+                 loopCnt < createParams->numPipe ;
+                 loopCnt++)
+            {
+                if (((instObj->pipeId[loopCnt] != CSL_DSS_VID_PIPE_ID_MAX) &&
+                    (instObj->pipeId[loopCnt] != createParams->pipeId[loopCnt])) ||
+                    (createParams->pipeId[loopCnt] == CSL_DSS_VID_PIPE_ID_MAX))
+                {
+                    break;
+                }
+            }
+            if (loopCnt < createParams->numPipe)
+            {
+                retVal = FVID2_EBADARGS;
+                GT_0trace(DssTrace, GT_ERR, "Wrong Pipe instance used!!!\r\n");
+            }
+
+            /* Check if same DSS Pipe and Overlay is provided within
+               different Create calls */
+            if (((instObj->overlayId != CSL_DSS_OVERLAY_ID_MAX) &&
+                 (instObj->overlayId != createParams->overlayId)) ||
+                 (createParams->overlayId == CSL_DSS_OVERLAY_ID_MAX))
+            {
+                retVal = FVID2_EBADARGS;
+                GT_0trace(DssTrace, GT_ERR, "Wrong Overlay instance used!!!\r\n");
+            }
+
+            if (FVID2_SOK == retVal)
+            {
+                /* Update app provided configurations in the instance object */
+                /* Copy create and Call-back parameters */
+                Fvid2Utils_memcpy(&virtContext->createParams,
+                                  createParams,
+                                  sizeof(Dss_WbCreateParams));
+                Fvid2Utils_memcpy(&virtContext->fdmCbParams,
+                                  fdmCbParams,
+                                  sizeof(Fvid2_DrvCbParams));
+                /* Set status to '0' */
+                Fvid2Utils_memset(&virtContext->wbStatus, 0U, sizeof(Dss_WbStatus));
+                /* Clear instance configurations,
+                   these will be later set by IOCTLs */
+                Fvid2Utils_memset(&virtContext->instCfg,
+                                  0U,
+                                  sizeof(DssM2MDrv_moduleCfg));
+                for (loopCnt = 0U ;
+                     loopCnt < createParams->numPipe ;
+                     loopCnt++)
+                {
+                    virtContext->pipeId[loopCnt] = createParams->pipeId[loopCnt];
+                }
+                virtContext->numPipe   = createParams->numPipe;
+                virtContext->overlayId = createParams->overlayId;
+            }
+
+            if (FVID2_SOK == retVal)
+            {
+                virtContext->doneQ = NULL;
+                retVal = Fvid2Utils_constructQ(&virtContext->doneLlObj);
+                GT_assert(DssTrace, (retVal == FVID2_SOK));
+                virtContext->doneQ = &virtContext->doneLlObj;
+            }
+
+            if (FVID2_SOK == retVal)
+            {
+                if ((0U == m2mObj->numVirtContUsed[instId]) &&
+                    (DSSM2M_DRV_USAGE_STATUS_NOT_USED == instObj->inUse))
+                {
+                    for (loopCnt = 0U ;
+                         loopCnt < createParams->numPipe ;
+                         loopCnt++)
+                    {
+                        instObj->pipeId[loopCnt] = virtContext->pipeId[loopCnt];
+                    }
+                    instObj->overlayId = virtContext->overlayId;
+                    instObj->numPipe   = virtContext->numPipe;
+                    /* Set instance status */
+                    Fvid2Utils_memset(&instObj->status,
+                                      0U,
+                                      sizeof(Dss_WbStatus));
+                    /* Create Queues for Buffer Management - Do this for
+                       only first create call*/
+                    retVal = Dss_m2mDrvCreateInstQueues(virtContext);
+                }
+
+                if (FVID2_SOK == retVal)
+                {
+                    /* Set states of driver object and instance object */
+                    virtContext->numBufQed = 0U;
+                    instObj->commRegs      =
+                        instObj->commonObjRef->socInfo.commRegs[CSL_DSS_COMM_REG_ID_0];
+                    instObj->ovrRegs       =
+                        instObj->commonObjRef->socInfo.overlayRegs[createParams->overlayId];
+                    for (loopCnt = 0U ;
+                         loopCnt < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+                         loopCnt++)
+                    {
+                        instObj->pipeRegs[createParams->pipeId[loopCnt]] =
+                            instObj->commonObjRef->socInfo.pipeRegs[createParams->pipeId[loopCnt]];
+                    }
+                    virtContext->inUse     = DSSM2M_DRV_USAGE_STATUS_IN_USE;
+                    virtContext->state     = DSSM2M_DRV_STATE_CREATED;
+                    instObj->inUse         = DSSM2M_DRV_USAGE_STATUS_IN_USE;
+                    m2mObj->numVirtContUsed[instId]++;
+                    drvHandle = (Fdrv_Handle)virtContext;
+                }
+            }
+            /* Configure WB pipeline input connection */
+            if (FVID2_SOK == retVal)
+            {
+                switch (createParams->overlayId)
+                {
+                    case CSL_DSS_OVERLAY_ID_1:
+                        CSL_dssSetWbInputCh(instObj->commRegs,
+                                            CSL_DSS_WB_INPUT_OVERLAY1);
+                    break;
+                    case CSL_DSS_OVERLAY_ID_2:
+                        CSL_dssSetWbInputCh(instObj->commRegs,
+                                            CSL_DSS_WB_INPUT_OVERLAY2);
+                    break;
+                    case CSL_DSS_OVERLAY_ID_3:
+                        CSL_dssSetWbInputCh(instObj->commRegs,
+                                            CSL_DSS_WB_INPUT_OVERLAY3);
+                    break;
+                    case CSL_DSS_OVERLAY_ID_4:
+                        CSL_dssSetWbInputCh(instObj->commRegs,
+                                            CSL_DSS_WB_INPUT_OVERLAY4);
+                    break;
+                    default:
+                        GT_0trace(DssTrace,
+                                  GT_ERR,
+                                  "Wrong Overlay instance used!!!\r\n");
+                    break;
+                }
+            }
+
+            if(NULL != instObj->commonObjRef->lockSem)
+            {
+                /* Post the instance semaphore */
+                (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+            }
+        }
+        if (NULL != createStatusArgs)
+        {
+            createStatus->retVal = retVal;
+        }
+    }
+
+    return (drvHandle);
+}
+
+int32_t Dss_m2mDelete(Fdrv_Handle handle, void *reserved)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t pipeIdx;
+    DssM2MDrv_CommonObj *m2mObj;
+    DssM2MDrv_VirtContext *virtContext;
+    DssM2MDrv_InstObj *instObj;
+    DssM2M_DrvQueObj *qObj;
+
+    m2mObj = &gDssM2mCommonObj;
+    GT_assert(DssTrace, (NULL != m2mObj));
+
+    if (NULL == handle)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        virtContext = (DssM2MDrv_VirtContext *)handle;
+        instObj = virtContext->instObj;
+
+        /* Set states of driver object and instance object */
+        virtContext->inUse = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+        virtContext->state = DSSM2M_DRV_STATE_IDLE;
+        m2mObj->numVirtContUsed[virtContext->instObj->drvInstId]--;
+
+        if(NULL != virtContext->doneQ)
+        {
+            /* Free-up all the queued free queue objects */
+            do
+            {
+                qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(virtContext->doneQ);
+                if (NULL != qObj)
+                {
+                    Fvid2Utils_queue(instObj->bmObj.freeQ, &qObj->qElem, qObj);
+                }
+            } while (NULL != qObj);
+
+            /* Delete the free Q */
+            Fvid2Utils_destructQ(virtContext->doneQ);
+            virtContext->doneQ = NULL;
+        }
+        for (pipeIdx = 0U ;
+             pipeIdx < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+             pipeIdx++)
+        {
+            virtContext->pipeId[pipeIdx] = CSL_DSS_VID_PIPE_ID_MAX;
+        }
+        virtContext->numPipe   = 0U;
+        virtContext->overlayId = CSL_DSS_OVERLAY_ID_MAX;
+
+        /* Delete Queues only on delete call for last opened Virtual context */
+        if ((0U == m2mObj->numVirtContUsed[virtContext->instObj->drvInstId]) &&
+                    (DSSM2M_DRV_USAGE_STATUS_IN_USE == instObj->inUse))
+        {
+            for (pipeIdx = 0U ;
+                 pipeIdx < DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE ;
+                 pipeIdx++)
+            {
+                instObj->pipeRegs[pipeIdx] = NULL;
+                instObj->pipeId[pipeIdx]   = CSL_DSS_VID_PIPE_ID_MAX;
+            }
+            instObj->numPipe   = 0U;
+            instObj->overlayId = CSL_DSS_OVERLAY_ID_MAX;
+            instObj->commRegs  = NULL;
+            instObj->ovrRegs   = NULL;
+            if(NULL != instObj->commonObjRef->lockSem)
+            {
+                /* Take the instance semaphore */
+                (void) SemaphoreP_pend(instObj->commonObjRef->lockSem,
+                                       SemaphoreP_WAIT_FOREVER);
+            }
+
+            retVal = Dss_m2mDrvDeleteInstQueues(virtContext);
+
+            if(NULL != instObj->commonObjRef->lockSem)
+            {
+                /* Post the instance semaphore */
+                (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+            }
+            instObj->inUse = DSSM2M_DRV_USAGE_STATUS_NOT_USED;
+        }
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mProcessRequest(Fdrv_Handle handle,
+                              Fvid2_FrameList *inProcessList,
+                              Fvid2_FrameList *outProcessList,
+                              uint32_t timeout)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_VirtContext *virtContext= NULL;
+    DssM2MDrv_InstObj *instObj = NULL;
+    uint32_t semTimeout, frmCnt, cookie, loopCnt;
+    DssM2M_DrvQueObj *qObj;
+    DssM2M_DrvBufManObj *bmObj;
+
+    /** Steps
+     *  1. Get a queue object from the freeQ. Assert error if NULL.
+     *  2. Copy handle into queue object
+     *  3. Copy frame lists into queue object
+     *  4. Move the queue object to reqQ
+     *  5. Increment Queue Count in the status
+     *  6. If number of elements in currQ < 1, then do following
+     *     a. Get a queue object from the reqQ. Assert error if NULL
+     *     b. Disable DSS and WB pipeline
+     *     c. Re-program DSS pipeline, Overlay and WB Pipeline if needed
+     *     d. Set buffer addresses in the WB & DSS Pipeline
+     *     e. Enable DSS and WB pipeline
+     *     f. Move the queue object to currQ
+     */
+    if ((NULL == handle) || (NULL == inProcessList) || (NULL == outProcessList))
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    if (FVID2_SOK == retVal)
+    {
+        virtContext = (DssM2MDrv_VirtContext *)handle;
+        instObj     = virtContext->instObj;
+        GT_assert(DssTrace, (NULL != instObj));
+        bmObj       = &instObj->bmObj;
+        GT_assert(DssTrace, (NULL != bmObj));
+
+        if ((instObj->inUse != DSSM2M_DRV_USAGE_STATUS_IN_USE) ||
+            (virtContext->inUse != DSSM2M_DRV_USAGE_STATUS_IN_USE) ||
+            ((virtContext->state == DSSM2M_DRV_STATE_IDLE) ||
+             (virtContext->state == DSSM2M_DRV_STATE_UNINIT)))
+        {
+            retVal = FVID2_EFAIL;
+            GT_0trace(DssTrace, GT_ERR,
+                "Invalid state: Can't submit request to an un-opened instance!!\r\n");
+        }
+    }
+    if (FVID2_TIMEOUT_FOREVER == timeout)
+    {
+        semTimeout = SemaphoreP_WAIT_FOREVER;
+    }
+    else if (FVID2_TIMEOUT_NONE == timeout)
+    {
+        semTimeout = SemaphoreP_NO_WAIT;
+    }
+    else
+    {
+        semTimeout = timeout;
+    }
+    if ((NULL != instObj) && (NULL != instObj->commonObjRef->lockSem))
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_pend(instObj->commonObjRef->lockSem, semTimeout);
+    }
+
+    cookie = HwiP_disable();
+    /* Steps 1 to 5 */
+    if (FVID2_SOK == retVal)
+    {
+        /* Check frame list for error and NULL pointer check */
+        retVal = Fvid2_checkFrameList(inProcessList,
+                                      (uint32_t) FVID2_MAX_FRAME_PTR);
+        retVal += Fvid2_checkFrameList(outProcessList,
+                                       (uint32_t) FVID2_MAX_FRAME_PTR);
+
+    }
+    if ((FVID2_SOK == retVal) &&
+        (inProcessList->numFrames != virtContext->createParams.numPipe) &&
+        (outProcessList->numFrames != 1U))
+    {
+        retVal = FVID2_EBADARGS;
+        GT_0trace(DssTrace, GT_ERR,
+            "Number of frames in input (must be equal to number of pipes used) OR "
+            "output (must be equal to 1) frame list does not match !!\r\n");
+    }
+    if (FVID2_SOK == retVal)
+    {
+        qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->freeQ);
+        if (qObj == NULL)
+        {
+            GT_0trace(DssTrace, GT_ERR,
+                      "ALLOC: Q object allocation failed\r\n");
+            retVal = FVID2_EALLOC;
+        }
+        if (FVID2_SOK == retVal)
+        {
+            qObj->virtContext = virtContext;
+            qObj->outFrm      = outProcessList->frames[0U];
+            for (frmCnt = 0 ; frmCnt < inProcessList->numFrames ; frmCnt++)
+            {
+                qObj->inFrm[frmCnt] = inProcessList->frames[frmCnt];
+            }
+            Fvid2Utils_queue(bmObj->reqQ, &qObj->qElem, qObj);
+            virtContext->wbStatus.queueCount++;
+            instObj->status.queueCount++;
+        }
+    }
+    /* Step 6 */
+    if (FVID2_SOK == retVal)
+    {
+        GT_assert(DssTrace, (NULL != instObj->commRegs));
+        for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+        {
+            GT_assert(DssTrace,
+                    (NULL != instObj->pipeRegs[virtContext->pipeId[loopCnt]]));
+        }
+        GT_assert(DssTrace, (NULL != instObj->ovrRegs));
+        GT_assert(DssTrace, (NULL != instObj->wbRegs));
+
+        if (Fvid2Utils_getNumQElem(bmObj->currQ) == 0U)
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->reqQ);
+            GT_assert(DssTrace, (NULL != qObj));
+            for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+            {
+                CSL_dssVidPipeEnable(instObj->pipeRegs[virtContext->pipeId[loopCnt]],
+                                     (uint32_t) FALSE);
+            }
+            CSL_dssWbPipeEnable(instObj->wbRegs, (uint32_t) FALSE);
+
+            /* DCTRL has to be configurred before DISP */
+            retVal += Dss_m2mDrvPrgramDctrl(qObj->virtContext);
+            retVal += Dss_m2mDrvPrgramDisp(qObj->virtContext);
+            retVal += Dss_m2mDrvPrgramWbPipe(qObj->virtContext);
+
+            if (FVID2_SOK == retVal)
+            {
+                /* Queue to CurrQ */
+                Fvid2Utils_queue(bmObj->currQ, &qObj->qElem, qObj);
+
+                for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+                {
+                    CSL_dssVidPipeSetBuffAddr(
+                            instObj->pipeRegs[qObj->inFrm[loopCnt]->chNum],
+                            FVID2_FID_TOP,
+                            qObj->inFrm[loopCnt]->addr[0U],
+                            qObj->inFrm[loopCnt]->addr[1U]);
+                }
+                CSL_dssWbPipeSetBuffAddr(instObj->wbRegs,
+                                         FVID2_FID_TOP,
+                                         qObj->outFrm->addr[0U],
+                                         qObj->outFrm->addr[1U]);
+
+                for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+                {
+                    CSL_dssVidPipeEnable(instObj->pipeRegs[virtContext->pipeId[loopCnt]],
+                                         (uint32_t) TRUE);
+                }
+                CSL_dssWbPipeSetGoBit(instObj->wbRegs);
+                CSL_dssWbPipeEnable(instObj->wbRegs, (uint32_t) TRUE);
+            }
+            else
+            {
+                /* Queue back in case of failure */
+                Fvid2Utils_queue(bmObj->reqQ, &qObj->qElem, qObj);
+                GT_0trace(DssTrace, GT_ERR,
+                          "Programming Failed: DSS Pipe/Disp/WB Pipe\r\n");
+            }
+
+        }
+    }
+    HwiP_restore(cookie);
+
+    if ((NULL != instObj) && (NULL != instObj->commonObjRef->lockSem))
+    {
+        /* Post the instance semaphore */
+        (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mGetProcessedRequest(Fdrv_Handle handle,
+                                   Fvid2_FrameList *inProcessList,
+                                   Fvid2_FrameList *outProcessList,
+                                   uint32_t timeout)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_VirtContext *virtContext= NULL;
+    DssM2MDrv_InstObj *instObj = NULL;
+    uint32_t semTimeout, cookie, loopCnt;
+    DssM2M_DrvQueObj *qObj;
+    DssM2M_DrvBufManObj *bmObj;
+
+    /** Steps
+     *  1. Get a queue object from the doneQ. Assert error if NULL.
+     *  2. Copy frames into inProcessList and outProcessList
+     *  3. Set frames and context to NULL
+     *  4. Move the queue object to freeQ
+     *  5. Increment De-queue Count in the status
+     */
+    if ((NULL == handle) || (NULL == inProcessList) || (NULL == outProcessList))
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    if (FVID2_SOK == retVal)
+    {
+        virtContext = (DssM2MDrv_VirtContext *)handle;
+        instObj     = virtContext->instObj;
+        GT_assert(DssTrace, (NULL != instObj));
+        bmObj       = &instObj->bmObj;
+        GT_assert(DssTrace, (NULL != bmObj));
+
+        if ((instObj->inUse != DSSM2M_DRV_USAGE_STATUS_IN_USE) ||
+            (virtContext->inUse != DSSM2M_DRV_USAGE_STATUS_IN_USE) ||
+            ((virtContext->state == DSSM2M_DRV_STATE_IDLE) ||
+             (virtContext->state == DSSM2M_DRV_STATE_UNINIT)))
+        {
+            retVal = FVID2_EFAIL;
+            GT_0trace(DssTrace, GT_ERR,
+                "Invalid state: Can't submit request to an un-opened instance!!\r\n");
+        }
+    }
+    if (FVID2_TIMEOUT_FOREVER == timeout)
+    {
+        semTimeout = SemaphoreP_WAIT_FOREVER;
+    }
+    else if (FVID2_TIMEOUT_NONE == timeout)
+    {
+        semTimeout = SemaphoreP_NO_WAIT;
+    }
+    else
+    {
+        semTimeout = timeout;
+    }
+    if ((NULL != instObj) && (NULL != instObj->commonObjRef->lockSem))
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_pend(instObj->commonObjRef->lockSem, semTimeout);
+    }
+
+    cookie = HwiP_disable();
+    /* Steps 1 to 5 */
+    if (FVID2_SOK == retVal)
+    {
+        /* init frame list fields */
+        inProcessList->numFrames   = 0U;
+        inProcessList->perListCfg  = NULL;
+        outProcessList->numFrames  = 0U;
+        outProcessList->perListCfg = NULL;
+        /* Only De-queue one frame per call */
+        qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(virtContext->doneQ);
+        if (qObj != NULL)
+        {
+            for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+            {
+                inProcessList->frames[loopCnt] = qObj->inFrm[loopCnt];
+                inProcessList->numFrames++;
+                qObj->inFrm[loopCnt] = NULL;
+            }
+
+            outProcessList->frames[outProcessList->numFrames] = qObj->outFrm;
+            outProcessList->numFrames++;
+            qObj->virtContext = NULL;
+            qObj->outFrm      = NULL;
+            virtContext->wbStatus.dequeueCount++;
+            instObj->status.dequeueCount++;
+            Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj);
+        }
+    }
+
+    if ((retVal == FVID2_SOK) &&
+        (inProcessList->numFrames == 0U) &&
+        (outProcessList->numFrames == 0U))
+    {
+        if ((virtContext->state == DSSM2M_DRV_STATE_CREATED) ||
+            (virtContext->state == DSSM2M_DRV_STATE_STOPPED))
+        {
+            retVal = FVID2_ENO_MORE_BUFFERS;
+        }
+    }
+    HwiP_restore(cookie);
+
+    if ((NULL != instObj) && (NULL != instObj->commonObjRef->lockSem))
+    {
+        /* Post the instance semaphore */
+        (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mControl(Fdrv_Handle handle,
+                       uint32_t cmd,
+                       void *cmdArgs,
+                       void *cmdStatusArgs)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_VirtContext *virtContext;
+    Fvid2_TimeStampParams *tsParams;
+
+    /* Check for NULL pointers */
+    if (handle == NULL)
+    {
+        GT_0trace(DssTrace, GT_ERR, "Invalid argument!!\r\n");
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        virtContext = (DssM2MDrv_VirtContext *) handle;
+        switch (cmd)
+        {
+            case FVID2_START:
+                retVal = Dss_m2mDrvIoctlStart(virtContext);
+            break;
+            case FVID2_STOP:
+                retVal = Dss_m2mDrvIoctlStop(virtContext);
+            break;
+            case IOCTL_DSS_M2M_SET_WB_PIPE_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetWbPipeParams(virtContext,
+                                    (const Dss_WbPipeCfgParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_SET_WB_PIPE_MFLAG_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetmFlagParams(virtContext,
+                                    (const Dss_WbPipeMflagParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_GET_CURRENT_STATUS:
+                retVal = Dss_m2mDrvIoctlGetCurrentStatus(virtContext,
+                                    (Dss_WbStatus *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_SET_WB_PIPE_CSC_COEFF:
+                retVal = Dss_m2mDrvIoctlSetWbPipeCsc(virtContext,
+                                    (const CSL_DssCscCoeff *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_SET_WB_PIPE_DMA_CFG:
+                retVal = Dss_m2mDrvIoctlSetDmaCfg(virtContext,
+                                    (const CSL_DssWbPipeDmaCfg *)cmdArgs);
+            break;
+            case FVID2_REGISTER_TIMESTAMP_FXN:
+                tsParams = (Fvid2_TimeStampParams *)cmdArgs;
+                gDssM2mCommonObj.getTimeStamp = tsParams->timeStampFxn;
+            break;
+            case IOCTL_DSS_M2M_SET_PIPE_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetDssPipeParams(virtContext,
+                                    (const Dss_PipeCfgParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_SET_PIPE_MFLAG_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetPipeMflagParams(virtContext,
+                                    (const Dss_PipeMflagParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_M2M_SET_PIPE_CSC_COEFF:
+                retVal = Dss_m2mDrvIoctlSetPipeCsc(virtContext,
+                                    (const Dss_PipeCscParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_DCTRL_SET_OVERLAY_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetOverlayParams(virtContext,
+                                    (const Dss_DctrlOverlayParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_DCTRL_SET_LAYER_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetLayerParams(virtContext,
+                                (const Dss_DctrlOverlayLayerParams *)cmdArgs);
+            break;
+            case IOCTL_DSS_DCTRL_SET_GLOBAL_DSS_PARAMS:
+                retVal = Dss_m2mDrvIoctlSetGlobalParams(virtContext,
+                                (const Dss_DctrlGlobalDssParams *)cmdArgs);
+            break;
+            default:
+            {
+                GT_0trace(DssTrace, GT_ERR,
+                            "UNSUPPORTED_CMD: IOCTL not supported\r\n");
+                retVal = FVID2_EUNSUPPORTED_CMD;
+            }
+            break;
+        }
+    }
+
+    return retVal;
+}
+/* ========================================================================== */
+/*                       Static Function Definitions                          */
+/* ========================================================================== */
+int32_t Dss_m2mDrvSetWbPipeDmaCfg(DssM2MDrv_InstObj *instObj,
+                                  const CSL_DssWbPipeDmaCfg *dmaCfg)
+{
+    int32_t retVal = FVID2_SOK;
+
+    if (NULL == instObj->wbRegs)
+    {
+        retVal = FVID2_EFAIL;
+    }
+    else
+    {
+        /* Configure HW module */
+        CSL_dssWbPipeSetDmaConfig(instObj->wbRegs, dmaCfg);
+        /* Update programmed configurations in the instance object */
+        Fvid2Utils_memcpy(&instObj->progCfg.wbPipeCfg.dmaCfg,
+                          dmaCfg,
+                          sizeof(CSL_DssWbPipeDmaCfg));
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvCreateInstQueues(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2M_DrvBufManObj *bmObj;
+    uint32_t qCnt = 0U, loopCnt;
+    DssM2M_DrvQueObj *qObj;
+    DssM2MDrv_InstObj *instObj;
+
+    instObj = context->instObj;
+    bmObj = &instObj->bmObj;
+
+    bmObj->freeQ = NULL;
+    bmObj->reqQ = NULL;
+    bmObj->currQ = NULL;
+
+    /* Create Queues */
+    retVal = Fvid2Utils_constructQ(&bmObj->freeLlObj);
+    GT_assert(DssTrace, (retVal == FVID2_SOK));
+    bmObj->freeQ = &bmObj->freeLlObj;
+
+    retVal = Fvid2Utils_constructQ(&bmObj->reqLlObj);
+    GT_assert(DssTrace, (retVal == FVID2_SOK));
+    bmObj->reqQ = &bmObj->reqLlObj;
+
+    retVal = Fvid2Utils_constructQ(&bmObj->curLlObj);
+    GT_assert(DssTrace, (retVal == FVID2_SOK));
+    bmObj->currQ = &bmObj->curLlObj;
+
+    if(FVID2_SOK == retVal)
+    {
+        for (qCnt = 0U ;
+             qCnt < (DSS_DEF_QUEUE_LEN_PER_M2M_DRV_INST * DSSM2M_NUM_VIRTUAL_CONTEXT) ;
+             qCnt++)
+        {
+            qObj              = &bmObj->m2mQObj[qCnt];
+            qObj->virtContext = context;
+            for (loopCnt = 0U ; loopCnt < context->numPipe ; loopCnt++)
+            {
+                qObj->inFrm[loopCnt] = NULL;
+            }
+            qObj->outFrm      = NULL;
+            Fvid2Utils_queue(bmObj->freeQ, &qObj->qElem, qObj);
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvDeleteInstQueues(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2M_DrvBufManObj *bmObj;
+    DssM2M_DrvQueObj *qObj;
+    DssM2MDrv_InstObj *instObj;
+
+    instObj = context->instObj;
+    bmObj = &instObj->bmObj;
+
+    if(NULL != bmObj->freeQ)
+    {
+        /* Free-up all the queued free queue objects */
+        do
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->freeQ);
+        } while (NULL != qObj);
+
+        /* Delete the free Q */
+        Fvid2Utils_destructQ(bmObj->freeQ);
+        bmObj->freeQ = NULL;
+    }
+
+    if(NULL != bmObj->reqQ)
+    {
+        /* Free-up all the queued free queue objects */
+        do
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->reqQ);
+        } while (NULL != qObj);
+
+        /* Delete the free Q */
+        Fvid2Utils_destructQ(bmObj->reqQ);
+        bmObj->reqQ = NULL;
+    }
+
+    if(NULL != bmObj->currQ)
+    {
+        /* Free-up all the queued free queue objects */
+        do
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->currQ);
+        } while (NULL != qObj);
+
+        /* Delete the free Q */
+        Fvid2Utils_destructQ(bmObj->currQ);
+        bmObj->currQ = NULL;
+    }
+
+    return retVal;
+}
+
+static uint32_t Dss_m2mDrvWbPipeCfgChk(const Dss_WbPipeCfgParams *instCfg,
+                                       const Dss_WbPipeCfgParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->pipeCfg.wbMode             != progCfg->pipeCfg.wbMode)             ||
+        (instCfg->pipeCfg.yuvAlign           != progCfg->pipeCfg.yuvAlign)           ||
+        (instCfg->pipeCfg.cscRange           != progCfg->pipeCfg.cscRange)           ||
+        (instCfg->pipeCfg.scEnable           != progCfg->pipeCfg.scEnable)           ||
+        (instCfg->pipeCfg.alphaEnable        != progCfg->pipeCfg.alphaEnable)        ||
+        (instCfg->pipeCfg.inFmt.width        != progCfg->pipeCfg.inFmt.width)        ||
+        (instCfg->pipeCfg.inFmt.height       != progCfg->pipeCfg.inFmt.height)       ||
+        (instCfg->pipeCfg.inFmt.dataFormat   != progCfg->pipeCfg.inFmt.dataFormat)   ||
+        (instCfg->pipeCfg.outFmt.width       != progCfg->pipeCfg.outFmt.width)       ||
+        (instCfg->pipeCfg.outFmt.height      != progCfg->pipeCfg.outFmt.height)      ||
+        (instCfg->pipeCfg.outFmt.pitch       != progCfg->pipeCfg.outFmt.pitch)       ||
+        (instCfg->pipeCfg.outFmt.dataFormat  != progCfg->pipeCfg.outFmt.dataFormat)  ||
+        (instCfg->pipeCfg.outFmt.scanFormat  != progCfg->pipeCfg.outFmt.scanFormat)  ||
+        (instCfg->pipeCfg.outFmt.ccsFormat   != progCfg->pipeCfg.outFmt.ccsFormat)   ||
+        (instCfg->pipeCfg.outFmt.fieldMerged != progCfg->pipeCfg.outFmt.fieldMerged) ||
+        (instCfg->pipeCfg.inPos.startX       != progCfg->pipeCfg.inPos.startX)       ||
+        (instCfg->pipeCfg.inPos.startY       != progCfg->pipeCfg.inPos.startY))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+static uint32_t Dss_m2mDrvWbDmaCfgChk(const CSL_DssWbPipeDmaCfg *instCfg,
+                                      const CSL_DssWbPipeDmaCfg *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->bufLowThreshold  != progCfg->bufLowThreshold)  ||
+        (instCfg->bufHighThreshold != progCfg->bufHighThreshold) ||
+        (instCfg->arbitration      != progCfg->arbitration)      ||
+        (instCfg->frameCaptureRate != progCfg->frameCaptureRate) ||
+        (instCfg->idleSize         != progCfg->idleSize)         ||
+        (instCfg->idleNumber       != progCfg->idleNumber))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+static uint32_t Dss_m2mDrvWbMFlagCfgChk(const Dss_WbPipeMflagParams *instCfg,
+                                        const Dss_WbPipeMflagParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->mFlagCfg.thresholdLow  != progCfg->mFlagCfg.thresholdLow)  ||
+        (instCfg->mFlagCfg.thresholdHigh != progCfg->mFlagCfg.thresholdHigh))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+static uint32_t Dss_m2mDrvWbCscCfgChk(const CSL_DssCscCoeff *instCfg,
+                                      const CSL_DssCscCoeff *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->cscRange     != progCfg->cscRange)    ||
+        (instCfg->c00          != progCfg->c00)         ||
+        (instCfg->c01          != progCfg->c01)         ||
+        (instCfg->c02          != progCfg->c02)         ||
+        (instCfg->c10          != progCfg->c10)         ||
+        (instCfg->c11          != progCfg->c11)         ||
+        (instCfg->c12          != progCfg->c12)         ||
+        (instCfg->c20          != progCfg->c20)         ||
+        (instCfg->c21          != progCfg->c21)         ||
+        (instCfg->c22          != progCfg->c22)         ||
+        (instCfg->preOffset1   != progCfg->preOffset1)  ||
+        (instCfg->preOffset2   != progCfg->preOffset2)  ||
+        (instCfg->preOffset3   != progCfg->preOffset3)  ||
+        (instCfg->postOffset1  != progCfg->postOffset1) ||
+        (instCfg->postOffset2  != progCfg->postOffset2) ||
+        (instCfg->postOffset3  != progCfg->postOffset3))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvPrgramWbPipe(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t copyCfg = (uint32_t) FALSE;
+    DssM2MDrv_InstObj *instObj;
+    DssM2MDrv_WbPipeCfg *instCfg, *progCfg;
+
+    instObj = context->instObj;
+    instCfg = &context->instCfg.wbPipeCfg;
+    progCfg = &instObj->progCfg.wbPipeCfg;
+    GT_assert(DssTrace, (NULL != instObj->wbRegs));
+    /* Re-program WB pipe only if channel/instance configurations
+       are different than programmed */
+    if (FVID2_SOK == retVal)
+    {
+        /* Check write-back pipe configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvWbPipeCfgChk(
+                                        &instCfg->cfgParams,
+                                        &progCfg->cfgParams))
+        {
+            /* Program WB pipeline */
+            if (CSL_PASS != CSL_dssWbPipeSetConfig(instObj->wbRegs,
+                                &instCfg->cfgParams.pipeCfg))
+            {
+                retVal = FVID2_EFAIL;
+            }
+            else
+            {
+                copyCfg = (uint32_t) TRUE;
+            }
+        }
+    }
+    if (FVID2_SOK == retVal)
+    {
+        /* Check write-back pipe DMA configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvWbDmaCfgChk(
+                                        &instCfg->dmaCfg,
+                                        &progCfg->dmaCfg))
+        {
+            /* Program WB pipeline */
+            CSL_dssWbPipeSetDmaConfig(instObj->wbRegs,
+                                      &instCfg->dmaCfg);
+            copyCfg = (uint32_t) TRUE;
+        }
+    }
+    if (FVID2_SOK == retVal)
+    {
+        /* Check write-back pipe MFlag configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvWbMFlagCfgChk(
+                                    &instCfg->mFlagParams,
+                                    &progCfg->mFlagParams))
+        {
+            /* Program WB pipeline */
+            CSL_dssWbPipeSetMflagConfig(instObj->wbRegs,
+                                        &instCfg->mFlagParams.mFlagCfg);
+            copyCfg = (uint32_t) TRUE;
+        }
+    }
+    if (FVID2_SOK == retVal)
+    {
+        /* Check write-back pipe CSC configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvWbCscCfgChk(
+                                    &instCfg->cscCoeff,
+                                    &progCfg->cscCoeff))
+        {
+            /* Program WB pipeline */
+            CSL_dssWbPipeSetCSCCoeff(instObj->wbRegs,
+                                     &instCfg->cscCoeff);
+            copyCfg = (uint32_t) TRUE;
+        }
+    }
+
+    if ((FVID2_SOK == retVal) && (((uint32_t) TRUE) == copyCfg))
+    {
+        /* Update instance configurations */
+        Fvid2Utils_memcpy(progCfg, instCfg, sizeof(DssM2MDrv_WbPipeCfg));
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlStart(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    DssM2MDrv_InstObj *instObj;
+
+    /* Currently this API only does maintaining SW Driver states */
+    instObj = context->instObj;
+    GT_assert(DssTrace, (context != NULL));
+    GT_assert(DssTrace, (instObj != NULL));
+
+    if (NULL != instObj->commonObjRef->lockSem)
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_pend(instObj->commonObjRef->lockSem,
+                               SemaphoreP_WAIT_FOREVER);
+    }
+
+    context->state = DSSM2M_DRV_STATE_RUNNING;
+
+    if (NULL != instObj->commonObjRef->lockSem)
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlStop(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t numReqQNum, loopCnt;
+    DssM2MDrv_InstObj *instObj;
+    DssM2M_DrvQueObj *qObj = NULL;
+    DssM2M_DrvBufManObj *bmObj = NULL;
+
+    /* Currently this API only does maintaining SW Driver states */
+    instObj = context->instObj;
+    GT_assert(DssTrace, (context != NULL));
+    GT_assert(DssTrace, (instObj != NULL));
+
+    if (NULL != instObj->commonObjRef->lockSem)
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_pend(instObj->commonObjRef->lockSem,
+                               SemaphoreP_WAIT_FOREVER);
+    }
+
+    context->state = DSSM2M_DRV_STATE_STOPPED;
+
+    /* When driver is stopped, put buffers from reqQ to doneQ for
+       current virtual Context. This has to be done only for doneQ and
+       not for reqQ as existing frame will be processed completely */
+    if ((FVID2_SOK == retVal) &&
+        (context->state == DSSM2M_DRV_STATE_STOPPED))
+    {
+        bmObj = &instObj->bmObj;
+        GT_assert(DssTrace, (NULL != bmObj));
+        numReqQNum = Fvid2Utils_getNumQElem(bmObj->reqQ);
+        for (loopCnt = 0U ; loopCnt < numReqQNum ; loopCnt++)
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->reqQ);
+            GT_assert(DssTrace, (NULL != qObj));
+            if (qObj->virtContext == context)
+            {
+                /* Move to doneQ, if it matches with currently closed context */
+                Fvid2Utils_queue(context->doneQ, &qObj->qElem, qObj);
+            }
+            else
+            {
+                /* Queue back to reqQ */
+                Fvid2Utils_queue(bmObj->reqQ, &qObj->qElem, qObj);
+            }
+        }
+    }
+
+    if (NULL != instObj->commonObjRef->lockSem)
+    {
+        /* Take the instance semaphore */
+        (void) SemaphoreP_post(instObj->commonObjRef->lockSem);
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlSetWbPipeParams(DssM2MDrv_VirtContext *context,
+                                       const Dss_WbPipeCfgParams *pipeCfg)
+{
+    int32_t retVal = FVID2_SOK, retVal2 = CSL_PASS;
+
+    /* check for parameters */
+    if (NULL == pipeCfg)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        if (pipeCfg->pipeCfg.wbMode != CSL_DSS_WB_PIPE_MODE_M2M)
+        {
+            /* Only M2M mode is supported in this driver */
+            retVal = FVID2_EBADARGS;
+            GT_0trace(DssTrace, GT_ERR, "Only M2M mode supported!!\r\n");
+        }
+
+        if (FVID2_SOK == retVal)
+        {
+            retVal2 = CSL_dssWbPipeCheckFmt(pipeCfg->pipeCfg.outFmt.dataFormat);
+            if (CSL_PASS != retVal2)
+            {
+                GT_0trace(DssTrace, GT_ERR, "Given destination Fvid2_format not supported!!\r\n");
+                retVal = FVID2_EBADARGS;
+            }
+        }
+
+        if (FVID2_SOK == retVal)
+        {
+            retVal = Dss_m2mValidateM2mPipeParams(pipeCfg);
+            if (FVID2_SOK != retVal)
+            {
+                GT_0trace(DssTrace, GT_ERR, "Invalid arguments have been passed!!\r\n");
+            }
+        }
+
+        if (FVID2_SOK == retVal)
+        {
+            /* Only copy provided configurations to channel/virtual context object.
+               This will be programmed to HW module when buffers are submitted
+               through 'Fvid2_processRequest()' */
+               Fvid2Utils_memcpy(&context->instCfg.wbPipeCfg.cfgParams,
+                                 pipeCfg,
+                                 sizeof(Dss_WbPipeCfgParams));
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlSetmFlagParams(DssM2MDrv_VirtContext *context,
+                                      const Dss_WbPipeMflagParams *mFlagParams)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == mFlagParams)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* Only copy provided configurations to channel/virtual context object.
+           This will be programmed to HW module when buffers are submitted
+           through 'Fvid2_processRequest()' */
+           Fvid2Utils_memcpy(&context->instCfg.wbPipeCfg.mFlagParams,
+                             mFlagParams,
+                             sizeof(Dss_WbPipeMflagParams));
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlGetCurrentStatus(DssM2MDrv_VirtContext *context,
+                                               Dss_WbStatus *status)
+{
+    int32_t retVal = FVID2_SOK;
+
+
+    /* check for parameters */
+    if (NULL == status)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* Only copy provided configurations to channel/virtual context object.
+           This will be programmed to HW module when buffers are submitted
+           through 'Fvid2_processRequest()' */
+        Fvid2Utils_memcpy(status,
+                          &context->wbStatus,
+                          sizeof(Dss_WbStatus));
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlSetWbPipeCsc(DssM2MDrv_VirtContext *context,
+                                    const CSL_DssCscCoeff *csc)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == csc)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* Only copy provided configurations to channel/virtual context object.
+           This will be programmed to HW module when buffers are submitted
+           through 'Fvid2_processRequest()' */
+        Fvid2Utils_memcpy(&context->instCfg.wbPipeCfg.cscCoeff,
+                          csc,
+                          sizeof(CSL_DssCscCoeff));
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvIoctlSetDmaCfg(DssM2MDrv_VirtContext *context,
+                                        const CSL_DssWbPipeDmaCfg *dmaCfg)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == dmaCfg)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* upgrade configurations into context object and re-program HW module
+           on buffer submission */
+        Fvid2Utils_memcpy(&context->instCfg.wbPipeCfg.dmaCfg,
+                          dmaCfg,
+                          sizeof(CSL_DssWbPipeDmaCfg));
+    }
+
+    return retVal;
+}
+
+static void Dss_wbPipeCbFxn(const uint32_t *event,
+                            uint32_t numEvents,
+                            void *arg)
+{
+    uint32_t  loopCnt, currEvent, wbPipeId = 0U;
+    Dss_EvtMgrClientInfo *pClientObj = (Dss_EvtMgrClientInfo *)arg;
+    uint32_t eventGroup = pClientObj->eventGroup;
+    DssM2MDrv_InstObj *instObj;
+
+    Dss_convEventGrouptoModule(eventGroup, &wbPipeId);
+    GT_assert(DssTrace, (CSL_DSS_MODULE_INVALID != wbPipeId));
+    instObj = &(gDssM2mCommonObj.instObj[wbPipeId]);
+    for(loopCnt=0U; loopCnt<numEvents; loopCnt++)
+    {
+        currEvent = event[loopCnt];
+        if(DSS_WB_PIPE_EVENT_BUFF_FRAME_DONE == currEvent)
+        {
+           /* Application CB will be issued in the following function */
+           Dss_wbPipeDmaCompletionCbFxn(instObj);
+        }
+        else if(DSS_WB_PIPE_EVENT_BUFF_OVERFLOW == currEvent)
+        {
+           instObj->status.underflowCount++;
+        }
+        else
+        {
+            GT_assert(DssTrace, FALSE);
+        }
+    }
+
+    return;
+}
+
+static void Dss_wbPipeDmaCompletionCbFxn(DssM2MDrv_InstObj *instObj)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t loopCnt;
+    DssM2MDrv_VirtContext *virtContext= NULL;
+    DssM2M_DrvQueObj *qObj = NULL;
+    DssM2M_DrvBufManObj *bmObj = NULL;
+
+    GT_assert(DssTrace, (NULL != instObj));
+    bmObj = &instObj->bmObj;
+    GT_assert(DssTrace, (NULL != bmObj));
+
+    /** Steps
+     *  1. Get a queue object from the currQ. Assert error if NULL.
+     *  2. Move the queue object to doneQ
+     *  3. Increment wb frame count Count in the status
+     *  4. If number of elements in currQ < 1, then do following
+     *     a. Get a queue object from the reqQ. Assert error if NULL
+     *     b. Disable DSS and WB pipeline
+     *     c. Re-program DSS pipeline, Overlay and WB Pipeline if needed
+     *     d. Set buffer addresses in the WB & DSS Pipeline
+     *     e. Enable DSS and WB pipeline
+     *     f. Move the queue object to currQ
+     */
+    /* Steps 1 to 3 */
+    if (FVID2_SOK == retVal)
+    {
+        qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->currQ);
+        GT_assert(DssTrace, (NULL != qObj));
+        virtContext = qObj->virtContext;
+        GT_assert(DssTrace, (NULL != virtContext));
+        Fvid2Utils_queue(virtContext->doneQ, &qObj->qElem, qObj);
+        virtContext->wbStatus.wbFrmCount++;
+        instObj->status.wbFrmCount++;
+        /* Issue application CB */
+        if(virtContext->fdmCbParams.fdmCbFxn != NULL)
+        {
+            virtContext->fdmCbParams.fdmCbFxn(virtContext->fdmCbParams.fdmData);
+        }
+    }
+
+    /* Step 6 */
+    if (FVID2_SOK == retVal)
+    {
+        GT_assert(DssTrace, (NULL != instObj->commRegs));
+        for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+        {
+            GT_assert(DssTrace,
+                    (NULL != instObj->pipeRegs[virtContext->pipeId[loopCnt]]));
+        }
+        GT_assert(DssTrace, (NULL != instObj->ovrRegs));
+        GT_assert(DssTrace, (NULL != instObj->wbRegs));
+
+        /* Only program module if a frame is submitted */
+        if ((Fvid2Utils_getNumQElem(bmObj->currQ) == 0U) &&
+            (Fvid2Utils_getNumQElem(bmObj->reqQ) > 0U))
+        {
+            qObj = (DssM2M_DrvQueObj *) Fvid2Utils_dequeue(bmObj->reqQ);
+            GT_assert(DssTrace, (NULL != qObj));
+            for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+            {
+                CSL_dssVidPipeEnable(instObj->pipeRegs[virtContext->pipeId[loopCnt]],
+                                     (uint32_t) FALSE);
+            }
+            CSL_dssWbPipeEnable(instObj->wbRegs, (uint32_t) FALSE);
+
+            /* DCTRL has to be configurred before DISP */
+            retVal += Dss_m2mDrvPrgramDctrl(qObj->virtContext);
+            retVal += Dss_m2mDrvPrgramDisp(qObj->virtContext);
+            retVal += Dss_m2mDrvPrgramWbPipe(qObj->virtContext);
+
+            if (FVID2_SOK == retVal)
+            {
+                /* Queue to CurrQ */
+                Fvid2Utils_queue(bmObj->currQ, &qObj->qElem, qObj);
+
+                for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+                {
+                    CSL_dssVidPipeSetBuffAddr(
+                            instObj->pipeRegs[qObj->inFrm[loopCnt]->chNum],
+                            FVID2_FID_TOP,
+                            qObj->inFrm[loopCnt]->addr[0U],
+                            qObj->inFrm[loopCnt]->addr[1U]);
+                }
+                CSL_dssWbPipeSetBuffAddr(instObj->wbRegs,
+                                         FVID2_FID_TOP,
+                                         qObj->outFrm->addr[0U],
+                                         qObj->outFrm->addr[1U]);
+
+                for (loopCnt = 0U ; loopCnt < virtContext->numPipe ; loopCnt++)
+                {
+                    CSL_dssVidPipeEnable(instObj->pipeRegs[virtContext->pipeId[loopCnt]],
+                                         (uint32_t) TRUE);
+                }
+                CSL_dssWbPipeSetGoBit(instObj->wbRegs);
+                CSL_dssWbPipeEnable(instObj->wbRegs, (uint32_t) TRUE);
+            }
+            else
+            {
+                /* Queue back in case of failure */
+                Fvid2Utils_queue(bmObj->reqQ, &qObj->qElem, qObj);
+                GT_0trace(DssTrace, GT_ERR,
+                          "Programming Failed: DSS Pipe/Disp/WB Pipe\r\n");
+            }
+
+        }
+    }
+
+    GT_assert(DssTrace, (FVID2_SOK == retVal));
+
+    return;
+}
+
+static int32_t Dss_m2mValidateM2mPipeParams(const Dss_WbPipeCfgParams *wbPipeParams)
+{
+    int32_t retVal = FVID2_SOK, planeIdx, numFields, fieldIdx;
+    uint32_t pitchValArr[FVID2_MAX_PLANES_PER_FIELD];
+    CSL_DssWbPipeCfg wbPipeCfg;
+
+    wbPipeCfg = wbPipeParams->pipeCfg;
+    if (wbPipeCfg.inFmt.dataFormat != FVID2_DF_ARGB48_12121212)
+    {
+        GT_0trace(DssTrace, GT_ERR, "Input format can only be ARGB12121212!!\r\n");
+        retVal = FVID2_EBADARGS;
+    }
+
+    if( ((wbPipeCfg.inFmt.width != wbPipeCfg.outFmt.width) ||
+         (wbPipeCfg.inFmt.height != wbPipeCfg.outFmt.height)) &&
+         wbPipeCfg.scEnable != TRUE)
+    {
+        GT_0trace(DssTrace, GT_ERR, "Scaling must be enabled if input and output widths/heights are different!!\r\n");
+        retVal = FVID2_EBADARGS;
+    }
+
+    if (wbPipeCfg.outFmt.dataFormat == FVID2_DF_YUV420SP_UV)
+    {
+        if ((wbPipeCfg.inFmt.width > (2*wbPipeCfg.outFmt.width)) ||
+            (wbPipeCfg.inFmt.height > (2*wbPipeCfg.outFmt.height)))
+        {
+            GT_0trace(DssTrace, GT_ERR, "For YUV420 output, can not downscale more than a factor of 2!!\r\n");
+            retVal = FVID2_EBADARGS;
+        }
+    }
+
+    /* The the pitch factors in bits per pixel. */
+    retVal = CSL_dssWbGetPitchFactors(wbPipeCfg.outFmt.dataFormat, pitchValArr);
+
+    if (retVal == CSL_PASS)
+    {
+        if (wbPipeCfg.outFmt.scanFormat == FVID2_SF_INTERLACED)
+        {
+            numFields = 2;
+        }
+        else
+        {
+            numFields = 1;
+        }
+        for(fieldIdx = 0U ; fieldIdx < numFields; fieldIdx++)
+        {
+            for(planeIdx = 0U ; planeIdx < FVID2_MAX_PLANES_PER_FIELD; planeIdx++)
+            {
+                /* Application programmes pitch in terms of Byte, so divide referance pitch factor by 8. */
+                /* Application can allocate buffer in a way that the programmed pitch is greater than the minimum required pitch. */
+                if (wbPipeCfg.outFmt.pitch[fieldIdx*FVID2_MAX_PLANES_PER_FIELD + planeIdx] < (wbPipeCfg.outFmt.width*pitchValArr[planeIdx])/8)
+                {
+                    retVal = FVID2_EBADARGS;
+                    GT_0trace(DssTrace, GT_ERR, "Programmed pitch is too little for given data format parameters!!\r\n");
+                    break;
+                }
+            }
+        }
+    }
+
+    return retVal;
+}
\ No newline at end of file
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDctrl.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDctrl.c
new file mode 100755
index 00000000..f84a1c7e
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDctrl.c
@@ -0,0 +1,379 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2mDctrl.c
+ *
+ *  \brief File containing the DSS M2M driver DSS_DCTRL APIs.
+ *
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <ti/drv/dss/dss.h>
+#include <ti/drv/dss/src/drv/common/dss_evtMgr.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispDrv.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispPriv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlDrv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlPriv.h>
+#include <ti/drv/dss/src/drv/m2m/dss_m2mDrv.h>
+#include <dss_soc_priv.h>
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDctrlOvlCfgChk(const Dss_DctrlOverlayParams *instCfg,
+                                  const Dss_DctrlOverlayParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDctrlOvlLayerCfgChk(const Dss_DctrlOverlayLayerParams *instCfg,
+                                       const Dss_DctrlOverlayLayerParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDctrlGlobalCfgChk(const Dss_DctrlGlobalDssParams *instCfg,
+                                     const Dss_DctrlGlobalDssParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDctrlPathCfgChk(const Dss_DctrlPathInfo * instCfg,
+                                   const Dss_DctrlPathInfo * progCfg);
+
+int32_t Dss_m2mDrvPrgramDctrl(DssM2MDrv_VirtContext *context);
+
+/*
+ * Display IOCTLs
+ */
+int32_t Dss_m2mDrvIoctlSetOverlayParams(DssM2MDrv_VirtContext *context,
+                                        const Dss_DctrlOverlayParams *ovlParams);
+
+int32_t Dss_m2mDrvIoctlSetLayerParams(DssM2MDrv_VirtContext *context,
+                        const Dss_DctrlOverlayLayerParams *ovlLayerParams);
+
+int32_t Dss_m2mDrvIoctlSetGlobalParams(DssM2MDrv_VirtContext *context,
+                               const Dss_DctrlGlobalDssParams *globalParams);
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+extern DssM2MDrv_CommonObj gDssM2mCommonObj;
+
+/* ========================================================================== */
+/*                          Function Definitions                              */
+/* ========================================================================== */
+uint32_t Dss_m2mDrvDctrlOvlCfgChk(const Dss_DctrlOverlayParams *instCfg,
+                                         const Dss_DctrlOverlayParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->overlayId                   != progCfg->overlayId)                   ||
+        (instCfg->colorbarEnable              != progCfg->colorbarEnable)              ||
+        (instCfg->colorbarEnable              != FALSE)                                ||
+        (instCfg->overlayCfg.colorKeyEnable   != progCfg->overlayCfg.colorKeyEnable)   ||
+        (instCfg->overlayCfg.colorKeySel      != progCfg->overlayCfg.colorKeySel)      ||
+        (instCfg->overlayCfg.transColorKeyMin != progCfg->overlayCfg.transColorKeyMin) ||
+        (instCfg->overlayCfg.transColorKeyMax != progCfg->overlayCfg.transColorKeyMax) ||
+        (instCfg->overlayCfg.backGroundColor  != progCfg->overlayCfg.backGroundColor))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDctrlOvlLayerCfgChk(const Dss_DctrlOverlayLayerParams *instCfg,
+                                       const Dss_DctrlOverlayLayerParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+    uint32_t loopCnt = 0U;
+
+    if ((instCfg->overlayId  != progCfg->overlayId))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+    else
+    {
+        for (loopCnt = 0U ; loopCnt < CSL_DSS_VID_PIPE_ID_MAX ; loopCnt++)
+        {
+            if (instCfg->pipeLayerNum[loopCnt] != progCfg->pipeLayerNum[loopCnt])
+            {
+                break;
+            }
+        }
+        if (loopCnt < CSL_DSS_VID_PIPE_ID_MAX)
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDctrlGlobalCfgChk(const Dss_DctrlGlobalDssParams *instCfg,
+                                     const Dss_DctrlGlobalDssParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->globalMflagCfg.globalMflagStart  != progCfg->globalMflagCfg.globalMflagStart)  ||
+        (instCfg->globalMflagCfg.globalMflagCtrl   != progCfg->globalMflagCfg.globalMflagCtrl)   ||
+        (instCfg->cbaCfg.priHigh                   != progCfg->cbaCfg.priHigh)                   ||
+        (instCfg->cbaCfg.priLow                    != progCfg->cbaCfg.priLow))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDctrlPathCfgChk(const Dss_DctrlPathInfo * instCfg,
+                                   const Dss_DctrlPathInfo * progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+    uint32_t loopCnt = 0U;
+
+    if ((instCfg->numEdges  != progCfg->numEdges))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+    else
+    {
+        for (loopCnt = 0U ; loopCnt < DSS_DCTRL_MAX_EDGES ; loopCnt++)
+        {
+            if ((instCfg->edgeInfo[loopCnt].startNode !=
+                                        progCfg->edgeInfo[loopCnt].startNode) ||
+               (instCfg->edgeInfo[loopCnt].endNode   !=
+                                        progCfg->edgeInfo[loopCnt].endNode))
+            {
+                break;
+            }
+        }
+        if (loopCnt < DSS_DCTRL_MAX_EDGES)
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvPrgramDctrl(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t copyCfg = (uint32_t) FALSE;
+    uint32_t loopCnt = 0U;
+    DssM2MDrv_InstObj *instObj;
+    DssM2MDrv_dctrlCfg *instCfg, *progCfg;
+    CSL_DssOverlayLayerCfg layerCfg;
+
+    instObj = context->instObj;
+    instCfg = &context->instCfg.dctrlCfg;
+    progCfg = &instObj->progCfg.dctrlCfg;
+    GT_assert(DssTrace, (NULL != instObj->ovrRegs));
+
+    /* Re-program DCTRL only if channel/instance configurations
+       are different than programmed */
+    if (FVID2_SOK == retVal)
+    {
+        /* Check DCTRL Overlay configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvDctrlOvlCfgChk(&instCfg->ovlParams,
+                                                           &progCfg->ovlParams))
+        {
+            if ((CSL_DSS_OVERLAY_ID_MAX <= instCfg->ovlParams.overlayId) ||
+                (instCfg->ovlParams.overlayId != instObj->overlayId))
+            {
+                GT_0trace(DssTrace, GT_ERR, "Invalid argument: Overlay ID\r\n");
+                retVal = FVID2_EBADARGS;
+            }
+            if (FVID2_SOK == retVal)
+            {
+                /* Always Disable Color-bar */
+                CSL_dssOverlayColorBarEnable(instObj->ovrRegs, FALSE);
+                CSL_dssOverlaySetConfig(instObj->ovrRegs,
+                                        &instCfg->ovlParams.overlayCfg);
+                copyCfg = (uint32_t) TRUE;
+            }
+        }
+    }
+    if (FVID2_SOK == retVal)
+    {
+        /* Check DCTRL Overlay Layer configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvDctrlOvlLayerCfgChk(&instCfg->ovlLayerParams,
+                                                                &progCfg->ovlLayerParams))
+        {
+            if ((CSL_DSS_OVERLAY_ID_MAX <= instCfg->ovlLayerParams.overlayId) ||
+                (instCfg->ovlLayerParams.overlayId != instObj->overlayId))
+            {
+                GT_0trace(DssTrace, GT_ERR, "Invalid argument: Overlay ID(Layer)\r\n");
+                retVal = FVID2_EBADARGS;
+            }
+            if (FVID2_SOK == retVal)
+            {
+                /* Initialize layer configuration */
+                CSL_dssOverlayLayerCfgInit(&layerCfg);
+                /* Call CSL APIs */
+                for(loopCnt = 0U ; loopCnt < CSL_DSS_VID_PIPE_ID_MAX ; loopCnt++)
+                {
+                    if(CSL_DSS_OVERLAY_LAYER_INVALID != instCfg->ovlLayerParams.pipeLayerNum[loopCnt])
+                    {
+                        layerCfg.layerEnable = TRUE;
+                        layerCfg.layerNum = instCfg->ovlLayerParams.pipeLayerNum[loopCnt];
+                        layerCfg.inputPipe = loopCnt;
+                        CSL_dssOverlaySetLayerConfig(
+                                            instObj->ovrRegs,
+                                            (const CSL_DssOverlayLayerCfg *) &layerCfg);
+                    }
+                }
+                copyCfg = (uint32_t) TRUE;
+            }
+        }
+    }
+    if (FVID2_SOK == retVal)
+    {
+        /* Check DCTRL Global configuration */
+        if (((uint32_t) FALSE) == Dss_m2mDrvDctrlGlobalCfgChk(&instCfg->globalParams,
+                                                              &progCfg->globalParams))
+        {
+            CSL_dssSetGlobalMflagConfig(instObj->commRegs,
+                                &instCfg->globalParams.globalMflagCfg);
+            CSL_dssSetCbaConfig(instObj->commRegs,
+                                &instCfg->globalParams.cbaCfg);
+            copyCfg = (uint32_t) TRUE;
+        }
+    }
+    if ((FVID2_SOK == retVal) && (((uint32_t) TRUE) == copyCfg))
+    {
+        /* Update instance configurations */
+        Fvid2Utils_memcpy(progCfg, instCfg, sizeof(DssM2MDrv_dctrlCfg));
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetOverlayParams(DssM2MDrv_VirtContext *context,
+                                        const Dss_DctrlOverlayParams *ovlParams)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == ovlParams)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        if ((ovlParams->overlayId >= CSL_DSS_OVERLAY_ID_MAX) ||
+            (ovlParams->overlayId != context->instObj->overlayId))
+        {
+            retVal = FVID2_EBADARGS;
+            GT_0trace(DssTrace, GT_ERR, "Invalid argument: Overlay ID\r\n");
+        }
+        else
+        {
+            /* upgrade configurations into context object and re-program HW module
+               on buffer submission */
+            Fvid2Utils_memcpy(&context->instCfg.dctrlCfg.ovlParams,
+                              ovlParams,
+                              sizeof(Dss_DctrlOverlayParams));
+        }
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetLayerParams(DssM2MDrv_VirtContext *context,
+                            const Dss_DctrlOverlayLayerParams *ovlLayerParams)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == ovlLayerParams)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        if ((ovlLayerParams->overlayId >= CSL_DSS_OVERLAY_ID_MAX) ||
+            (ovlLayerParams->overlayId != context->instObj->overlayId))
+        {
+            retVal = FVID2_EBADARGS;
+            GT_0trace(DssTrace, GT_ERR, "Invalid argument: Overlay ID\r\n");
+        }
+        else
+        {
+            /* upgrade configurations into context object and re-program HW module
+               on buffer submission */
+            Fvid2Utils_memcpy(&context->instCfg.dctrlCfg.ovlLayerParams,
+                              ovlLayerParams,
+                              sizeof(Dss_DctrlOverlayLayerParams));
+        }
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetGlobalParams(DssM2MDrv_VirtContext *context,
+                               const Dss_DctrlGlobalDssParams *globalParams)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == globalParams)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* upgrade configurations into context object and re-program HW module
+           on buffer submission */
+        Fvid2Utils_memcpy(&context->instCfg.dctrlCfg.globalParams,
+                          globalParams,
+                          sizeof(Dss_DctrlGlobalDssParams));
+    }
+
+    return retVal;
+}
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDisp.c b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDisp.c
new file mode 100755
index 00000000..69e29665
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDisp.c
@@ -0,0 +1,575 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2022
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2mDisp.c
+ *
+ *  \brief File containing the DSS M2M driver DSS_DISP APIs.
+ *
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <ti/drv/dss/dss.h>
+#include <ti/drv/dss/src/drv/common/dss_evtMgr.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispDrv.h>
+#include <ti/drv/dss/src/drv/disp/dss_dispPriv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlDrv.h>
+#include <ti/drv/dss/src/drv/dctrl/dss_dctrlPriv.h>
+#include <ti/drv/dss/src/drv/m2m/dss_m2mDrv.h>
+#include <dss_soc_priv.h>
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDispPipeCfgChk(const Dss_DispParams *instCfg,
+                                  const Dss_DispParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDispMFlagCfgChk(const Dss_DispPipeMflagParams *instCfg,
+                                   const Dss_DispPipeMflagParams *progCfg);
+
+/* Returns TRUE if instance and channel/context configurations matches,
+   returns FALSE otherwise */
+uint32_t Dss_m2mDrvDispCscCfgChk(const CSL_DssCscCoeff *instCfg,
+                                 const CSL_DssCscCoeff *progCfg);
+
+int32_t Dss_m2mDrvPrgramDisp(DssM2MDrv_VirtContext *context);
+
+/*
+ * Display IOCTLs
+ */
+static int32_t Dss_m2mDrvValidateDispParams(DssM2MDrv_InstObj *instObj,
+                                            const Dss_PipeCfgParams *pipeCfg);
+
+int32_t Dss_m2mDrvIoctlSetDssPipeParams(DssM2MDrv_VirtContext *context,
+                                        const Dss_PipeCfgParams *pipeCfg);
+
+int32_t Dss_m2mDrvIoctlSetPipeMflagParams(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeMflagParams *mFlagParams);
+
+int32_t Dss_m2mDrvIoctlSetPipeCsc(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeCscParams *csc);
+
+/* Internal functions to check parameters. */
+static int32_t Dss_m2mDrvDispCheckFieldMerge(const Fvid2_Format *instCfg, const Fvid2_Format *progCfg, uint32_t scanFmt);
+
+static int32_t Dss_m2mDrvDispCheckPitch(const Fvid2_Format *instCfg, const Fvid2_Format *progCfg, uint32_t scanFmt);
+
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+
+
+/* ========================================================================== */
+/*                          Function Definitions                              */
+/* ========================================================================== */
+int32_t Dss_m2mDrvDispCheckPitch(const Fvid2_Format *instCfg, const Fvid2_Format *progCfg, uint32_t scanFmt)
+{
+    uint32_t numFields, fieldIdx, planeIdx;
+    int32_t retVal = FVID2_SOK;
+
+    if (scanFmt == FVID2_SF_INTERLACED)
+    {
+        numFields = 2;
+    }
+    else
+    {
+        numFields = 1;
+    }
+    for(fieldIdx = 0U ; fieldIdx < numFields; fieldIdx++)
+    {
+        for(planeIdx = 0U ; planeIdx < FVID2_MAX_PLANES_PER_FIELD; planeIdx++)
+        {
+            if (instCfg->pitch[fieldIdx*FVID2_MAX_PLANES_PER_FIELD + planeIdx] != progCfg->pitch[fieldIdx*FVID2_MAX_PLANES_PER_FIELD + planeIdx])
+            {
+                retVal = FVID2_EINVALID_PARAMS;
+                break;
+            }
+        }
+    }
+    return retVal;
+}
+
+int32_t Dss_m2mDrvDispCheckFieldMerge(const Fvid2_Format *instCfg, const Fvid2_Format *progCfg, uint32_t scanFmt)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t planeIdx;
+
+    if (scanFmt == FVID2_SF_INTERLACED)
+    {
+        for (planeIdx=0; planeIdx<FVID2_MAX_PLANES_PER_FIELD; planeIdx++)
+        {
+            if(instCfg->fieldMerged[planeIdx] != progCfg->fieldMerged[planeIdx])
+            {
+                retVal = FVID2_EINVALID_PARAMS;
+                break;
+            }
+        }
+    }
+    else
+    {
+        /* Field merged is not used for Progressive scan format. */
+    }
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDispPipeCfgChk(const Dss_DispParams *instCfg,
+                                  const Dss_DispParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+    uint32_t loopCnt = 0U, scanFmt;
+
+    scanFmt = instCfg->pipeCfg.inFmt.scanFormat;
+    /* check for Pipe configurations */
+    if ((instCfg->pipeCfg.pipeType          != progCfg->pipeCfg.pipeType)                                           ||
+        (instCfg->pipeCfg.pixelInc          != progCfg->pipeCfg.pixelInc)                                           ||
+        (instCfg->pipeCfg.yuvAlign          != progCfg->pipeCfg.yuvAlign)                                           ||
+        (instCfg->pipeCfg.outWidth          != progCfg->pipeCfg.outWidth)                                           ||
+        (instCfg->pipeCfg.outHeight         != progCfg->pipeCfg.outHeight)                                          ||
+        (instCfg->pipeCfg.scEnable          != progCfg->pipeCfg.scEnable)                                           ||
+        (instCfg->pipeCfg.cscRange          != progCfg->pipeCfg.cscRange)                                           ||
+        (instCfg->pipeCfg.flipType          != progCfg->pipeCfg.flipType)                                           ||
+        (instCfg->pipeCfg.nibbleModeEnable  != progCfg->pipeCfg.nibbleModeEnable)                                   ||
+        (instCfg->pipeCfg.gammaEnable       != progCfg->pipeCfg.gammaEnable)                                        ||
+        (instCfg->pipeCfg.inFmt.width       != progCfg->pipeCfg.inFmt.width)                                        ||
+        (instCfg->pipeCfg.inFmt.height      != progCfg->pipeCfg.inFmt.height)                                       ||
+        (Dss_m2mDrvDispCheckPitch(&(instCfg->pipeCfg.inFmt), &(progCfg->pipeCfg.inFmt), scanFmt) != FVID2_SOK)      ||
+        (instCfg->pipeCfg.inFmt.dataFormat  != progCfg->pipeCfg.inFmt.dataFormat)                                   ||
+        (instCfg->pipeCfg.inFmt.scanFormat  != progCfg->pipeCfg.inFmt.scanFormat)                                   ||
+        (instCfg->pipeCfg.inFmt.ccsFormat   != progCfg->pipeCfg.inFmt.ccsFormat)                                    ||
+        (Dss_m2mDrvDispCheckFieldMerge(&(instCfg->pipeCfg.inFmt), &(progCfg->pipeCfg.inFmt), scanFmt) != FVID2_SOK))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+    else
+    {
+        for (loopCnt = 0U ; loopCnt < CSL_DSS_NUM_LUT_ENTRIES ; loopCnt++)
+        {
+            if (instCfg->pipeCfg.clutData[loopCnt] !=
+                progCfg->pipeCfg.clutData[loopCnt])
+            {
+                break;
+            }
+        }
+        if (loopCnt < CSL_DSS_NUM_LUT_ENTRIES)
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+    /* check for DMA configurations */
+    if (retVal == ((uint32_t) TRUE))
+    {
+        if ((instCfg->dmaCfg.bufPreloadControl  != progCfg->dmaCfg.bufPreloadControl)  ||
+            (instCfg->dmaCfg.preloadVal         != progCfg->dmaCfg.preloadVal)         ||
+            (instCfg->dmaCfg.bufLowThreshold    != progCfg->dmaCfg.bufLowThreshold)    ||
+            (instCfg->dmaCfg.bufHighThreshold   != progCfg->dmaCfg.bufHighThreshold)   ||
+            (instCfg->dmaCfg.selfRefreshControl != progCfg->dmaCfg.selfRefreshControl) ||
+            (instCfg->dmaCfg.selfRefreshEnable  != progCfg->dmaCfg.selfRefreshEnable)  ||
+            (instCfg->dmaCfg.arbitration        != progCfg->dmaCfg.arbitration))
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+    /* check for Alpha configurations */
+    if (retVal == ((uint32_t) TRUE))
+    {
+        if ((instCfg->alphaCfg.globalAlpha      != progCfg->alphaCfg.globalAlpha)  ||
+            (instCfg->alphaCfg.preMultiplyAlpha != progCfg->alphaCfg.preMultiplyAlpha))
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+    /* check for VC1 configurations */
+    if (retVal == ((uint32_t) TRUE))
+    {
+        if ((instCfg->vc1Cfg.vc1Enable != progCfg->vc1Cfg.vc1Enable) ||
+            (instCfg->vc1Cfg.rangeY    != progCfg->vc1Cfg.rangeY)    ||
+            (instCfg->vc1Cfg.rangeUV   != progCfg->vc1Cfg.rangeUV))
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+    /* check for Crop configurations */
+    if (retVal == ((uint32_t) TRUE))
+    {
+        if ((instCfg->cropParams.cropEnable         != progCfg->cropParams.cropEnable)         ||
+            (instCfg->cropParams.cropCfg.cropTop    != progCfg->cropParams.cropCfg.cropTop)    ||
+            (instCfg->cropParams.cropCfg.cropBottom != progCfg->cropParams.cropCfg.cropBottom) ||
+            (instCfg->cropParams.cropCfg.cropLeft   != progCfg->cropParams.cropCfg.cropLeft)   ||
+            (instCfg->cropParams.cropCfg.cropRight  != progCfg->cropParams.cropCfg.cropRight))
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+    /* check for Layer configurations */
+    if (retVal == ((uint32_t) TRUE))
+    {
+        if ((instCfg->layerPos.startX != progCfg->layerPos.startX) ||
+            (instCfg->layerPos.startY != progCfg->layerPos.startY))
+        {
+            retVal = (uint32_t) FALSE;
+        }
+    }
+
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDispMFlagCfgChk(const Dss_DispPipeMflagParams *instCfg,
+                                   const Dss_DispPipeMflagParams *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->mflagCfg.thresholdLow  != progCfg->mflagCfg.thresholdLow)  ||
+        (instCfg->mflagCfg.thresholdHigh != progCfg->mflagCfg.thresholdHigh))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+uint32_t Dss_m2mDrvDispCscCfgChk(const CSL_DssCscCoeff *instCfg,
+                                 const CSL_DssCscCoeff *progCfg)
+{
+    uint32_t retVal = (uint32_t) TRUE;
+
+    if ((instCfg->cscRange     != progCfg->cscRange)    ||
+        (instCfg->c00          != progCfg->c00)         ||
+        (instCfg->c01          != progCfg->c01)         ||
+        (instCfg->c02          != progCfg->c02)         ||
+        (instCfg->c10          != progCfg->c10)         ||
+        (instCfg->c11          != progCfg->c11)         ||
+        (instCfg->c12          != progCfg->c12)         ||
+        (instCfg->c20          != progCfg->c20)         ||
+        (instCfg->c21          != progCfg->c21)         ||
+        (instCfg->c22          != progCfg->c22)         ||
+        (instCfg->preOffset1   != progCfg->preOffset1)  ||
+        (instCfg->preOffset2   != progCfg->preOffset2)  ||
+        (instCfg->preOffset3   != progCfg->preOffset3)  ||
+        (instCfg->postOffset1  != progCfg->postOffset1) ||
+        (instCfg->postOffset2  != progCfg->postOffset2) ||
+        (instCfg->postOffset3  != progCfg->postOffset3))
+    {
+        retVal = (uint32_t) FALSE;
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvPrgramDisp(DssM2MDrv_VirtContext *context)
+{
+    int32_t retVal = FVID2_SOK;
+    uint32_t copyCfg = (uint32_t) FALSE;
+    uint32_t layerNum, pipeIdx;
+    DssM2MDrv_InstObj *instObj;
+    DssM2MDrv_DispPipeCfg *instCfg, *progCfg;
+    CSL_DssOverlayPipePosCfg overlayPosCfg;
+
+    instObj = context->instObj;
+
+    for (pipeIdx = 0U ; pipeIdx < context->numPipe ; pipeIdx++)
+    {
+        instCfg = &context->instCfg.pipeCfg[context->pipeId[pipeIdx]];
+        progCfg = &instObj->progCfg.pipeCfg[context->pipeId[pipeIdx]];
+        /* Re-program DSS pipe only if channel/instance configurations
+           are different than programmed */
+        if (FVID2_SOK == retVal)
+        {
+            /* Check DSS Pipeline configuration */
+            if (((uint32_t) FALSE) == Dss_m2mDrvDispPipeCfgChk(&instCfg->cfgParams,
+                                                               &progCfg->cfgParams))
+            {
+                if (FVID2_SOK == retVal)
+                {
+                    /* Program: DSS Pipeline */
+                    /* Need to program CSC params only is cscRange is CUSTOM. CSL has prediefined params
+                     * for LIMITED and FULL ranges which it uses for programming pipe.
+                     */
+                    if(CSL_DSS_CSC_RANGE_CUSTOM == instCfg->cfgParams.pipeCfg.cscRange)
+                    {
+                        Fvid2Utils_memcpy(&instCfg->cfgParams.pipeCfg.custCscCoeff,
+                                &progCfg->cfgParams,
+                                sizeof(CSL_DssCscCoeff));
+                    }
+
+                    retVal = CSL_dssVidPipeSetConfig(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                                (const CSL_DssVidPipeCfg *)(&instCfg->cfgParams.pipeCfg),
+                                (const CSL_DssVidPipeVC1Cfg *)(&instCfg->cfgParams.vc1Cfg));
+                }
+                if (FVID2_SOK == retVal)
+                {
+                    /* Program: DMA, Alpha, Crop, Layer configurations */
+                    CSL_dssVidPipeSetDmaConfig(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                                (const CSL_DssVidPipeDmaCfg *)(&instCfg->cfgParams.dmaCfg));
+
+                    CSL_dssVidPipeSetAlphaConfig(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                                (const CSL_DssVidPipeAlphaCfg *)(&instCfg->cfgParams.alphaCfg));
+
+#if defined (SOC_J721E) || defined (SOC_J721S2)
+                    CSL_dssVidPipeSetCropConfig(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                            (const Fvid2_EdgeCropConfig *)(&instCfg->cfgParams.cropParams.cropCfg),
+                            instCfg->cfgParams.cropParams.cropEnable);
+#endif
+                    layerNum = CSL_dssOverlayGetEnabledPipeLayerNum(instObj->ovrRegs,
+                                                                    context->pipeId[pipeIdx]);
+                    GT_assert(DssTrace, (layerNum < CSL_DSS_OVERLAY_LAYER_MAX));
+                    overlayPosCfg.layerPos.startX = instCfg->cfgParams.layerPos.startX;
+                    overlayPosCfg.layerPos.startY = instCfg->cfgParams.layerPos.startY;
+                    CSL_dssOverlaySetPipePosConfig(instObj->ovrRegs,
+                                (const CSL_DssOverlayPipePosCfg *)(&overlayPosCfg),
+                                layerNum);
+                }
+                if (FVID2_SOK == retVal)
+                {
+                    copyCfg = (uint32_t) TRUE;
+                }
+            }
+        }
+        if (FVID2_SOK == retVal)
+        {
+            /* Check DSS Pipeline MFlag configuration */
+            if (((uint32_t) FALSE) == Dss_m2mDrvDispMFlagCfgChk(&instCfg->mFlagParams,
+                                                                &progCfg->mFlagParams))
+            {
+                if (FVID2_SOK == retVal)
+                {
+                    /* Program: DSS Pipeline MFlag */
+                    CSL_dssVidPipeSetMflagConfig(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                        (const CSL_DssVidPipeMFlagCfg *)(&instCfg->mFlagParams.mflagCfg));
+                    copyCfg = (uint32_t) TRUE;
+                }
+            }
+        }
+        if (FVID2_SOK == retVal)
+        {
+            /* Check DSS Pipeline Csc configuration */
+            if (((uint32_t) FALSE) == Dss_m2mDrvDispCscCfgChk(&instCfg->cscCoeff,
+                                                              &progCfg->cscCoeff))
+            {
+                if (FVID2_SOK == retVal)
+                {
+                    /* Program: DSS Pipeline Csc */
+                    CSL_dssVidPipeSetCSCCoeff(instObj->pipeRegs[context->pipeId[pipeIdx]],
+                            (const CSL_DssCscCoeff *)(&instCfg->cscCoeff));
+                    copyCfg = (uint32_t) TRUE;
+                }
+            }
+        }
+        if ((FVID2_SOK == retVal) && (((uint32_t) TRUE) == copyCfg))
+        {
+            /* Update instance configurations */
+            Fvid2Utils_memcpy(progCfg, instCfg, sizeof(DssM2MDrv_DispPipeCfg));
+        }
+    }
+
+    return retVal;
+}
+
+static int32_t Dss_m2mDrvValidateDispParams(DssM2MDrv_InstObj *instObj,
+                                            const Dss_PipeCfgParams *pipeCfg)
+{
+    int32_t retVal = FVID2_SOK;
+    const Dss_DispParams *dispParams;
+
+    dispParams = &pipeCfg->cfgParams;
+    /* Not Checked: Interlaced to progressive or vice versa, not supported in M2M */
+    /* Scaling ratio check */
+    if(((dispParams->pipeCfg.inFmt.height * 16U) <
+                                        (dispParams->pipeCfg.outHeight)) ||
+       ((dispParams->pipeCfg.inFmt.width * 16U) <
+                                        (dispParams->pipeCfg.outWidth)))
+    {
+        GT_0trace(DssTrace,
+                  GT_ERR,
+                  "M2M: Upscaling ratio is more than 16x \r\n");
+        retVal = FVID2_EINVALID_PARAMS;
+    }
+    if(((dispParams->pipeCfg.inFmt.height) >
+                                    (dispParams->pipeCfg.outHeight * 4U)) ||
+       ((dispParams->pipeCfg.inFmt.width) >
+                                    (dispParams->pipeCfg.outWidth * 4U)))
+    {
+        GT_0trace(DssTrace,
+                  GT_ERR,
+                  "M2M: Downscaling ratio is more than 0.25x \r\n");
+        retVal = FVID2_EINVALID_PARAMS;
+    }
+
+    if((dispParams->pipeCfg.inFmt.height != dispParams->pipeCfg.outHeight) ||
+       (dispParams->pipeCfg.inFmt.width != dispParams->pipeCfg.outWidth))
+    {
+        if(TRUE == Dss_dispIsVidLInst(pipeCfg->pipeId))
+        {
+            GT_0trace(DssTrace,
+                      GT_ERR,
+                      "M2M: Scaling cant be enabled for video lite pipe \r\n");
+            retVal = FVID2_EINVALID_PARAMS;
+        }
+        if(FALSE == dispParams->pipeCfg.scEnable)
+        {
+            GT_0trace(DssTrace,
+                      GT_ERR,
+                      "M2M: Scaling should be enabled \r\n");
+            retVal = FVID2_EINVALID_PARAMS;
+        }
+    }
+
+    if((dispParams->cropParams.cropCfg.cropTop >= 32U) ||
+       (dispParams->cropParams.cropCfg.cropBottom >= 32U) ||
+       (dispParams->cropParams.cropCfg.cropLeft >= 32U) ||
+       (dispParams->cropParams.cropCfg.cropRight >= 32U))
+    {
+        GT_0trace(DssTrace,
+                  GT_ERR,
+                  "M2M: Crop Parameter(s) should be less than 32 \r\n");
+        retVal = FVID2_EINVALID_PARAMS;
+    }
+
+    if(((dispParams->pipeCfg.flipType == FVID2_FLIP_TYPE_V) ||
+        (dispParams->pipeCfg.flipType == FVID2_FLIP_TYPE_H)) &&
+       ((dispParams->pipeCfg.inFmt.dataFormat == FVID2_DF_RGB24_888) ||
+        (dispParams->pipeCfg.inFmt.dataFormat == FVID2_DF_BGR24_888)))
+    {
+        GT_0trace(DssTrace,
+                  GT_ERR,
+                  "M2M: Flip Parameter(s) should not be used for 24-bit RGB/BGR formats \r\n");
+        retVal = FVID2_EINVALID_PARAMS;
+    }
+
+    /* There is a limitation with scaling in DSS, where maximum scaling ratio
+     * supported is the ratio of the DSS functional clock and Pixel Clock.
+     * Driver can't check this condition as it is unaware of Pixel Clock.
+     * So it should be checked by the application.
+     */
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetDssPipeParams(DssM2MDrv_VirtContext *context,
+                                        const Dss_PipeCfgParams *pipeCfg)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == pipeCfg)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else if (pipeCfg->pipeId >= CSL_DSS_VID_PIPE_ID_MAX)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        retVal = Dss_m2mDrvValidateDispParams(context->instObj, pipeCfg);
+        if (retVal == FVID2_SOK)
+        {
+            /* upgrade configurations into context object and re-program HW module
+               on buffer submission */
+            Fvid2Utils_memcpy(&context->instCfg.pipeCfg[pipeCfg->pipeId].cfgParams,
+                              &pipeCfg->cfgParams,
+                              sizeof(Dss_DispParams));
+        }
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetPipeMflagParams(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeMflagParams *mFlagParams)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == mFlagParams)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else if (mFlagParams->pipeId >= CSL_DSS_VID_PIPE_ID_MAX)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* upgrade configurations into context object and re-program HW module
+           on buffer submission */
+        Fvid2Utils_memcpy(&context->instCfg.pipeCfg[mFlagParams->pipeId].mFlagParams,
+                          &mFlagParams->mFlagCfg,
+                          sizeof(Dss_DispPipeMflagParams));
+    }
+
+    return retVal;
+}
+
+int32_t Dss_m2mDrvIoctlSetPipeCsc(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeCscParams *csc)
+{
+    int32_t retVal = FVID2_SOK;
+
+    /* check for parameters */
+    if (NULL == csc)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else if (csc->pipeId >= CSL_DSS_VID_PIPE_ID_MAX)
+    {
+        retVal = FVID2_EBADARGS;
+    }
+    else
+    {
+        /* upgrade configurations into context object and re-program HW module
+           on buffer submission */
+        Fvid2Utils_memcpy(&context->instCfg.pipeCfg[csc->pipeId].cscCoeff,
+                          &csc->csc,
+                          sizeof(CSL_DssCscCoeff));
+    }
+
+    return retVal;
+}
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDrv.h b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDrv.h
new file mode 100755
index 00000000..0d131ac5
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mDrv.h
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2mDrv.h
+ *
+ *  \brief DSS m2m driver internal interface file.
+ */
+
+#ifndef DSS_M2MDRV_H_
+#define DSS_M2MDRV_H_
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <ti/drv/dss/src/drv/m2m/dss_m2mPriv.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+/**
+ *  \brief DSS M2M Driver initialization parameters.
+ */
+typedef struct
+{
+    uint32_t drvInstId;
+    /**< Driver Instance Id */
+} Dss_M2MDrvInitParams;
+
+/* ========================================================================== */
+/*                  Internal/Private Function Declarations                   */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+/**
+ *  \brief DSS display driver initialization function.
+ *   This function gets called as a part of Dss_init(). It Initializes internal
+ *   data structures and common system level resources related to display.
+ *
+ *  \param initParams     Pointer to a #Dss_InitParams structure
+ *                        containing the driver init configuration
+ *
+ *  \return FVID2_SOK if successful, else suitable error code
+ */
+int32_t Dss_m2mDrvInit(const Dss_InitParams *initParams);
+
+/**
+ *  \brief DSS display driver de-initialization function.
+ *   This function gets called as a part of Dss_deInit(). It de-Initializes
+ *   internal data structures and common system level resources
+ *   related to display.
+ *
+ *  \param None
+ *
+ *  \return FVID2_SOK if successful, else suitable error code
+ */
+int32_t Dss_m2mDrvDeInit(void);
+
+/*
+ * FVID2 DSS M2M Driver API's
+ */
+Fdrv_Handle Dss_m2mCreate(uint32_t drvId,
+                          uint32_t instId,
+                          void *createArgs,
+                          void *createStatusArgs,
+                          const Fvid2_DrvCbParams *fdmCbParams);
+
+int32_t Dss_m2mDelete(Fdrv_Handle handle, void *reserved);
+
+int32_t Dss_m2mProcessRequest(Fdrv_Handle handle,
+                              Fvid2_FrameList *inProcessList,
+                              Fvid2_FrameList *outProcessList,
+                              uint32_t timeout);
+
+int32_t Dss_m2mGetProcessedRequest(Fdrv_Handle handle,
+                                   Fvid2_FrameList *inProcessList,
+                                   Fvid2_FrameList *outProcessList,
+                                   uint32_t timeout);
+
+int32_t Dss_m2mControl(Fdrv_Handle handle,
+                       uint32_t cmd,
+                       void *cmdArgs,
+                       void *cmdStatusArgs);
+/* ========================================================================== */
+/*                       Static Function Definitions                          */
+/* ========================================================================== */
+
+/* None */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef DSS_M2MDRV_H_ */
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mPriv.h b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mPriv.h
new file mode 100755
index 00000000..3fbe9fb5
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/dss_m2mPriv.h
@@ -0,0 +1,416 @@
+/*
+ *  Copyright (c) Texas Instruments Incorporated 2021
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    Redistributions 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.
+ */
+
+/**
+ *  \file dss_m2mPriv.h
+ *
+ *  \brief DSS M2M driver private header file.
+ */
+
+#ifndef DSS_M2MPRIV_H_
+#define DSS_M2MPRIV_H_
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+#include <ti/drv/dss/dss.h>
+
+#ifdef __cplusplus
+"C" {
+#endif
+
+/* ========================================================================== */
+/*                           Macros & Typedefs                                */
+/* ========================================================================== */
+
+/**
+ *  \brief Minimum number of buffers needed for starting the display operation.
+ */
+#define DSS_M2M_DRV_MIN_PRIME_BUFFERS        (0U)
+
+/**
+ *  \anchor DSSM2M_DrvState
+ *  \name   DSS M2M DRV State
+ *  \brief  Represents the state of the DSS M2M Driver state.
+ *
+ *  @{
+ */
+/*
+ * State transitions are explained below
+ *
+ * IDLE - initial or not open state
+ *  |
+ * CREATED - state after calling Fvid2_create
+ *  |
+ * DO_START - temporary state when Fvid2_start() is called
+ *  |         this means driver has requested Capture Module to start the instance
+ *  |
+ * RUNNING  - this is the state after Fvid2_start() completes, this means
+ *  |         Capture Module started capture and now it is running, it remains in this
+ *  |         state
+ *  |         until Fvid2_stop()  is called
+ *  |
+ * DO_STOP  - temporary state when Fvid2_stop is called()
+ *  |         this means driver has request Capture Module to stop the instance
+ *  |
+ * STOPPED  - this is the state after Fvid2_stop() completes, this means
+ *  |         Capture Module has stopped this instance
+ *  |
+ * IDLE     - this is the state after Fvid2_delete() completes
+ */
+/** \brief Driver is not open and is idle. */
+#define DSSM2M_DRV_STATE_IDLE             ((uint32_t)0U)
+/** \brief Driver is created. */
+#define DSSM2M_DRV_STATE_CREATED          ((uint32_t)1U)
+/** \brief Driver is requesting a start. */
+#define DSSM2M_DRV_STATE_DO_START         ((uint32_t)2U)
+/** \brief Driver is running. */
+#define DSSM2M_DRV_STATE_RUNNING          ((uint32_t)3U)
+/** \brief Driver is requesting a stop. */
+#define DSSM2M_DRV_STATE_DO_STOP          ((uint32_t)4U)
+/** \brief Driver is stopped. */
+#define DSSM2M_DRV_STATE_STOPPED          ((uint32_t)5U)
+/** \brief Driver is un-initialized. */
+#define DSSM2M_DRV_STATE_UNINIT           ((uint32_t)6U)
+/* @} */
+
+/**
+ *  \anchor DSSM2M_DrvUsageStatus
+ *  \name   DSS M2M Usage status
+ *  \brief  Usage status for module of DSS M2M DRV.
+ *
+ *  @{
+ */
+/** \brief Usage Status: Not used */
+#define DSSM2M_DRV_USAGE_STATUS_NOT_USED               ((uint32_t) 0xDEADBABEU)
+/** \brief Usage Status: In use */
+#define DSSM2M_DRV_USAGE_STATUS_IN_USE                 ((uint32_t) 0xABCDEF01U)
+/* @} */
+
+/* ========================================================================== */
+/*                         Structure Declarations                             */
+/* ========================================================================== */
+typedef struct DssM2MDrv_InstObj_t DssM2MDrv_InstObj;
+typedef struct DssM2MDrv_VirtContext_t DssM2MDrv_VirtContext;
+typedef struct DssM2MDrv_DispPipeCfg_t DssM2MDrv_DispPipeCfg;
+typedef struct DssM2MDrv_dctrlCfg_t DssM2MDrv_dctrlCfg;
+typedef struct DssM2MDrv_CommonObj_t DssM2MDrv_CommonObj;
+typedef struct DssM2MDrv_WbPipeCfg_t DssM2MDrv_WbPipeCfg;
+typedef struct DssM2MDrv_moduleCfg_t DssM2MDrv_moduleCfg;
+typedef struct DssM2M_DrvQueObj_t DssM2M_DrvQueObj;
+typedef struct DssM2M_DrvBufManObj_t DssM2M_DrvBufManObj;
+
+/*
+ * struct DssM2MDrv_DispPipeCfg_t
+ * \brief DSS display pipe configurations handle object.
+ *        These are object re-used from DSS_DISP_DRV
+ */
+struct DssM2MDrv_DispPipeCfg_t
+{
+    Dss_DispParams cfgParams;
+    /**< DSS pipeline parameters */
+    Dss_DispPipeMflagParams mFlagParams;
+    /**< Video Pipeline Mflag Information */
+    CSL_DssCscCoeff cscCoeff;
+    /**< CSC co-efficients for DSS_DISP_DRV */
+};
+
+/*
+ * struct DssM2MDrv_dctrlCfg_t
+ * \brief DSS display controller configurations handle object.
+ *        These are object re-used from DSS_DCTRL_DRV
+ */
+struct DssM2MDrv_dctrlCfg_t
+{
+    Dss_DctrlOverlayParams ovlParams;
+    /**< Overlay configurations information */
+    Dss_DctrlOverlayLayerParams ovlLayerParams;
+    /**< Overlay layer information */
+    Dss_DctrlGlobalDssParams globalParams;
+    /**< global DSS Configuration */
+};
+
+/*
+ * struct DssM2MDrv_WbPipeCfg_t
+ * \brief DSS display write-back pipe configurations handle object.
+ */
+struct DssM2MDrv_WbPipeCfg_t
+{
+    Dss_WbPipeCfgParams cfgParams;
+    /**< DSS write-back pipe configuration */
+    CSL_DssWbPipeDmaCfg dmaCfg;
+    /**< DMA configuration for WB pipeline */
+    Dss_WbPipeMflagParams  mFlagParams;
+    /**< Video write-back Pipe Mflag Information */
+    CSL_DssCscCoeff cscCoeff;
+    /**< CSC co-efficients for write-back pipeline */
+};
+
+/*
+ * struct DssM2MDrv_moduleCfg_t
+ * \brief Object containing DSS module configurations.
+ */
+struct DssM2MDrv_moduleCfg_t
+{
+    DssM2MDrv_DispPipeCfg pipeCfg[CSL_DSS_VID_PIPE_ID_MAX];
+    /**< Display pipeline configuration parameters */
+    DssM2MDrv_dctrlCfg dctrlCfg;
+    /**< Display controller configuration parameters  */
+    DssM2MDrv_WbPipeCfg wbPipeCfg;
+    /**< Write-back pipeline configuration parameters */
+};
+
+/*
+ * struct DssM2MDrv_VirtContext_t
+ * \brief DSS M2M driver create handle object.
+ */
+struct DssM2MDrv_VirtContext_t
+{
+    uint32_t contextId;
+    /**< Context ID */
+    uint32_t inUse;
+    /**< Current is being used or not.
+      *   See \ref DSSM2M_DrvUsageStatus for details */
+    uint32_t state;
+    /**< Instance state.
+      *  See \ref DSSM2M_DrvState for details */
+    DssM2MDrv_InstObj *instObj;
+    /**< Reference to instance object. */
+    Dss_WbCreateParams createParams;
+    /**< DSS M2M module create configurations.
+      *  See \ref Dss_WbCreateParams for details */
+    Fvid2_DrvCbParams fdmCbParams;
+    /**< FVID2 driver manager callback function parameters. */
+    Dss_WbStatus wbStatus;
+    /**< DSS M2M driver status.
+      *  See \ref Dss_WbStatus for details */
+    DssM2MDrv_moduleCfg instCfg;
+    /**< DSS module configurations provided by application.
+      *  See \ref DssM2MDrv_moduleCfg for details */
+    Fvid2UtilsLinkListObj *doneQ;
+    /**< Queue object to put the displayed output requests */
+    Fvid2UtilsLinkListObj doneLlObj;
+    /**< Linked List object for doneQ */
+    uint32_t numBufQed;
+    /**< Number of buffers Queued to HW */
+    uint32_t numPipe;
+    /**< Number of Display pipe-lines used for given M2M/WB pipeline. */
+    uint32_t pipeId[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< ID DSS pipeline to use.
+     *   See \ref CSL_DssVidPipeId for details */
+    uint32_t overlayId;
+    /**< ID DSS overlay to use. CSL_DssOverlayId.
+     *   See \ref CSL_DssOverlayId for details */
+};
+
+/**
+ *  \brief Structure defining the queue object used in queue/dequeue operation.
+ *   Instead of creating frame objects, this is used so that any other
+ *   information could be queued/dequeued along with the frame.
+ *   Already qElem is added to avoid dynamic allocation of Queue nodes.
+ */
+struct DssM2M_DrvQueObj_t
+{
+    Fvid2Utils_QElem qElem;
+    /**< FVID2 Utils queue element used in node addition */
+    DssM2MDrv_VirtContext *virtContext;
+    /**< Reference to the instance object for this queue object */
+    uint32_t numPipe;
+    /**< Number of DSS pipes used. This will be also equal to number of frames in inFrm */
+    Fvid2_Frame *inFrm[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< #FVID2_frame to read the incoming frame packets from memory */
+    Fvid2_Frame *outFrm;
+    /**< #FVID2_frame to store the outgoing frame packets to memory */
+};
+
+/**
+ *  \brief Structure to store the buffer management functionality variables.
+ */
+struct DssM2M_DrvBufManObj_t
+{
+    /*
+     * Initially all the queue elements will be in freeQ.
+     *
+     * For every application submit request operation,      freeQ -> reqQ
+     * For every request submitted to hardware,             reqQ  -> currQ
+     * For every request completion from hardware,          currQ  -> doneQ
+     * For every application get request operation,         doneQ -> freeQ
+     */
+    Fvid2UtilsLinkListObj *freeQ;
+    /**< Queue for queuing all the free queue objects */
+    Fvid2UtilsLinkListObj freeLlObj;
+    /**< Linked List object for freeQ */
+    Fvid2UtilsLinkListObj *reqQ;
+    /**< Queue object to put the input requests */
+    Fvid2UtilsLinkListObj reqLlObj;
+    /**< Linked List object for reqQ */
+    Fvid2UtilsLinkListObj *currQ;
+    /**< Buffers that are queued to hardware but not yet fully displayed */
+    Fvid2UtilsLinkListObj curLlObj;
+    /**< Linked List object for currQ */
+    DssM2M_DrvQueObj m2mQObj[(DSS_DEF_QUEUE_LEN_PER_M2M_DRV_INST * DSSM2M_NUM_VIRTUAL_CONTEXT)];
+    /**< Display queue objects */
+};
+
+/**
+ *  \brief DSS M2M Driver Instance Object.
+ */
+struct DssM2MDrv_InstObj_t
+{
+    uint32_t drvInstId;
+    /**< Instance ID. */
+    uint32_t inUse;
+    /**< Current is being used or not.
+      *   See \ref DSSM2M_DrvUsageStatus for details */
+    uint32_t numRegEvtHandle;
+    /**< Number of registered event group handles */
+    void *evtGroupHandle[DSS_DISP_INST_EVT_MGR_MAX_CLIENTS];
+    /**< Handle to registered event groups */
+    DssM2MDrv_CommonObj *commonObjRef;
+    /**< Reference to driver common object */
+    Dss_WbStatus status;
+    /**< DSS M2M driver status */
+    DssM2MDrv_moduleCfg progCfg;
+    /**< DSS module configurations actually programmed into the HW module.
+      *  See \ref DssM2MDrv_moduleCfg for details */
+    CSL_dss_commRegs *commRegs;
+    /**< Write-back Pipe registers */
+    CSL_dss_pipeRegs *pipeRegs[CSL_DSS_VID_PIPE_ID_MAX];
+    /**< Write-back Pipe registers */
+    CSL_dss_overlayRegs *ovrRegs;
+    /**< Write-back Pipe registers */
+    CSL_dss_wbRegs *wbRegs;
+    /**< Write-back Pipe registers */
+    DssM2M_DrvBufManObj bmObj;
+    /**< Buffer management object */
+    uint32_t numPipe;
+    /**< Number of Display pipe-lines used for given M2M/WB pipeline. */
+    uint32_t pipeId[DSSM2M_NUM_PIPELINE_TO_USE_IN_M2M_MODE];
+    /**< ID of DSS pipeline used. */
+    uint32_t overlayId;
+    /**< ID of DSS overlay used. */
+    uint32_t pathCfgDone;
+    /**< Path configuration done. True if done, false otherwise. */
+    Dss_DctrlPathInfo pathInfo;
+    /**< DSS path information */
+};
+
+/*
+ * struct DssM2MDrv_CommonObj_t
+ * \brief DSS M2M driver global/common driver object.
+ */
+struct DssM2MDrv_CommonObj_t
+{
+    Fvid2_DrvOps fvidDrvOps;
+    /**< FVID2 driver ops. */
+    uint32_t isRegistered;
+    /**< FVID2 registration complete flag. */
+    uint32_t numVirtContUsed[DSSM2M_NUM_WB_PIPELINE];
+    /**< Number of virtual context used */
+    DssM2MDrv_VirtContext virtContext[DSSM2M_NUM_WB_PIPELINE][DSSM2M_NUM_VIRTUAL_CONTEXT];
+    /**< Virtual context objects. */
+    DssM2MDrv_InstObj instObj[DSSM2M_NUM_WB_PIPELINE];
+    /**< DSS M2M HW instance objects. */
+    Dss_SocInfo socInfo;
+    /**< Structure containing Register addresses for DSS regions */
+    Fvid2_TimeStampFxn getTimeStamp;
+    /**< Get time stamp function. */
+    SemaphoreP_Handle lockSem;
+    /**< Semaphore to protect the open/close calls and other memory
+     *   allocation per instance. */
+};
+/* ========================================================================== */
+/*                  Internal/Private Function Declarations                   */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/*                          Function Declarations                             */
+/* ========================================================================== */
+int32_t Dss_m2mDrvIoctlSetDssPipeParams(DssM2MDrv_VirtContext *context,
+                                        const Dss_PipeCfgParams *pipeCfg);
+
+int32_t Dss_m2mDrvIoctlSetPipeMflagParams(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeMflagParams *mFlagParams);
+
+int32_t Dss_m2mDrvIoctlSetPipeCsc(DssM2MDrv_VirtContext *context,
+                                  const Dss_PipeCscParams *csc);
+
+int32_t Dss_m2mDrvIoctlSetOverlayParams(DssM2MDrv_VirtContext *context,
+                                    const Dss_DctrlOverlayParams *ovlParams);
+
+int32_t Dss_m2mDrvIoctlSetLayerParams(DssM2MDrv_VirtContext *context,
+                        const Dss_DctrlOverlayLayerParams *ovlLayerParams);
+
+int32_t Dss_m2mDrvIoctlSetGlobalParams(DssM2MDrv_VirtContext *context,
+                               const Dss_DctrlGlobalDssParams *globalParams);
+
+uint32_t Dss_m2mDrvDctrlOvlCfgChk(const Dss_DctrlOverlayParams *instCfg,
+                                  const Dss_DctrlOverlayParams *progCfg);
+
+uint32_t Dss_m2mDrvDctrlOvlLayerCfgChk(const Dss_DctrlOverlayLayerParams *instCfg,
+                                       const Dss_DctrlOverlayLayerParams *progCfg);
+
+uint32_t Dss_m2mDrvDctrlGlobalCfgChk(const Dss_DctrlGlobalDssParams *instCfg,
+                                     const Dss_DctrlGlobalDssParams *progCfg);
+
+uint32_t Dss_m2mDrvDctrlPathCfgChk(const Dss_DctrlPathInfo * instCfg,
+                                   const Dss_DctrlPathInfo * progCfg);
+
+int32_t Dss_m2mDrvPrgramDctrl(DssM2MDrv_VirtContext *context);
+
+uint32_t Dss_m2mDrvDispPipeCfgChk(const Dss_DispParams *instCfg,
+                                  const Dss_DispParams *progCfg);
+
+uint32_t Dss_m2mDrvDispMFlagCfgChk(const Dss_DispPipeMflagParams *instCfg,
+                                   const Dss_DispPipeMflagParams *progCfg);
+
+uint32_t Dss_m2mDrvDispCscCfgChk(const CSL_DssCscCoeff *instCfg,
+                                 const CSL_DssCscCoeff *progCfg);
+
+int32_t Dss_m2mDrvPrgramDisp(DssM2MDrv_VirtContext *context);
+
+int32_t Dss_m2mDrvSetWbPipeDmaCfg(DssM2MDrv_InstObj *instObj,
+                                  const CSL_DssWbPipeDmaCfg *dmaCfg);
+/* ========================================================================== */
+/*                       Static Function Definitions                          */
+/* ========================================================================== */
+
+/* None */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef DSS_M2MPRIV_H_ */
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/src_files_m2m.mk b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/src_files_m2m.mk
new file mode 100755
index 00000000..454980ac
--- /dev/null
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/m2m/src_files_m2m.mk
@@ -0,0 +1 @@
+SRCS_COMMON += dss_m2mDctrl.c dss_m2mDisp.c dss_m2mApi.c
diff --git a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/src_files_drv.mk b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/src_files_drv.mk
index 4b512678..ae5d2cd9 100755
--- a/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/src_files_drv.mk
+++ b/pdk_j784s4_08_05_00_37/packages/ti/drv/dss/src/drv/src_files_drv.mk
@@ -8,7 +8,7 @@ include src/drv/common/src_files_common.mk
 include src/drv/dctrl/src_files_dctrl.mk
 include src/drv/disp/src_files_disp.mk
 
-ifeq ($(SOC),$(filter $(SOC), j721e j721s2))
+ifeq ($(SOC),$(filter $(SOC), j721e j721s2 j784s4))
 SRCDIR += src/drv/m2m
 PACKAGE_SRCS_COMMON += src/drv/m2m
 include src/drv/m2m/src_files_m2m.mk
diff --git a/tiovx/build_flags.mak b/tiovx/build_flags.mak
index 1e3ec6a7..85aaed11 100755
--- a/tiovx/build_flags.mak
+++ b/tiovx/build_flags.mak
@@ -24,7 +24,7 @@ BUILD_CT_TIOVX_TVM=yes
 BUILD_CT_TIOVX_HWA=yes
 BUILD_CT_TIOVX_HWA_NEGATIVE_TESTS=yes
 BUILD_CT_TIOVX_HWA_CAPTURE_TESTS=no
-BUILD_CT_TIOVX_HWA_DISPLAY_TESTS=no
+BUILD_CT_TIOVX_HWA_DISPLAY_TESTS=yes
 
 # valid values: release debug all
 PROFILE?=release
diff --git a/tiovx/kernels_j7/hwa/display_m2m/concerto.mak b/tiovx/kernels_j7/hwa/display_m2m/concerto.mak
index 756326e5..96b80294 100755
--- a/tiovx/kernels_j7/hwa/display_m2m/concerto.mak
+++ b/tiovx/kernels_j7/hwa/display_m2m/concerto.mak
@@ -1,4 +1,4 @@
-ifeq ($(TARGET_PLATFORM), $(filter $(TARGET_PLATFORM), J7 J721S2))
+ifeq ($(TARGET_PLATFORM), $(filter $(TARGET_PLATFORM), J7 J721S2 J784S4))
 ifeq ($(TARGET_CPU), $(filter $(TARGET_CPU), R5F))
 ifeq ($(BUILD_HWA_KERNELS),yes)
 ifeq ($(BUILD_DISPLAY),yes)
diff --git a/vision_apps/platform/j784s4/rtos/common/app_init.c b/vision_apps/platform/j784s4/rtos/common/app_init.c
index 05f22228..7014a6d1 100755
--- a/vision_apps/platform/j784s4/rtos/common/app_init.c
+++ b/vision_apps/platform/j784s4/rtos/common/app_init.c
@@ -578,7 +578,7 @@ int32_t appInit()
         prm.display_type = APP_DSS_DEFAULT_DISPLAY_TYPE_EDP;
         #endif
 
-        prm.enableM2m            = false;
+        prm.enableM2m            = true;
         /* Do not rely on "init". Always provide known good tmings */
         prm.timings.width        = 1920U;
         prm.timings.height       = 1080U;
@@ -616,7 +616,7 @@ int32_t appInit()
         /* default parameters are enough to enable both EDP and HDMI */
         appDssDualDisplayDefaultSetDefaultPrm(&prm);
 
-        prm.enableM2m                           = false;
+        prm.enableM2m                           = true;
         /* Do not rely on "init". Always provide known good tmings */
         for(i=0; i<2; i++)
         {
@@ -816,6 +816,7 @@ static void appRegisterOpenVXTargetKernels()
         #endif
         #if defined(ENABLE_DSS_SINGLE) || defined(ENABLE_DSS_DUAL)
         tivxRegisterHwaTargetDisplayKernels();
+        tivxRegisterHwaTargetDisplayM2MKernels();
         #endif
         #ifdef C7120
         #if defined(CPU_c7x_1) || defined(CPU_c7x_2) || defined(CPU_c7x_3) || defined(CPU_c7x_4)
diff --git a/vision_apps/platform/j784s4/rtos/concerto_r5f_inc.mak b/vision_apps/platform/j784s4/rtos/concerto_r5f_inc.mak
index e7bb6a32..f58c74aa 100755
--- a/vision_apps/platform/j784s4/rtos/concerto_r5f_inc.mak
+++ b/vision_apps/platform/j784s4/rtos/concerto_r5f_inc.mak
@@ -57,6 +57,7 @@ TIOVX_LIBS += vx_target_kernels_display
 TIOVX_LIBS += vx_target_kernels_capture
 TIOVX_LIBS += vx_target_kernels_csitx
 TIOVX_LIBS += vx_target_kernels_j7_arm
+TIOVX_LIBS += vx_target_kernels_display_m2m
 
 IMAGING_LIBS  = ti_imaging_awbalg
 IMAGING_LIBS += ti_imaging_dcc
-- 
2.17.1

