📄 ddk_clk.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 + -