📄 hwinit.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// Copyright (c) Intrinsyc Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Intrinsyc end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// File: Hwinit.c
//
#include <windows.h>
#include <oal.h>
#include <omap2420.h>
#include <ceddkex.h>
#ifdef DEBUG
#define ZONE_ERROR DEBUGZONE(0)
#define ZONE_FUNCTION DEBUGZONE(12)
#define ZONE_INTERRUPTS DEBUGZONE(8)
#define ZONE_POWER DEBUGZONE(9)
#define ZONE_PDD DEBUGZONE(15)
#endif
#if 0
#undef DEBUGMSG
#define DEBUGMSG RETAILMSG
#define ZONE_ERROR 1
#define ZONE_FUNCTION 1
#define ZONE_INTERRUPTS 1
#define ZONE_POWER 1
#define ZONE_PDD 1
#endif
#ifdef BSP_NOOTG
#define USE_USB_DEVICE_PORT 1
#endif
BOOL InitializeHardware()
{
PHYSICAL_ADDRESS pa;
BOOL rv = TRUE;
OMAP2420_SYSC1_REGS * pSysConRegs = NULL;
OMAP2420_PRCM_REGS * pPRCMRegs = NULL;
OMAP2420_OTG_REGS * pOTGRegs = NULL;
DWORD otgSysCon1 = 0x00000000;
DWORD otgSysCon2 = 0x00000000;
DWORD regBit = 0x00000000;
DWORD cbRet = 0x00000000;
DWORD temp = 0x00000000;
DWORD mode = 0x00000000;
DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - "
L"START\r\n"));
// Note: MUX setting should be done in boot loader
////////////////////////////////////////////////////////////////////////////
// Map memory blocks for the registers we need to configure. //
////////////////////////////////////////////////////////////////////////////
// Map OTG registers
pa.QuadPart = OMAP3_SCM_REGS_PA;
pSysConRegs = (OMAP2420_SYSC1_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_SYSC1_REGS), FALSE);
if (pSysConRegs == NULL)
{
DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
L"ERROR: Could not map System Control Registers\r\n"));
rv = FALSE;
goto clean;
}
// Map Power, Reset, and Clock Manager (PRCM) Registers
pa.QuadPart = OMAP2420_PRCM_REGS_PA;
pPRCMRegs = (OMAP2420_PRCM_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_PRCM_REGS), FALSE);
if (pPRCMRegs == NULL)
{
DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
L"ERROR: Could not map PRCM Registers\r\n"));
rv = FALSE;
goto clean;
}
// Map OTG registers
pa.QuadPart = OMAP2420_OTG_REGS_PA;
if ((pOTGRegs = (OMAP2420_OTG_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_OTG_REGS), FALSE)) == NULL)
{
DEBUGMSG(ZONE_ERROR, (L"USBD InitializeHardware() - "
L"ERROR: Could not map USB OTG Registers\r\n"));
rv = FALSE;
goto clean;
}
////////////////////////////////////////////////////////////////////////
// Configure PRCM Registers //
////////////////////////////////////////////////////////////////////////
// Bit Mask used to control USBD Clocks
regBit = 0x00000001;
// Disable the USB Interface clock so we can change its speed
KernelIoControl(IOCTL_ICLK2_DIS, (VOID *)®Bit, sizeof(DWORD), NULL, 0, &cbRet);
// Configure the USB Interface Clock Speed
// Note: Clear previous value, then set new value
CLRREG32(&pPRCMRegs->ulCM_CLKSEL1_CORE, 0x0E000000);
SETREG32(&pPRCMRegs->ulCM_CLKSEL1_CORE, 0x04000000);
// Ensure that the USB Interface clock remains active when the MPU enters Idle Mode.
KernelIoControl(IOCTL_AIDLE2_DIS, (VOID *)®Bit, sizeof(DWORD), NULL, 0, &cbRet);
// Enable the USB Interface and Functional clocks
KernelIoControl(IOCTL_ICLK2_ENB, (VOID *)®Bit, sizeof(DWORD), NULL, 0, &cbRet);
KernelIoControl(IOCTL_FCLK2_ENB, (VOID *)®Bit, sizeof(DWORD), NULL, 0, &cbRet);
// Enable USB Wake-Up
SETREG32(&pPRCMRegs->ulPM_WKEN2_CORE, 0x00000001);
////////////////////////////////////////////////////////////////////////
// Display the modified PRCM Registers //
////////////////////////////////////////////////////////////////////////
DEBUGMSG(ZONE_POWER, (L"USBD InitializeHardware() - Modified PRCM Register Values:\r\n"));
DEBUGMSG(ZONE_POWER, (L" CM_ICLKEN2_CORE: 0x%08X\r\n", pPRCMRegs->ulCM_ICLKEN2_CORE));
DEBUGMSG(ZONE_POWER, (L" CM_FCLKEN2_CORE: 0x%08X\r\n", pPRCMRegs->ulCM_FCLKEN2_CORE));
DEBUGMSG(ZONE_POWER, (L" CM_CLKSEL1_CORE: 0x%08X\r\n", pPRCMRegs->ulCM_CLKSEL1_CORE));
DEBUGMSG(ZONE_POWER, (L" CM_AUTOIDLE2_CORE: 0x%08X\r\n", pPRCMRegs->ulCM_AUTOIDLE2_CORE));
DEBUGMSG(ZONE_POWER, (L" CM_PM_WKEN2_CORE: 0x%08X\r\n", pPRCMRegs->ulPM_WKEN2_CORE));
////////////////////////////////////////////////////////////////////////
// Configure OTG Registers //
////////////////////////////////////////////////////////////////////////
// Reset all USB controllers
OUTREG32(&pOTGRegs->SYSCON_1, OTG_SYSCON_1_SOFT_RESET);
// Wait for the reset to complete.
while ((INREG32(&pOTGRegs->SYSCON_1) & OTG_SYSCON_1_RESET_DONE) == 0);
otgSysCon1 = INREG32(&pOTGRegs->SYSCON_1);
// Clear USB0_TRX_MODE
otgSysCon1 &= 0xFFFCFFFF;
// Set USB0_TRX_MODE
// Note that the H4 System's two USB transceivers will only work in
// one of the three available transceiver modes. The USB OTG transceiver
// (ISP1301BS) will only work in the 3-pin bidirectional mode. The USB
// Device Transceiver will only work in the 6-pin unidirectional mode.
#ifndef BSP_NOOTG
// otgSysCon1 |= (1 << 16); // 4-pin bidirectional (VP_VM) transceiver signalling
otgSysCon1 |= (2 << 16); // 3-pin bidirectional (DAT_SE0) transceiver signalling
#else
otgSysCon1 |= (3 << 16); // 6-pin unidirectional transceiver signalling
#endif
#if USE_USB_DEVICE_PORT
// Set OTG_IDLE_EN
otgSysCon1 |= 0x00008000;
// Clear DEV_IDLE_EN
otgSysCon1 &= 0xFFFFDFFF;
#else
// Clear OTG_IDLE_EN
otgSysCon1 &= 0xFFFF7FFF;
// Set DEV_IDLE_EN
otgSysCon1 |= 0x00002000;
#endif
#ifdef BSP_NOOTG
// Set HST_IDLE_EN
otgSysCon1 |= 0x00004000;
#endif
OUTREG32(&pOTGRegs->SYSCON_1, otgSysCon1);
// Ensure USB On-The Go is enabled.
// otgSysCon2 = INREG32(&pOTGRegs->SYSCON_2);
// otgSysCon2 |= OTG_SYSCON_2_SYNCHRO;
// otgSysCon2 |= (4 << 16); // B_ASE0_BRST
// otgSysCon2 |= OTG_SYSCON_2_UHOST_EN;
#ifdef BSP_NOOTG
otgSysCon2 &= ~(OTG_SYSCON_2_OTG_EN);
otgSysCon2 |= OTG_SYSCON_2_SYNCHRO;
otgSysCon2 &= ~(OTG_SYSCON_2_OTG_MST16);
otgSysCon2 |= 0x03000000; // SRP_GPUVBUS
otgSysCon2 |= 0x00200000; // A_WAIT_VRISE
otgSysCon2 |= 0x00040000; // B_ASE0_BRST
otgSysCon2 &= ~(OTG_SYSCON_2_SRP_DPW);
otgSysCon2 &= ~(OTG_SYSCON_2_SRP_DATA);
otgSysCon2 &= ~(OTG_SYSCON_2_SRP_VBUS);
otgSysCon2 &= ~(OTG_SYSCON_2_OTG_PADEN);
otgSysCon2 &= ~(OTG_SYSCON_2_HMC_PADEN);
otgSysCon2 &= ~(OTG_SYSCON_2_UHOST_EN);
otgSysCon2 |= OTG_SYSCON_2_HMC_TLLSPEED;
otgSysCon2 &= ~(OTG_SYSCON_2_HMC_TLLATTACH);
otgSysCon2 &= 0xFFFFFFC0; // HMC_MODE
#else
otgSysCon2 |= OTG_SYSCON_2_OTG_EN;
otgSysCon2 |= OTG_SYSCON_2_SRP_DATA;
otgSysCon2 |= OTG_SYSCON_2_SRP_VBUS;
#endif
otgSysCon2 |= OTG_SYSCON_2_SRP_GPDATA;
otgSysCon2 |= OTG_SYSCON_2_SRP_GPDVBUS;
// otgSysCon2 |= (3 << 24); // SRP_GPUVBUS = 3 (During SRP generation, VBUS is charged for 2ms nominal)
// otgSysCon2 |= OTG_SYSCON_2_HMC_TLLSPEED;
OUTREG32(&pOTGRegs->SYSCON_2, otgSysCon2);
// Clear OTG interrupts
OUTREG32(&pOTGRegs->IRQ_EN, 0x00000000);
OUTREG32(&pOTGRegs->IRQ_SRC, 0x00000000);
CLRREG32(&pOTGRegs->CTRL, OTG_CTRL_BSESSEND);
// We don't get any interrupts from the USB Device unless this bit
// is set. Unfortunately, setting this bit also sets the "USB
// Cable Attached" bit, which remains set regardless of whether or
// not a cable is actually attached, and thus prevents us from
// being able to properly tell when a USB cable is connected to or
// disconnected from the device.
// The OMAP2420 TRM suggest having an additional hardware mechanism
// that would allow the driver to detect when a cable is connected
// and then set the BSESSVLD bit as appropriate. The H4 System
// design lacks this feature, so we'll have to use a workaround in
// the USB Driver PDD to compensate for this.
SETREG32(&pOTGRegs->CTRL, OTG_CTRL_BSESSVLD);
////////////////////////////////////////////////////////////////////////
// Display the modified OTG Registers //
////////////////////////////////////////////////////////////////////////
DEBUGMSG(ZONE_PDD, (L"USBD InitializeHardware() - Modified OTG Register Values:\r\n"));
DEBUGMSG(ZONE_PDD, (L" REV: 0x%08X\r\n", pOTGRegs->REV));
DEBUGMSG(ZONE_PDD, (L" SYSCON_1: 0x%08X\r\n", pOTGRegs->SYSCON_1));
DEBUGMSG(ZONE_PDD, (L" SYSCON_2: 0x%08X\r\n", pOTGRegs->SYSCON_2));
DEBUGMSG(ZONE_PDD, (L" CTRL: 0x%08X\r\n", pOTGRegs->CTRL));
DEBUGMSG(ZONE_PDD, (L" IRQ_EN: 0x%04X\r\n", pOTGRegs->IRQ_EN));
DEBUGMSG(ZONE_PDD, (L" IRQ_SRC: 0x%04X\r\n", pOTGRegs->IRQ_SRC));
DEBUGMSG(ZONE_PDD, (L" OUTCTRL: 0x%04X\r\n", pOTGRegs->OUTCTRL));
DEBUGMSG(ZONE_PDD, (L" TEST: 0x%04X\r\n", pOTGRegs->TEST));
DEBUGMSG(ZONE_PDD, (L" VC: 0x%08X\r\n", pOTGRegs->VC));
////////////////////////////////////////////////////////////////////////
// Configure System Control Registers //
////////////////////////////////////////////////////////////////////////
temp = INREG32(&pSysConRegs->ulCONTROL_DEVCONF);
mode = ((otgSysCon1 & 0x00070000) >> 16);
// Clear USBT0WRIMODEI. This places the USB Controls in Unidirectional Mode
temp &= 0xFF3FFFFF;
// Set the Transceiver Interface Mode for USB Port 0
if ((mode == 0x01) || (mode == 0x02))
{
// Change the mode to Bidirectional.
temp |= 0x00800000;
}
// Make sure the USB Enable signal is being used as an Active-High signal
temp &= 0xFFFEFFFF;
// Make sure the USB module standby signal is not asserted
temp &= 0xFFFF7FFF;
OUTREG32(&pSysConRegs->ulCONTROL_DEVCONF, temp);
////////////////////////////////////////////////////////////////////////
// Display the modified System Control Registers //
////////////////////////////////////////////////////////////////////////
DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - Modified System Control Register Values:\r\n"));
DEBUGMSG(ZONE_FUNCTION, (L" CONTROL_DEVCONF: 0x%08X\r\n", pSysConRegs->ulCONTROL_DEVCONF));
////////////////////////////////////////////////////////////////////////////
// Unmap the memory mapped above. //
////////////////////////////////////////////////////////////////////////////
clean:
// Unmap the memory for the System Control Registers
if (pSysConRegs)
{
MmUnmapIoSpace((VOID*)pSysConRegs, sizeof(OMAP2420_SYSC1_REGS));
}
// Unmap the memory for the PRCM Registers
if (pPRCMRegs)
{
MmUnmapIoSpace((VOID*)pPRCMRegs, sizeof(OMAP2420_PRCM_REGS));
}
// Unmap the memory for the OTG Registers
if (pOTGRegs)
{
MmUnmapIoSpace((VOID*)pOTGRegs, sizeof(OMAP2420_OTG_REGS));
}
DEBUGMSG(ZONE_FUNCTION, (L"USBD InitializeHardware() - "
L"END\r\n"));
// Done
return rv;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -