⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddk_clk.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
字号:
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-2006, 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:  ddk_clk.c
//
//  This file contains the CCM DDK interface that is used by applications and
//  other drivers to access the capabilities of the CCM driver.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include "bsp.h"

//-----------------------------------------------------------------------------
// External Functions


//-----------------------------------------------------------------------------
// External Variables
extern PCSP_CCM_REGS g_pCCM;
extern HANDLE g_hDdkClkMutex;

//-----------------------------------------------------------------------------
// Defines

#if BSP_SDMA_SUPPORT_ATA
#define CGR0_ATA_MASK               CCM_CGR0_ATA_MASK
#else
#define CGR0_ATA_MASK               0
#endif


#if BSP_SDMA_SUPPORT_SSI1
#ifdef BSP_AUDIO_DMA_BUF_ADDR
#if (BSP_AUDIO_DMA_BUF_ADDR == IMAGE_SHARE_IRAM_AUDIO_PA_START)
#define CGR0_SSI1_MASK              0
#else
#define CGR0_SSI1_MASK              CCM_CGR0_SSI1_MASK
#endif // BSP_AUDIO_DMA_BUF_ADDR == IMAGE_SHARE_IRAM_AUDIO_PA_START
#else
#define CGR0_SSI1_MASK              CCM_CGR0_SSI1_MASK
#endif // BSP_AUDIO_DMA_BUF_ADDR
#else
#define CGR0_SSI1_MASK              0
#endif // BSP_SDMA_SUPPORT_SSI1

#if BSP_SDMA_SUPPORT_SSI2
#ifdef BSP_AUDIO_DMA_BUF_ADDR
#if (BSP_AUDIO_DMA_BUF_ADDR == IMAGE_SHARE_IRAM_AUDIO_PA_START)
#define CGR2_SSI2_MASK              0
#else
#define CGR2_SSI2_MASK              CCM_CGR2_SSI2_MASK
#endif // BSP_AUDIO_DMA_BUF_ADDR == IMAGE_SHARE_IRAM_AUDIO_PA_START
#else
#define CGR2_SSI2_MASK              CCM_CGR2_SSI2_MASK
#endif // BSP_AUDIO_DMA_BUF_ADDR
#else
#define CGR2_SSI2_MASK              0
#endif // BSP_SDMA_SUPPORT_SSI1

#if BSP_SDMA_SUPPORT_SDHC1
#define CGR0_SDHC1_MASK             CCM_CGR0_SDHC1_MASK
#else
#define CGR0_SDHC1_MASK             0
#endif

#if BSP_SDMA_SUPPORT_SDHC2
#define CGR0_SDHC2_MASK             CCM_CGR0_SDHC2_MASK
#else
#define CGR0_SDHC2_MASK             0
#endif

#if BSP_SDMA_SUPPORT_CSPI1
#define CGR2_CSPI1_MASK             CCM_CGR2_CSPI1_MASK
#else
#define CGR2_CSPI1_MASK             0
#endif

#if BSP_SDMA_SUPPORT_CSPI2
#define CGR2_CSPI2_MASK             CCM_CGR2_CSPI2_MASK
#else
#define CGR2_CSPI2_MASK             0
#endif

#if BSP_SDMA_SUPPORT_CSPI3
#define CGR0_CSPI3_MASK             CCM_CGR0_CSPI3_MASK
#else
#define CGR0_CSPI3_MASK             0
#endif

#if BSP_SDMA_SUPPORT_UART1
#define CGR0_UART1_MASK             CCM_CGR0_UART1_MASK
#else
#define CGR0_UART1_MASK             0
#endif

#if BSP_SDMA_SUPPORT_UART2
#define CGR0_UART2_MASK             CCM_CGR0_UART2_MASK
#else
#define CGR0_UART2_MASK             0
#endif

#if BSP_SDMA_SUPPORT_UART3
#define CGR1_UART3_MASK             CCM_CGR1_UART3_MASK
#else
#define CGR1_UART3_MASK             0
#endif

#if BSP_SDMA_SUPPORT_UART4
#define CGR1_UART4_MASK             CCM_CGR1_UART4_MASK
#else
#define CGR1_UART4_MASK             0
#endif

#if BSP_SDMA_SUPPORT_UART5
#define CGR1_UART5_MASK             CCM_CGR1_UART5_MASK
#else
#define CGR1_UART5_MASK             0
#endif

#if BSP_SDMA_SUPPORT_FIRI
#define CGR2_FIRI_MASK              CCM_CGR2_FIRI_MASK
#else
#define CGR2_FIRI_MASK              0
#endif

#if BSP_SDMA_SUPPORT_SIM
#define CGR1_SIM_MASK               CCM_CGR1_SIM_MASK
#else
#define CGR1_SIM_MASK               0
#endif

#define CCM_EMI_CGR0_MASK           (CGR0_ATA_MASK |  \
                                    CGR0_SSI1_MASK |  \
                                    CGR0_SDHC1_MASK |  \
                                    CGR0_SDHC2_MASK |  \
                                    CGR0_CSPI3_MASK |  \
                                    CGR0_UART1_MASK |  \
                                    CGR0_UART2_MASK)

#define CCM_EMI_CGR1_MASK           (CCM_CGR1_MPEG4_MASK |  \
                                    CCM_CGR1_USBOTG_MASK |  \
                                    CCM_CGR1_IPU_MASK |  \
                                    CGR1_UART3_MASK |  \
                                    CGR1_UART4_MASK |  \
                                    CGR1_UART5_MASK |  \
                                    CGR1_SIM_MASK)
                                    
#define CCM_EMI_CGR2_MASK           (CCM_CGR2_RTIC_MASK |  \
                                    CGR2_SSI2_MASK |  \
                                    CGR2_CSPI1_MASK |  \
                                    CGR2_CSPI2_MASK |  \
                                    CGR2_FIRI_MASK | \
                                    CCM_CGR2_NFC_MASK) 

#define CCM_CGR2_EMI_LSH            CCM_CGR_SHIFT(DDK_CLOCK_GATE_INDEX_EMI)

//-----------------------------------------------------------------------------
// Types


//-----------------------------------------------------------------------------
// Global Variables


//-----------------------------------------------------------------------------
// Local Variables
static BSP_ARGS *g_pBspArgs = NULL;

//-----------------------------------------------------------------------------
// Local Functions


//-----------------------------------------------------------------------------
//
// Function:  BSPClockDealloc
//
// This function deallocates the data structures required for interaction
// with the clock configuration hardware.
//
// Parameters:
//      None.
//
// Returns:
//      Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL BSPClockDealloc(void)
{
    // Unmap peripheral address space
    if (g_pBspArgs == NULL)
    {
        MmUnmapIoSpace(g_pBspArgs, sizeof(BSP_ARGS));
        g_pBspArgs = NULL;
    }

    return TRUE;
    
}


//-----------------------------------------------------------------------------
//
// Function:  BSPClockAlloc
//
// This function allocates the data structures required for interaction
// with the clock configuration hardware.
//
// Parameters:
//      None.
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPClockAlloc(void)
{
    BOOL rc = FALSE;
    PHYSICAL_ADDRESS phyAddr;
         
    if (g_pBspArgs == NULL)
    {
        phyAddr.QuadPart = IMAGE_BOOT_RAM_PA_START;

        // Map peripheral physical address to virtual address
        g_pBspArgs = (BSP_ARGS *) MmMapIoSpace(phyAddr, sizeof(BSP_ARGS),
            FALSE);

        // Check if virtual mapping failed
        if (g_pBspArgs == NULL)
        {
            DBGCHK((_T("CSPDDK")),  FALSE);
            ERRORMSG(1, (_T("BSPClockAlloc:  MmMapIoSpace failed!\r\n")));
            goto cleanUp;
        }

    }

    rc = TRUE;
     
cleanUp:

    if (!rc) BSPClockDealloc();

    return rc;
    
}


//-----------------------------------------------------------------------------
//
// Function: BSPClockGetFreq
//
// Retrieves the clock frequency in Hz for the specified clock signal.
//
// Parameters:
//      sig
//           [in] Clock signal.
//
//      freq
//           [out] Current frequency in Hz.
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPClockGetFreq(DDK_CLOCK_SIGNAL sig, UINT32 *freq)
{
    *freq = g_pBspArgs->clockFreq[sig];

    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: BSPClockUpdateFreq
//
// Updates the clock frequency in Hz for the specified clock signal.
//
// Parameters:
//      sig
//           [in] Clock signal.
//      src
//          [in] Selects the input clock source.
//
//      preDiv
//          [in] Specifies the value programmed into the baud clock predivider.
//
//      postDiv
//          [in] Specifies the value programmed into the baud clock postdivider.
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPClockUpdateFreq(DDK_CLOCK_SIGNAL sig, DDK_CLOCK_BAUD_SOURCE src, 
    UINT32 preDiv, UINT32 postDiv)
{
    BOOL rc = FALSE;
    
    UINT32 srcFreq;

    switch (src)
    {
    case DDK_CLOCK_BAUD_SOURCE_MCUPLL:
        srcFreq = g_pBspArgs->clockFreq[DDK_CLOCK_SIGNAL_MCUPLL];
        break;

    case DDK_CLOCK_BAUD_SOURCE_USBPLL:
        srcFreq = g_pBspArgs->clockFreq[DDK_CLOCK_SIGNAL_USBPLL];
        break;

    case DDK_CLOCK_BAUD_SOURCE_SERPLL:
        srcFreq = g_pBspArgs->clockFreq[DDK_CLOCK_SIGNAL_SERPLL];
        break;
    }

    g_pBspArgs->clockFreq[sig] = srcFreq / ((preDiv+1) * (postDiv+1));

    return rc;
}


//-----------------------------------------------------------------------------
//
// Function: BSPClockIncrPanicRequests
//
// Increments a shared global that keeps track of the number of panic
// mode requests made by drivers/modules on the system.
//
// Parameters:
//      None.
//
// Returns:
//      Returns the current number of panic requests resulting from
//      incrementing the shared global.
//
//-----------------------------------------------------------------------------
UINT32 BSPClockIncrPanicRequests(void)
{
    return ++(g_pBspArgs->panicRequests);
}


//-----------------------------------------------------------------------------
//
// Function: BSPClockDecrPanicRequests
//
// Decrements a shared global that keeps track of the number of panic
// mode requests made by drivers/modules on the system.
//
// Parameters:
//      None.
//
// Returns:
//      Returns the current number of panic requests resulting from
//      decrementing the shared global.
//
//-----------------------------------------------------------------------------
UINT32 BSPClockDecrPanicRequests(void)
{
    if (g_pBspArgs->panicRequests) --g_pBspArgs->panicRequests;
        
    return g_pBspArgs->panicRequests;
}


//-----------------------------------------------------------------------------
//
// Function: BSPClockSetEmiGatingMode
//
// Allows platform-specific control over EMI clock gating.
//
// Parameters:
//      index
//           [in] Index for referencing the peripheral clock gating control 
//           bits.
//
//      mode
//           [in] Requested clock gating mode for the peripheral.
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL BSPClockSetEmiGatingMode(DDK_CLOCK_GATE_INDEX index, DDK_CLOCK_GATE_MODE mode)
{
    DDK_CLOCK_GATE_MODE emiMode;
    UINT32 cgrOld, cgrNew;
        
    // Default EMI to clock gate while ARM is in wait mode.  This will be
    // overriden below if any EMI dependants need the EMI to remain active.
    emiMode = DDK_CLOCK_GATE_MODE_ENABLED_RUN;
    
    // If this is a clock signal belongs to a module that
    // depends on EMI clocks
    switch (index)
    {
    // If this is EMI bus master (except SDMA)
    case DDK_CLOCK_GATE_INDEX_RTIC:
    case DDK_CLOCK_GATE_INDEX_USBOTG:
    case DDK_CLOCK_GATE_INDEX_MPEG4:
    case DDK_CLOCK_GATE_INDEX_IPU:
    case DDK_CLOCK_GATE_INDEX_NFC:
    case DDK_CLOCK_GATE_INDEX_GACC:

    // If this is a peripheral that uses SDMA accesses to EMI
#if CGR0_ATA_MASK
    case DDK_CLOCK_GATE_INDEX_ATA:
#endif

#if CGR0_SSI1_MASK
    case DDK_CLOCK_GATE_INDEX_SSI1:
#endif

#if CGR0_SDHC1_MASK
    case DDK_CLOCK_GATE_INDEX_SDHC1:
#endif

#if CGR0_SDHC2_MASK
    case DDK_CLOCK_GATE_INDEX_SDHC2:
#endif

#if CGR0_CSPI3_MASK
    case DDK_CLOCK_GATE_INDEX_CSPI3:
#endif

#if CGR0_UART1_MASK
    case DDK_CLOCK_GATE_INDEX_UART1:
#endif

#if CGR0_UART2_MASK
    case DDK_CLOCK_GATE_INDEX_UART2:
#endif

#if CGR1_UART3_MASK
    case DDK_CLOCK_GATE_INDEX_UART3:
#endif

#if CGR1_UART4_MASK
    case DDK_CLOCK_GATE_INDEX_UART4:
#endif

#if CGR1_UART5_MASK
    case DDK_CLOCK_GATE_INDEX_UART5:
#endif

#if CGR1_SIM_MASK
    case DDK_CLOCK_GATE_INDEX_SIM:
#endif

#if CGR2_SSI2_MASK
    case DDK_CLOCK_GATE_INDEX_SSI2:
#endif

#if CGR2_CSPI1_MASK
    case DDK_CLOCK_GATE_INDEX_CSPI1:
#endif

#if CGR2_CSPI2_MASK
    case DDK_CLOCK_GATE_INDEX_CSPI2:
#endif

#if CGR2_FIRI_MASK
    case DDK_CLOCK_GATE_INDEX_FIRI:
#endif

        // Grab mutex before attempting to scan EMI dependants
        WaitForSingleObject(g_hDdkClkMutex, INFINITE);
        
        // If we are enabling any clock source dependent upon 
        // EMI, then we must keep EMI active
        if (mode != DDK_CLOCK_GATE_MODE_DISABLED)
        {
            emiMode = DDK_CLOCK_GATE_MODE_ENABLED_ALL;
        }

        // Else we are disabling one of the clock sources dependent
        // upon EMI.  Scan through all other EMI dependants and see
        // if we can clock gate the EMI when the ARM is in wait mode.
        else
        {
            // If any of the EMI dependants are active, we must
            // keep EMI active
            if ((INREG32(&g_pCCM->CGR[0]) & CCM_EMI_CGR0_MASK) ||
                (INREG32(&g_pCCM->CGR[1]) & CCM_EMI_CGR1_MASK) || 
                (INREG32(&g_pCCM->CGR[2]) & CCM_EMI_CGR2_MASK))
            {
                emiMode = DDK_CLOCK_GATE_MODE_ENABLED_ALL;
            }            
        }


        // If EMI clock gating needs to be updated
        if (EXTREG32(&g_pCCM->CGR[2], CCM_CGR2_EMI_MASK, CCM_CGR2_EMI_LSH) 
            != emiMode)
        {

            // Update EMI clock gating using interlocked API since CGR
            // accesses are not protected by g_hDdkClkMutex
            do
            {
                cgrOld = INREG32(&g_pCCM->CGR[2]);
                cgrNew = (cgrOld & (~CCM_CGR2_EMI_MASK)) | 
                    (emiMode << CCM_CGR2_EMI_LSH);
            } while (InterlockedTestExchange(&g_pCCM->CGR[2], 
                               cgrOld, cgrNew) != cgrOld);        

            // DEBUGMSG(TRUE, (_T("EMI CGR = %d\r\n"), emiMode));
            // DEBUGMSG(TRUE, (_T("CGR[0] = 0x%x\r\n"), INREG32(&g_pCCM->CGR[0])));
            // DEBUGMSG(TRUE, (_T("CGR[1] = 0x%x\r\n"), INREG32(&g_pCCM->CGR[1])));
            // DEBUGMSG(TRUE, (_T("CGR[2] = 0x%x\r\n"), INREG32(&g_pCCM->CGR[2])));
            
        }
                    
        ReleaseMutex(g_hDdkClkMutex);

    }

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -