//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-2007, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
//  File:  bspipu.c
//
//  Provides BSP-specific routines for use by the IPU.
//
//------------------------------------------------------------------------------

#pragma warning(push)
#pragma warning(disable: 4115 4201 4204 4214)
#include <windows.h>
#pragma warning(pop)

#include "bsp.h"


//------------------------------------------------------------------------------
// External Functions


//------------------------------------------------------------------------------
// External Variables


//------------------------------------------------------------------------------
// Defines 


//------------------------------------------------------------------------------
// Types


//------------------------------------------------------------------------------
// Global Variables


//------------------------------------------------------------------------------
// Local Variables
static DDK_DVFC_SETPOINT g_IpuSetpoint = DDK_DVFC_SETPOINT_LOW;
static BOOL g_bIpuClkEnable = FALSE;


//------------------------------------------------------------------------------
// Local Functions


//------------------------------------------------------------------------------
//
// Function: BSPIPUSetClockGatingMode
//
// This function calls to the CRM module to
// set the clock gating mode, turning on or off
// clocks to the IPU.
//
// Parameters:
//      dwIPUEnableMask
//          [in] Mask of IPU modules currently enabled.
//
// Returns:
//      TRUE if success.
//      FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL BSPIPUSetClockGatingMode(DWORD dwIPUEnableMask)
{
    BOOL rc = FALSE;

    // IF SDC is being enabled, HIGH setpoint is needed due to HSP_CLK 
    // constraints
    if (dwIPUEnableMask & CSP_BITFMASK(IPU_IPU_CONF_SDC_EN))
{
        // If HIGH setpoint is not currently requested
        if (g_IpuSetpoint != DDK_DVFC_SETPOINT_HIGH)
        {
            // Request and block on HIGH setpoint
            g_IpuSetpoint = DDK_DVFC_SETPOINT_HIGH;
            if (!DDKClockSetpointRequest(DDK_DVFC_SETPOINT_HIGH, TRUE))
            {
                ERRORMSG(TRUE, (_T("DDKClockSetpointRequest failed!\r\n")));
                goto cleanUp;
            }
        }
    }
    // Else, IPU module being enabled does not require HIGH setpoint
    else
    {
        // If HIGH setpoint is currently requested
        if (g_IpuSetpoint == DDK_DVFC_SETPOINT_HIGH)
    {
            // Release HIGH setpoint request
            g_IpuSetpoint = DDK_DVFC_SETPOINT_LOW;
            if (!DDKClockSetpointRelease(DDK_DVFC_SETPOINT_HIGH))
            {
                ERRORMSG(TRUE, (_T("DDKClockSetpointRelease failed!\r\n")));
                goto cleanUp;
            }
        }
    }

    // If any IPU module is enabled
    if (dwIPUEnableMask)
    {
        // If IPU clock is not currently enabled
        if (!g_bIpuClkEnable)
        {
            // Request for IPU clock to be enabled
            g_bIpuClkEnable = TRUE;
        if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IPU,
            DDK_CLOCK_GATE_MODE_ENABLED_ALL))
        {
                ERRORMSG(TRUE, (_T("DDKClockSetGatingMode failed!\r\n")));
                goto cleanUp;
            }
        }
    }
    // Else all IPU modules are disabled
    else
    {
        // If IPU clock is currently enabled
        if (g_bIpuClkEnable)
        {
            // Request for IPU clock to be disabled
            g_bIpuClkEnable = FALSE;
        if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IPU,
            DDK_CLOCK_GATE_MODE_DISABLED))
        {
                ERRORMSG(TRUE, (_T("DDKClockSetGatingMode failed!\r\n")));
                goto cleanUp;
            }
        }
    }

    rc = TRUE;

cleanUp:
    return rc;
}
