📄 hwinit.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft
// premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license
// agreement, you are not authorized to use this source code.
// For the terms of the license, please see the license agreement
// signed by you and Microsoft.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//------------------------------------------------------------------------------
//
// 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: hwinit.c
* Purpose: Platform-specific host driver initialisation and configuration
* Pin muxing
* CPLD configuration
* transceiver, wakeup, Vbus configuration
*
* Functions: BSPUsbhCheckConfigPower - verify power available for devices
* BSPUsbSetWakeUp - setup wakeup sources for host port
* InitializeTransceiver - any setup required for attached transceiver
* SetPHYPowerMgmt - suspend or resume the transceiver
*/
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "mx27_usb.h"
#include "mx27_usbname.h"
#include "mx27_usbcommon.h"
//-----------------------------------------------------------------------------
// External Functions
//-----------------------------------------------------------------------------
extern BOOL Initialize1105();
extern BOOL Initialize1301(CSP_USB_REGS * regs);
extern BOOL Initialize1504(CSP_USB_REGS * regs, WORD sel);
#ifdef DEBUG
extern void DumpULPIRegs(PCSP_USB_REGS pRegs, WORD sel);
#endif
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
// ISP1105: Full Speed Host 1
// ISP1504: High Speed OTG
// ISP1301: Full Speed OTG
// ISP1504: High Speed Host 2
#define HIGH_SPEED 1
#define FULL_SPEED 2
#define QUEUE_HEAD_SIZE 0x200
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
PCSP_USB_REGS gpRegs;
WORD gSel;
volatile UINT32 *gQueueHead;
TCHAR gszOTGGroup[30];
DWORD gdwOTGSupport;
//-----------------------------------------------------------------------------
// Local Variables
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
BOOL BSPUsbCheckWakeUp(void);
void SetULPIHostMode(PCSP_USB_REGS pRegs, WORD pSel, BOOL fSuspend);
//-----------------------------------------------------------------------------
//
// Function: SetPHYPowerMgmt
//
// This function is to configure the ULPI to suspend or resume mode.
//
// Parameters:
// fSuspend - TRUE : Suspend request, FALSE : Resume request
//
// Returns:
// NULL
//
//-----------------------------------------------------------------------------
void SetPHYPowerMgmt(BOOL fSuspend)
{
DEBUGMSG(1, (TEXT("+SetPHYPowerMgmt for the H2 \r\n")));
// 2 is OTG while 0 is H2
if ((gSel != USB_SEL_OTG) && (gSel != USB_SEL_H2))
return;
SetULPIHostMode(gpRegs, gSel, fSuspend);
DEBUGMSG(1, (TEXT("-SetPHYPowerMgmt\r\n")));
return;
}
//-----------------------------------------------------------------------------
//
// Function: InitializeOTGMux
//
// This function is to configure the IOMUX for USB OTG Core
//
// Parameters:
// NULL
//
// Returns:
// NULL
//
//-----------------------------------------------------------------------------
static void InitializeOTGMux()
{
DDK_GPIO_CFG cfgE, cfgC, cfgB;
DDK_GPIO_SET_CONFIG(cfgE, USBOTG_E );
DEBUGMSG(1, (TEXT("USBOTG_E cfgE.ConfigType 0x%x\r\n"),cfgE.ConfigType));
DEBUGMSG(1, (TEXT("USBOTG_E cfgE.PriConfig.Port 0x%x\r\n"),cfgE.PriConfig.Port ));
DEBUGMSG(1, (TEXT("USBOTG_E cfgE.PriConfig.PinMap 0x%x\r\n"),cfgE.PriConfig.PinMap ));
DEBUGMSG(1, (TEXT("USBOTG_E cfgE.PriConfig.PuenMap 0x%x\r\n"),cfgE.PriConfig.PuenMap ));
DDK_GPIO_SET_CONFIG(cfgC, USBOTG_C);
DEBUGMSG(1, (TEXT("USBOTG_C cfgC.ConfigType 0x%x\r\n"),cfgC.ConfigType));
DEBUGMSG(1, (TEXT("USBOTG_C cfgC.PriConfig.Port 0x%x\r\n"),cfgC.PriConfig.Port ));
DEBUGMSG(1, (TEXT("USBOTG_C cfgC.PriConfig.PinMap 0x%x\r\n"),cfgC.PriConfig.PinMap ));
DEBUGMSG(1, (TEXT("USBOTG_C cfgC.PriConfig.PuenMap 0x%x\r\n"),cfgC.PriConfig.PuenMap ));
DDK_GPIO_SET_CONFIG(cfgB, USBOTG_B);
DEBUGMSG(1, (TEXT("USBOTG_B cfgB.ConfigType 0x%x\r\n"),cfgB.ConfigType));
DEBUGMSG(1, (TEXT("USBOTG_B cfgB.PriConfig.Port 0x%x\r\n"),cfgB.PriConfig.Port ));
DEBUGMSG(1, (TEXT("USBOTG_B cfgB.PriConfig.PinMap 0x%x\r\n"),cfgB.PriConfig.PinMap ));
DEBUGMSG(1, (TEXT("USBOTG_B cfgB.PriConfig.PuenMap 0x%x\r\n"),cfgB.PriConfig.PuenMap ));
DDKGpioEnable(&cfgE);
DDKGpioEnable(&cfgC);
DDKGpioEnable(&cfgB);
return;
}
//-----------------------------------------------------------------------------
//
// Function: InitializeHost1Mux
//
// This function is to configure the IOMUX for USB H1 Core
//
// Parameters:
// NULL
//
// Returns:
// NULL
//
//-----------------------------------------------------------------------------
static void InitializeHost1Mux()
{
DDK_GPIO_CFG cfg;
DEBUGMSG(1, (TEXT("InitializeHostF1Mux\r\n")));
DDK_GPIO_SET_CONFIG(cfg, USBF1_B);
DEBUGMSG(1, (TEXT("USBF1_B cfg.ConfigType 0x%x\r\n"),cfg.ConfigType));
DEBUGMSG(1, (TEXT("USBF1_B cfg.PriConfig.Port 0x%x\r\n"),cfg.PriConfig.Port ));
DEBUGMSG(1, (TEXT("USBF1_B cfg.PriConfig.PinMap 0x%x\r\n"),cfg.PriConfig.PinMap ));
DEBUGMSG(1, (TEXT("USBF1_B cfg.PriConfig.PuenMap 0x%x\r\n"),cfg.PriConfig.PuenMap ));
DDKGpioEnable(&cfg);
}
//-----------------------------------------------------------------------------
//
// Function: InitializeHost2Mux
//
// This function is to configure the IOMUX for USB H2 Core
//
// Parameters:
// NULL
//
// Returns:
// NULL
//
//-----------------------------------------------------------------------------
static void InitializeHost2Mux()
{
GPIO_PORT port;
PHYSICAL_ADDRESS phyAddr;
PCSP_GPIO_REGS pGPIO;
phyAddr.QuadPart = CSP_BASE_REG_PA_GPIO;
// Map peripheral physical address to virtual address
pGPIO = (PCSP_GPIO_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_GPIO_REGS),
FALSE);
// Check if virtual mapping failed
if (pGPIO == NULL) {
DEBUGMSG(1, (_T("GpioAlloc: MmMapIoSpace failed!\r\n")));
goto CleanUp;
}
port = GPIO_PORT_A;
pGPIO->PORT[port].GIUS &= ~GPIO_USBH2_A_MASK;
pGPIO->PORT[port].GPR &= ~GPIO_USBH2_A_MASK;
// Ensure only selected pins PUEN are changed
pGPIO->PORT[port].PUEN = ~GPIO_USBH2_A_MASK;
DEBUGMSG(1, (TEXT("USBH2_D cfgD.PriConfig.Port 0x%x\r\n"),port ));
DEBUGMSG(1, (TEXT("USBH2_D g_pGPIO->PORT[A].GIUS 0x%x\r\n"),pGPIO->PORT[port].GIUS ));
DEBUGMSG(1, (TEXT("USBH2_D g_pGPIO->PORT[A].GPR 0x%x\r\n"),pGPIO->PORT[port].GPR ));
port = GPIO_PORT_D;
pGPIO->PORT[port].GIUS &= ~GPIO_USBH2_D_MASK;
pGPIO->PORT[port].GPR |= GPIO_USBH2_D_MASK;
// Ensure only selected pins PUEN are changed
pGPIO->PORT[port].PUEN = ~GPIO_USBH2_D_MASK;
DEBUGMSG(1, (TEXT("USBH2_D cfgD.PriConfig.Port 0x%x\r\n"),port ));
DEBUGMSG(1, (TEXT("USBH2_D g_pGPIO->PORT[D].GIUS 0x%x\r\n"),pGPIO->PORT[port].GIUS ));
DEBUGMSG(1, (TEXT("USBH2_D g_pGPIO->PORT[D].GPR 0x%x\r\n"),pGPIO->PORT[port].GPR ));
CleanUp:
return;
}
//-----------------------------------------------------------------------------
//
// Function: InitializeMux
//
// This function is to configure the IOMUX for USB Host Cores
//
// Parameters:
// sel - Selection of the USB cores (0 - H2, 1 - H1, 2- OTG)
//
// Returns:
// offset of the USB core register to be configured.
//
//-----------------------------------------------------------------------------
static DWORD InitializeMux(int sel)
{
DWORD off=offset(CSP_USB_REGS, H2)+offset(CSP_USB_REG, CAPLENGTH);
DEBUGMSG(1, (TEXT("USBH2 InitializeMux with sel=%d \r\n"), sel));
if (sel == USB_SEL_OTG) { // OTG
InitializeOTGMux();
off=offset(CSP_USB_REG, CAPLENGTH);
}
else if (sel == USB_SEL_H1){ // Host 1
off=offset(CSP_USB_REGS, H1)+offset(CSP_USB_REG, CAPLENGTH);
InitializeHost1Mux();
}
else if (sel == USB_SEL_H2){ // H2
DEBUGMSG(1, (TEXT("InitializeHost2Mux with sel=%d \r\n"), sel));
off = offset(CSP_USB_REGS, H2) + offset(CSP_USB_REG, CAPLENGTH);
InitializeHost2Mux();
}
return off;
}
//-----------------------------------------------------------------------------
//
// Function: dumpCPLD
//
// This function is to dump the CPLD information
//
// Parameters:
// cpld - Pointer to Mapped CPLD Register
//
// Returns:
// None
//
//-----------------------------------------------------------------------------
#ifdef DEBUG
void dumpCPLD(PCSP_PBC_REGS cpld)
{
DEBUGMSG(1,(L"Dump PBC registers:\r\n"));
DEBUGMSG(1,(L"\tVERSION=%x\r\n", INREG16(&cpld->VERSION)));
// DEBUGMSG(1,(L"\tBSTAT2=%x\r\n", INREG16(&cpld->BSTAT2)));
DEBUGMSG(1,(L"\tBCTRL1_SET=%x\r\n", INREG16(&cpld->BCTRL1_SET)));
DEBUGMSG(1,(L"\tBCTRL1_CLEAR=%x\r\n", INREG16(&cpld->BCTRL1_CLEAR)));
DEBUGMSG(1,(L"\tBCTRL2_SET=%x\r\n", INREG16(&cpld->BCTRL2_SET)));
DEBUGMSG(1,(L"\tBCTRL2_CLEAR=%x\r\n", INREG16(&cpld->BCTRL2_CLEAR)));
DEBUGMSG(1,(L"\tBCTRL3_SET=%x\r\n", INREG16(&cpld->BCTRL3_SET)));
DEBUGMSG(1,(L"\tBCTRL3_CLEAR=%x\r\n", INREG16(&cpld->BCTRL3_CLEAR)));
DEBUGMSG(1,(L"\tBCTRL4_SET=%x\r\n", INREG16(&cpld->BCTRL4_SET)));
DEBUGMSG(1,(L"\tBCTRL4_CLEAR=%x\r\n", INREG16(&cpld->BCTRL4_CLEAR)));
DEBUGMSG(1,(L"\tBSTAT1=%x\r\n", INREG16(&cpld->BSTAT1)));
DEBUGMSG(1,(L"\tINT_STATUS=%x\r\n", INREG16(&cpld->INT_STATUS)));
DEBUGMSG(1,(L"\tINT_CUR_STATUS=%x\r\n", INREG16(&cpld->INT_CUR_STATUS)));
DEBUGMSG(1,(L"\tINT_MASK_SET=%x\r\n", INREG16(&cpld->INT_MASK_SET)));
DEBUGMSG(1,(L"\tINT_MASK_CLEAR=%x\r\n", INREG16(&cpld->INT_MASK_CLEAR)));
}
#endif
//-----------------------------------------------------------------------------
//
// Function: InitializeCPLD
//
// This function is to configure the CPLD to corresponding USB core
//
// Parameters:
// sel - the value in which USB core to configure.
//
// Returns:
// Speed of the USB core - HIGH_SPEED or FULL_SPEED
//
//-----------------------------------------------------------------------------
static int InitializeCPLD(WORD * sel)
{
#ifndef FREESCALE_MODIFY_B4_SHIP_REMOVE_PBC
PCSP_PBC_REGS cpld;
PHYSICAL_ADDRESS phyAddr;
#endif
int r;
#ifndef FREESCALE_MODIFY_B4_SHIP_REMOVE_PBC
phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE;
cpld = (PCSP_PBC_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_PBC_REGS), FALSE);
if (cpld == NULL)
{
DEBUGMSG(1,(TEXT("%s(): MmMapIoSpace failed!\r\n"), __WFUNCTION__));
return FALSE;
}
else
{
DEBUGMSG(1, (TEXT("USB FS host MmMapIoSpace is cpld 0x%x\r\n"),cpld));
}
#endif
#if (USB_HOST_MODE==0)||(USB_HOST_MODE==1)
// OTG port, be sure to turn off the USB function driver.
*sel=USB_SEL_OTG;
#ifndef FREESCALE_MODIFY_B4_SHIP_REMOVE_PBC
OUTREG16(&cpld->BCTRL3_CLEAR,(1<<PBC_BCTRL3_OTG_VBUS_EN_LSH));
#endif
#if (USB_HOST_MODE==0) //OTG Full Speed - ISP1301
r=FULL_SPEED;
#else //OTG High Speed - ISP1504
#ifndef FREESCALE_MODIFY_B4_SHIP_REMOVE_PBC
DEBUGMSG(1, (L"PBC_BCTRL3_OTG_HS_EN_LSH ....\r\n"));
OUTREG16(&cpld->BCTRL3_CLEAR,(1<<PBC_BCTRL3_OTG_HS_EN_LSH));
#endif
r=HIGH_SPEED;
DEBUGMSG(1, (L"High Speed USB OTG Host\r\n"));
#endif
#else
#if (USB_HOST_MODE!=4)
{
DEBUGMSG(1, (L"Full speed USB host\r\n"));
#ifndef FREESCALE_MODIFY_B4_SHIP_REMOVE_PBC
DEBUGMSG(TRUE, (TEXT("BCTRL3, set 12, clear 9, 6\r\n")));
OUTREG16(&cpld->BCTRL3_CLEAR, (1<<PBC_BCTRL3_USB_FSH_ON_LSH));
OUTREG16(&cpld->BCTRL3_SET, (1<<PBC_BCTRL3_USB_FSH_ON_LSH)); //bit 12: USB_FSH_EN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -