//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    Power.c

Abstract:       Implementation of Video Driver
                This module handle Power context data

Functions:


Notes:


--*/

#include <bsp.h>
#include <CAMDriver.h>
#include "pmplatform.h"
#include "SVEngine.h"

//extern DBGPARAM dpCurSettings;

void SVE_initialize_power_context(void)
{
    SVEnginePowerContext *pPMCtxt;

    VDE_MSG((_T("[VDE] SVE_initialize_context()\r\n")));

    pPMCtxt = SVE_get_power_context();

    memset(pPMCtxt, 0x0, sizeof(SVEnginePowerContext));

    pPMCtxt->bPowerOn = TRUE;    // Initially Power On

    // Invalidate All Stored Values
    pPMCtxt->bFIMDOutputParam = FALSE;
    pPMCtxt->bFIMDOutputWB = FALSE;
    pPMCtxt->eVideoOutPath = DISP_OUTPUT_SINGLE_BYPASS;
    pPMCtxt->dwCaptureFrameRate = 30;
    pPMCtxt->bFIMDOutputGamma = FALSE;
    pPMCtxt->bFIMDOutputColorGain = FALSE;
    pPMCtxt->bFIMDOutputHue = FALSE;
    pPMCtxt->bFIMDOutALPS = FALSE;
    pPMCtxt->bFIMDOutDithering = FALSE;
    pPMCtxt->bFIMDOutputEnable = FALSE;
    pPMCtxt->bFIMDWinMode[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDWinMode[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDWinMode[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDWinMode[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDWinMode[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDWinFBuffer[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDWinFBuffer[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDWinFBuffer[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDWinFBuffer[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDWinFBuffer[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDColorKey[DISP_WIN0] = FALSE;    // Never Used
    pPMCtxt->bFIMDColorKey[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDColorKey[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDColorKey[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDColorKey[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDAlpha[DISP_WIN0] = FALSE;        // Never Used
    pPMCtxt->bFIMDAlpha[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDAlpha[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDAlpha[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDAlpha[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDAlphaEx[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDAlphaEx[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDAlphaEx[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDAlphaEx[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDAlphaEx[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDWinColormap[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDWinColormap[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDWinColormap[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDWinColormap[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDWinColormap[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDWinQos[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDWinQos[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDWinQos[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDWinQos[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDWinQos[DISP_WIN4] = FALSE;
    pPMCtxt->bFIMDWinEnable[DISP_WIN0] = FALSE;
    pPMCtxt->bFIMDWinEnable[DISP_WIN1] = FALSE;
    pPMCtxt->bFIMDWinEnable[DISP_WIN2] = FALSE;
    pPMCtxt->bFIMDWinEnable[DISP_WIN3] = FALSE;
    pPMCtxt->bFIMDWinEnable[DISP_WIN4] = FALSE;
    pPMCtxt->bLocalPathWin0Enable = FALSE;
    pPMCtxt->bLocalPathWin1Enable = FALSE;
    pPMCtxt->bLocalPathWin2Enable = FALSE;
    pPMCtxt->bRotatorParam = FALSE;
    pPMCtxt->bRotatorSrcBuffer = FALSE;
    pPMCtxt->bRotatorDstBuffer = FALSE;
    pPMCtxt->bRotatorStart = FALSE;
}

void SVE_deinitialize_power_context(void)
{
    // Currently, Power Context is static global variable
    // So, we don't need to any deinit procedure
    VDE_MSG( (_T("[VDE] SVE_deinitialize_power_context()\r\n")));
    return;
}

void SVE_video_engine_power_on(void)
{
    SVEngineContext *pCtxt;
    SVEnginePowerContext *pPMCtxt;
    int iWinCnt;

    VDE_MSG( (_T("[VDE] ++SVE_video_engine_power_on()\r\n")));

    pCtxt = SVE_get_context();
    pPMCtxt = SVE_get_power_context();

    if (pPMCtxt->bPowerOn)
    {
        VDE_MSG((_T("[VDE:INF] SVE_video_engine_power_on() : Video Engine is Already Power On\r\n")));
        goto CleanUp;
    }

    //-------------------------------
    // HW Block Power On and Clock On
    //-------------------------------
#ifdef USE_DSI
    SVE_hw_power_control(HWPWR_MIPI_DSI_DPHY_ON);
    SVE_hw_clock_control(HWCLK_MIPI_DSI_ON);
#endif
    SVE_hw_power_control(HWPWR_DISPLAY_ON);
    SVE_hw_clock_control(HWCLK_DISPLAY_ON);

#if (S5PV210_EVT>0)
    SVE_hw_power_control(HWPWR_2D_ON);
    SVE_hw_clock_control(HWCLK_2D_ON);
#endif

    //-------------------
    // FIMD Reconfiguration
    //-------------------
    if (pPMCtxt->bFIMDOutputParam)
    {
        Disp_set_output_device_information(&pPMCtxt->tFIMDOutputParam.tDispDevInfo);

        Disp_initialize_output_interface(DISP_VIDOUT_RGBIF);
        Disp_set_output_path(pPMCtxt->eVideoOutPath);

        if (pPMCtxt->bFIMDOutputWB)
        {
            Disp_enable_WB_interface( \
                    pPMCtxt->tFIMDOutputParam.tDispDevInfo.RGBINFO.Frame_Rate/ \
                    pPMCtxt->dwCaptureFrameRate);
        }
        else
        {
            Disp_disable_WB_interface(pPMCtxt->eVideoOutPath);
        }

        if(pPMCtxt->bFIMDOutputGamma)
        {
            if(DISP_SUCCESS != Disp_set_gamma(pPMCtxt->bFIMDOutputGamma, \
                                                pPMCtxt->ucFIMDOutputGammaValue))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : Disp_set_gamma() failed\n\r")));
            }
        }

        if(pPMCtxt->bFIMDOutputColorGain)
        {
            if(DISP_SUCCESS != Disp_set_colorgain( \
                                            pPMCtxt->bFIMDOutputColorGain, \
                                            pPMCtxt->usFIMDOutputColorGainR, \
                                            pPMCtxt->usFIMDOutputColorGainG, \
                                            pPMCtxt->usFIMDOutputColorGainB))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : Disp_set_colorgain() failed\n\r")));
            }
        }

        if(pPMCtxt->bFIMDOutputHue)
        {
            if(DISP_SUCCESS != Disp_set_hue(pPMCtxt->bFIMDOutputHue, \
                                                pPMCtxt->tFIMDOutputHueControl))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : bFIMDOutputHue() failed\n\r")));
            }
        }

        if(pPMCtxt->bFIMDOutALPS)
        {
        }

        if(pPMCtxt->bFIMDOutDithering)
        {
            if(DISP_SUCCESS != Disp_set_dithering(pPMCtxt->bFIMDOutDithering, \
                                            pPMCtxt->eFIMDOutputDitheringMode))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : Disp_set_dithering() failed\n\r")));
            }
        }
    }

    //---------------------------
    // FIMD Window Reconfiguration
    //---------------------------

    for (iWinCnt=DISP_WIN0; iWinCnt< DISP_WIN_MAX; iWinCnt++)
    {
        if (pPMCtxt->bFIMDWinMode[iWinCnt])
        {
            Disp_set_window_mode(pPMCtxt->tFIMDWinMode[iWinCnt].dwWinMode, pPMCtxt->tFIMDWinMode[iWinCnt].dwBPP,
                                    pPMCtxt->tFIMDWinMode[iWinCnt].dwWidth, pPMCtxt->tFIMDWinMode[iWinCnt].dwHeight,
                                    pPMCtxt->tFIMDWinMode[iWinCnt].dwOffsetX, pPMCtxt->tFIMDWinMode[iWinCnt].dwOffsetY);
        }

        if (pPMCtxt->bFIMDWinFBuffer[iWinCnt])
        {
            Disp_set_framebuffer(iWinCnt, pPMCtxt->tFIMDWinFBuffer[iWinCnt].dwFrameBuffer);
        }

        if (pPMCtxt->bFIMDColorKey[iWinCnt])
        {
            Disp_set_color_key(iWinCnt, pPMCtxt->tFIMDColorKey[iWinCnt].bOnOff, pPMCtxt->tFIMDColorKey[iWinCnt].bBlend,
                                pPMCtxt->tFIMDColorKey[iWinCnt].dwDirection, pPMCtxt->tFIMDColorKey[iWinCnt].dwColorKey,
                                pPMCtxt->tFIMDColorKey[iWinCnt].dwCompareKey, pPMCtxt->tFIMDColorKey[iWinCnt].dwKeyAlpha);
        }

        if (pPMCtxt->bFIMDAlpha[iWinCnt])
        {
            Disp_set_alpha_blending_ex(iWinCnt, pPMCtxt->tFIMDAlphaEx[iWinCnt].dwMethod,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwABlendEq,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwBBlendEq,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwPBlendEq,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwQBlendEq,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwAlpha0,
                                        pPMCtxt->tFIMDAlphaEx[iWinCnt].dwAlpha1);
        }

        if(pPMCtxt->bFIMDWinColormap[iWinCnt])
        {
            if(DISP_SUCCESS != Disp_set_window_color_map(iWinCnt, \
                                pPMCtxt->bFIMDWinColormap[iWinCnt], \
                                pPMCtxt->uiFIMDWinColormapColorValue[iWinCnt]))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : Disp_set_window_color_map() failed\n\r")));
            }
        }

        if(pPMCtxt->bFIMDWinQos[iWinCnt])
        {
            if(DISP_SUCCESS != Disp_set_window_qos(iWinCnt, \
                                pPMCtxt->bFIMDWinQos[iWinCnt], \
                                pPMCtxt->ucFIMDWinQosFifoLevel[iWinCnt]))
            {
                VDE_ERR((_T("[VDE:ERR] SVE_video_engine_power_on() : bFIMDWinQos() failed\n\r")));
            }
        }

        if (pPMCtxt->bFIMDWinEnable[iWinCnt])
        {
            Disp_window_onfoff(iWinCnt, DISP_WINDOW_ON);
            pCtxt->bWindowEnable[iWinCnt] = TRUE;
        }
    }

    //---------------------------
    // Post Processor Reconfiguration
    //---------------------------
    {
        BOOL bRet;
        bRet = DeviceIoControl(pCtxt->hCamera/*dwLastOpenContext*/, IOCTL_CAM_POST_RESUME, (LPVOID)NULL, (DWORD)NULL, (LPVOID)NULL, (DWORD)NULL, (LPDWORD)NULL, NULL);
        if(!bRet)
        {
            VDE_INF( (_T("[VDE] %s() : Cannot Resume Post Processor\n\r"), _T(__FUNCTION__)));
//            goto CleanUp;
        }
    }

    //---------------------------
    // Local Path Reconfiguration
    //---------------------------

    if (pPMCtxt->bLocalPathWin0Enable)
    {

        Disp_set_framebuffer(DISP_WIN0, g_VideoMemoryPhysicalBase);    // Safe Frame Bufer Address for Local Path
        Disp_window_onfoff(DISP_WIN0, DISP_WINDOW_ON);

        pCtxt->bWindowEnable[DISP_WIN0] = TRUE;
    }

    if (pPMCtxt->bLocalPathWin1Enable)
    {
        // This require enabling CamIF MSDMA or TV Scaler
        // attatched to Display controller through LocalPath FIFO in caller process
        Disp_set_framebuffer(DISP_WIN1, g_VideoMemoryPhysicalBase);    // Safe Frame Bufer Address for Local Path
        Disp_window_onfoff(DISP_WIN1, DISP_WINDOW_ON);

        pCtxt->bWindowEnable[DISP_WIN1] = TRUE;
    }

    if (pPMCtxt->bLocalPathWin2Enable)
    {
        // This require enabling CamIF MSDMA or TV Scaler
        // attatched to Display controller through LocalPath FIFO in caller process
        Disp_set_framebuffer(DISP_WIN2, g_VideoMemoryPhysicalBase);    // Safe Frame Bufer Address for Local Path
        Disp_window_onfoff(DISP_WIN2, DISP_WINDOW_ON);

        pCtxt->bWindowEnable[DISP_WIN2] = TRUE;
    }

#if 0 // ROTATOR IP was changed, so new rotator d/d will be developed
    //---------------------------
    // Image Rotator Reconfiguration
    //---------------------------

    if (pPMCtxt->bRotatorParam)
    {
        SVE_hw_power_control(HWPWR_ROTATOR_ON);
        SVE_hw_clock_control(HWCLK_ROTATOR_ON);
        Rotator_initialize(pPMCtxt->tRotatorParam.dwImgFormat,
                        pPMCtxt->tRotatorParam.dwOpType,
                        pPMCtxt->tRotatorParam.dwSrcWidth,
                        pPMCtxt->tRotatorParam.dwSrcHeight);

        if (pPMCtxt->bRotatorSrcBuffer)
        {
            Rotator_set_source_buffer(pPMCtxt->tRotatorSrcBuffer.dwBufferRGBY,
                                    pPMCtxt->tRotatorSrcBuffer.dwBufferCb,
                                    pPMCtxt->tRotatorSrcBuffer.dwBufferCr);
        }

        if (pPMCtxt->bRotatorDstBuffer)
        {
            Rotator_set_destination_buffer(pPMCtxt->tRotatorDstBuffer.dwBufferRGBY,
                                    pPMCtxt->tRotatorDstBuffer.dwBufferCb,
                                    pPMCtxt->tRotatorDstBuffer.dwBufferCr);
        }

        if (pPMCtxt->bRotatorStart)
        {
            pPMCtxt->bRotatorStart = FALSE;
            pCtxt->bRotatorBusy = TRUE;
            Rotator_enable_interrupt();
            Rotator_start();
        }
    }
#endif

    if (pPMCtxt->bFIMDOutputEnable)
    {
        // Enable Interrupt
        Disp_set_frame_interrupt(DISP_FRMINT_FRONTPORCH);
        Disp_enable_frame_interrupt();

        // Video Output Enable
        Disp_envid_onoff(DISP_ENVID_ON);
        pCtxt->bVideoEnable = TRUE;
    }

    //-------------------
    // Update Power State
    //-------------------
    pPMCtxt->bPowerOn = TRUE;

CleanUp:

    VDE_MSG((_T("[VDE] --%s()\r\n"), _T(__FUNCTION__)));
}

void SVE_video_engine_power_off(void)
{
    SVEngineContext *pCtxt;
    SVEnginePowerContext *pPMCtxt;

    VDE_MSG( (_T("[VDE] ++%s()\r\n"), _T(__FUNCTION__)));

    pCtxt = SVE_get_context();
    pPMCtxt = SVE_get_power_context();

    if (!pPMCtxt->bPowerOn)
    {
        VDE_MSG((_T("[VDE:INF] %s() : Video Engine is Already Power Off\r\n"), _T(__FUNCTION__)));
        goto CleanUp;
    }

    //-----------------------
    // Disable Video Engine HW
    //-----------------------

    // Disable FIMD Interrupt
    Disp_disable_frame_interrupt();

    // Clear FIMD Interrupt Pending
    Disp_clear_interrupt_pending();

    // Disable FIMD output
    Disp_envid_onoff(DISP_ENVID_OFF);
    // wait for envid off
    {
        int i=0;
        for(i=0;i<10;i++)
        {
            if(Disp_wait_until_envid_off(1)==FALSE)
            {
                break;
            }
            Sleep(10);
        }
    }
    /*
    if(Disp_wait_until_envid_off(36000*3) == FALSE) // about 30ms, a period of VS is 18ms(55Mhz)
    {
        Disp_envid_onoff(DISP_ENVID_DIRECT_OFF);
    }
    */

    pCtxt->bVideoEnable = FALSE;
    pCtxt->bWindowEnable[DISP_WIN0] = FALSE;
    pCtxt->bWindowEnable[DISP_WIN1] = FALSE;
    pCtxt->bWindowEnable[DISP_WIN2] = FALSE;
    pCtxt->bWindowEnable[DISP_WIN3] = FALSE;
    pCtxt->bWindowEnable[DISP_WIN4] = FALSE;

    // Disable Post Processor Operation
//    Post_disable_interrupt();
//    Post_clear_interrupt_pending();
//    Post_processing_stop();
    {
        BOOL bRet;
        bRet = DeviceIoControl(pCtxt->hCamera/*dwLastOpenContext*/, IOCTL_CAM_POST_SUSPEND, (LPVOID)NULL, (DWORD)NULL, (LPVOID)NULL, (DWORD)NULL, (LPDWORD)NULL, NULL);
        if(!bRet)
        {
            VDE_INF( (_T("[VDE] %s() : Cannot Suspend Post Processor\n\r"), _T(__FUNCTION__)));
//            goto CleanUp;
        }
    }

#if 0 // ROTATOR IP was changed, so new rotator d/d will be developed
    // Disable Rotator Interrupt
    Rotator_disable_interrupt();

    // Clear Rotator Interrupt Pending
    Rotator_clear_interrupt_pending();

    // Disable Rotator Operation
    Rotator_stop();
    pCtxt->bRotatorBusy = FALSE;
#endif

    //-------------------------------
    // HW Clock Off and Block Power Off
    //-------------------------------
    SVE_hw_clock_control(HWCLK_ALL_OFF);
    SVE_hw_power_control(HWPWR_ALL_OFF);

#if (S5PV210_EVT>0)
    SVE_hw_clock_control(HWCLK_2D_OFF);
    SVE_hw_power_control(HWPWR_2D_OFF);
#endif

#ifdef USE_DSI
    SVE_hw_clock_control(HWCLK_MIPI_DSI_OFF);
    SVE_hw_power_control(HWPWR_MIPI_DSI_DPHY_OFF);
#endif

    //-------------------
    // Update Power State
    //-------------------
    pPMCtxt->bPowerOn = FALSE;

CleanUp:

    VDE_MSG((_T("[VDE] --%s()\r\n"), _T(__FUNCTION__)));
}

BOOL SVE_initialize_power_control(void)
{
    SVEngineContext *pCtxt;

    VDE_MSG((_T("[VDE] ++%s()\r\n"), _T(__FUNCTION__)));

    pCtxt = SVE_get_context();

    // Open Device Power Control Driver
    pCtxt->hPowerControl = CreateFile( L"PWC0:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
    if (pCtxt->hPowerControl == INVALID_HANDLE_VALUE)
    {
        VDE_ERR((_T("[VDE:ERR] %s() : PWC0 Open Device Failed\r\n"), _T(__FUNCTION__)));
        goto CleanUp;
    }

    VDE_MSG((_T("[VDE] --%s()\r\n"), _T(__FUNCTION__)));

    return TRUE;

CleanUp:

    VDE_ERR((_T("[VDE:ERR] --%s() : Failed\r\n"), _T(__FUNCTION__)));

    return FALSE;
}

void SVE_deinitialize_power_control(void)
{
    SVEngineContext *pCtxt;

    VDE_MSG((_T("[VDE] ++SVE_deinitialize_power_control()\r\n")));

    pCtxt = SVE_get_context();

    if (pCtxt->hPowerControl !=INVALID_HANDLE_VALUE)
    {
        CloseHandle(pCtxt->hPowerControl);
    }

    VDE_MSG((_T("[VDE] ++SVE_deinitialize_power_control()\r\n")));
}

BOOL SVE_hw_clock_control(HWCLK_GATING eParams)
{
    SVEngineContext *pCtxt;
    DWORD dwIPIndex = 0, dwBytes = 0;
    BOOL bRet = TRUE;

    VDE_MSG((_T("[VDE] ++%s(%d)\r\n"), _T(__FUNCTION__), eParams));

    pCtxt = SVE_get_context();
    switch(eParams)
    {
    case HWCLK_ALL_ON:
        dwIPIndex = CLK_IP1_FIMD;    // Clock On Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        dwIPIndex = CLK_IP0_ROTATOR;    // Clock On Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_ALL_OFF:
        dwIPIndex = CLK_IP1_FIMD;    // Clock Off Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        dwIPIndex = CLK_IP0_ROTATOR;    // Clock Off Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_DISPLAY_ON:
        dwIPIndex = CLK_IP1_FIMD;    // Clock On Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_DISPLAY_OFF:
        dwIPIndex = CLK_IP1_FIMD;    // Clock Off Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_ROTATOR_ON:
        dwIPIndex = CLK_IP0_ROTATOR;    // Clock On Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_ROTATOR_OFF:
        dwIPIndex = CLK_IP0_ROTATOR;    // Clock Off Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_2D_ON:
        dwIPIndex = CLK_IP0_G2D;    // Clock On 2D
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_2D_OFF:
        dwIPIndex = CLK_IP0_G2D;    // Clock Off 2D
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_MIPI_DSI_ON:
        dwIPIndex = CLK_IP1_DSIM;
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWCLK_MIPI_DSI_OFF:
        dwIPIndex = CLK_IP1_DSIM;
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_CLOCK_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
    break;

    default:
        VDE_ERR((_T("[VDE:ERR] SVE_hw_clock_control() : Unknown Parameter = %d\n\r"), eParams));
        bRet = FALSE;
        break;
    }
    VDE_MSG((_T("[VDE] --%s()\n\r"), _T(__FUNCTION__)));

    return bRet;
}

BOOL SVE_hw_power_control(HWPWR_GATING eParams)
{
    SVEngineContext *pCtxt;
    DWORD dwIPIndex = 0, dwBytes = 0;
    BOOL bRet = TRUE;

    VDE_MSG((_T("[VDE] ++%s(%d)\r\n"), _T(__FUNCTION__), eParams));

    pCtxt = SVE_get_context();

    switch(eParams)
    {
    case HWPWR_ALL_ON:
        dwIPIndex = PWR_IP_DISPCON;    // Power On Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }

        dwIPIndex = PWR_IP_ROTATOR;    // Power On Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;
    case HWPWR_ALL_OFF:
        dwIPIndex = PWR_IP_DISPCON;    // Power Off Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }

        dwIPIndex = PWR_IP_ROTATOR;    // Power Off Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;
    case HWPWR_DISPLAY_ON:
        dwIPIndex = PWR_IP_DISPCON;    // Power On Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_DISPLAY_OFF:
        dwIPIndex = PWR_IP_DISPCON;    // Power Off Display Controller
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_ROTATOR_ON:
        dwIPIndex = PWR_IP_ROTATOR;    // Power On Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_ROTATOR_OFF:
        dwIPIndex = PWR_IP_ROTATOR;    // Power Off Image Rotator
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_2D_ON:
        dwIPIndex = PWR_IP_G2D;        // Power On FIMG 2D
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_2D_OFF:
        dwIPIndex = PWR_IP_G2D;        // Power Off FIMG 2D
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_MIPI_DSI_DPHY_ON:	       // Power On MIPI DSI DPHY
        dwIPIndex = PWR_IP_MIPI_DSI_DPHY;
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_ON, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
        break;

    case HWPWR_MIPI_DSI_DPHY_OFF:	   // Power Off MIPI DSI DPHY
        dwIPIndex = PWR_IP_MIPI_DSI_DPHY;
        if ( !DeviceIoControl(pCtxt->hPowerControl, IOCTL_PWRCON_SET_POWER_OFF, &dwIPIndex, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
        {
            bRet = FALSE;
        }
    break;

    default:
        VDE_ERR( (_T("[VDE:ERR] %s() : Unknown Parameter = %d\n\r"), _T(__FUNCTION__), eParams));
        bRet = FALSE;
        break;
    }

    VDE_MSG((_T("[VDE] --%s() IP Index=%d, return=%d\n\r"), _T(__FUNCTION__), dwIPIndex, bRet));

    return bRet;
}

