📄 usbclock.c
字号:
/*---------------------------------------------------------------------------
* Copyright (C) 2005-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: USBClock.c
// Purpose: Maintains shared access to USB peripheral block clock gating
// Functions: USBClockDisable(BOOL fEnabled) - either enable or disable the
// the USB clock, for this user. Only if no other user requires
// the clock will it actually be gated off.
//
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "mx31_usbname.h"
HANDLE m_hUSBClockGatingHandle = NULL;
BSP_USB_CLOCK_GATING *pUSBClkGating = NULL;
BOOL BSPUSBClockDisable(BOOL fStop);
extern WORD BSPGetUSBControllerType(void);
#ifdef DEBUG
#define ZONE_FUNCTION DEBUGZONE(3)
#define ZONE_ERROR DEBUGZONE(0)
extern DBGPARAM dpCurSettings;
#endif
//-------------------------------------------------------------------------
//
// Function: USBClockSet
//
// Local function in actual stopping and enabling the USB clock
//
// Parameters:
// TRUE : Enabled, FALSE : Disable
//
// Returns:
// TRUE - operation success
// FALSE - operation failed
//
//------------------------------------------------------------------------
static BOOL USBClockSet(BOOL fEnabled)
{
BOOL rc = FALSE;
if (fEnabled)
{
if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_USBOTG, DDK_CLOCK_GATE_MODE_ENABLED_ALL))
{
DEBUGMSG (ZONE_ERROR, (L"DDKClockSetGatingMode failed\r\n"));
goto cleanUp;
}
if (!DDKClockConfigBaud(DDK_CLOCK_SIGNAL_USB, DDK_CLOCK_BAUD_SOURCE_USBPLL, 1, 1))
{
DEBUGMSG (ZONE_ERROR, (L"DDKClockConfigBaud failed\r\n"));
goto cleanUp;
}
}
else
{
if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_USBOTG, DDK_CLOCK_GATE_MODE_DISABLED))
{
DEBUGMSG (ZONE_ERROR, (L"DDKClockSetGatingMode failed\r\n"));
goto cleanUp;
}
}
rc = TRUE;
DEBUGMSG(ZONE_FUNCTION, (TEXT("USBClock %s return %d\r\n"),
(fEnabled? TEXT("TRUE"): TEXT("FALSE")), rc));
cleanUp:
return rc;
}
//-------------------------------------------------------------
//
// Function: USBClockInit
//
// Init and start the USB Core Clock
//
// Parameter: NULL
//
// Return:
// TRUE - success to start the clock
// FALSE - fail to start the clock
//
//-------------------------------------------------------------
BOOL USBClockInit(void)
{
BSPUSBClockDisable(FALSE);
return USBClockSet(TRUE);
}
//---------------------------------------------------------------
//
// Function: USBClockGatingLock
//
// Use the parameter ClockGatingLock as a critical section
// in controlling the access within the Lock/Unlock for multiple
// USB drivers
//
// Parameters:
// NULL
//
// Returns:
// NULL
//
//--------------------------------------------------------------
void USBClockGatingLock(void)
{
do
{
// Wait until lock is released
while (*((volatile UINT32 *)(&pUSBClkGating->ClockGatingLock)));
} while (InterlockedTestExchange(&pUSBClkGating->ClockGatingLock, FALSE, TRUE) != FALSE);
}
//-----------------------------------------------------------------
//
// Function: USBClockGatingUnlock
//
// Use the parameter ClockGatingLock as a critical section
// in controlling the access within the Lock/Unlock for multiple
// USB drivers
//
// Parameter:
// NULL
//
// Returns:
// NULL
//
//-----------------------------------------------------------------
void USBClockGatingUnlock(void)
{
pUSBClkGating->ClockGatingLock = FALSE;
}
//-----------------------------------------------------------------
//
// Function: BSPUSBClockCreateFileMapping
//
// This is use to create the shared memory to be used
// for controlling the stop/start of USB clock when multiple
// USB controllers are running
//
// Parameter:
// NULL
//
// Returns: NULL
//
//--------------------------------------------------------------------
BOOL BSPUSBClockCreateFileMapping(void)
{
WORD sel = BSPGetUSBControllerType();
DEBUGMSG(ZONE_FUNCTION, (TEXT("Port(%d):BSPUSBCreateFileMapping\r\n"), sel));
if (m_hUSBClockGatingHandle == NULL)
{
m_hUSBClockGatingHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, sizeof(BSP_USB_CLOCK_GATING), USBClockGatingName);
if (m_hUSBClockGatingHandle == NULL)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Failure to Create File Mapping for USB\r\n")));
return FALSE;
}
if (GetLastError() != ERROR_ALREADY_EXISTS) // you are the first one to create it
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Port(%d):First to create USB_CLOCK_GATING\r\n"), sel));
pUSBClkGating = (BSP_USB_CLOCK_GATING *) MapViewOfFile(m_hUSBClockGatingHandle,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
pUSBClkGating->ClockGatingMask = 0;
pUSBClkGating->ClockGatingLock = FALSE;
}
else
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Port(%d) Open existing USB_CLOCK_GATING\r\n"), sel));
pUSBClkGating = (BSP_USB_CLOCK_GATING *) MapViewOfFile(m_hUSBClockGatingHandle,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("Port(%d):BSPUSBClockCreateFileMapping create success\r\n"), sel));
return TRUE;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("-Port(%d):BSPUSBClockCreateFileMapping handle exist\r\n"), sel));
return TRUE;
}
//---------------------------------------------------------
//
// Function: BSPUSBClockDeleteFileMapping
//
// This is use to delete the shared memory to be used
// for controlling the stop/start of USB clock when multiple
// USB controllers are running
//
// Parameters: NULL
//
// Returns: NULL
//
//----------------------------------------------------------
void BSPUSBClockDeleteFileMapping(void)
{
if (pUSBClkGating)
{
UnmapViewOfFile(pUSBClkGating);
pUSBClkGating = NULL;
}
if (m_hUSBClockGatingHandle)
{
CloseHandle(m_hUSBClockGatingHandle);
m_hUSBClockGatingHandle = NULL;
}
}
//------------------------------------------------------
//
// Function: BSPUSBClockDisable
//
// This is use to control multiple USB controllers from accessing
// the same USB clock. ClockGatingMask is used to control 3 USB controllers
// (H1, H2 and OTG). If stop is request, it would check against the ClockGatingMask
// and make sure it is 0 before it actually stop the clock.
// On other hands, whenever a start is request, it would start right away
// ClockGatingMask - Bit 0 => H2, Bit 1 => H1, Bit 2 => OTG
//
// Parameters:
// fStop: TRUE - Stop the clock, FALSE - Start the clock
//
// Returns:
// TRUE: Success
// FALSE: FAilure
//
//--------------------------------------------------------
BOOL BSPUSBClockDisable(BOOL fStop)
{
DWORD dwMask = 0x0;
BOOL fOK = FALSE;
WORD sel = BSPGetUSBControllerType();
// Since only OTG port support client mode.
dwMask = 0x1 << sel;
BSPUSBClockCreateFileMapping();
USBClockGatingLock();
if (fStop)
{
pUSBClkGating->ClockGatingMask &= ~dwMask;
fOK = ((pUSBClkGating->ClockGatingMask == 0)? TRUE: FALSE);
if (fOK)
fOK = USBClockSet(FALSE);
}
else
{
pUSBClkGating->ClockGatingMask |= dwMask;
fOK = TRUE;
fOK = USBClockSet(TRUE);
}
USBClockGatingUnlock();
DEBUGMSG(ZONE_FUNCTION, (TEXT("Port(%d) - USBClockCanClockGating(%d), return 0x%x, value 0x%x\r\n"),
sel, fStop, fOK, pUSBClkGating->ClockGatingMask));
return fOK;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -