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

📄 ohcdpdd.c

📁 Intel PXA270 Wince5.0 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
            Info.PortSize = sizeof(DWORD);
            Info.MaskAddr = PhysAddr + 0x10;
            
            if (!KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {
                DEBUGMSG(ZONE_ERROR, (L"UHCD: KernelLibIoControl call failed.\r\n"));
            }
        }
    }
#endif
    
#ifdef TRANSLATE_ADDRESSES
    // The PDD can supply a buffer of contiguous physical memory here, or can let the 
    // MDD try to allocate the memory from system RAM.  We will use the HalAllocateCommonBuffer()
    // API to allocate the memory and bus controller physical addresses and pass this information
    // into the MDD.
    pPddObject->AdapterObject.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
    pPddObject->AdapterObject.InterfaceType = IfcType;
    pPddObject->AdapterObject.BusNumber = dwBusNumber;
    if ((pPddObject->pvVirtualAddress = HalAllocateCommonBuffer(&pPddObject->AdapterObject, gcTotalAvailablePhysicalMemory, &pPddObject->LogicalAddress, FALSE)) == NULL) {
        goto InitializeUHCI_Error;
    }
   if (!(pobMem = HcdMdd_CreateMemoryObject(gcTotalAvailablePhysicalMemory, gcHighPriorityPhysicalMemory, (PUCHAR) pPddObject->pvVirtualAddress, (PUCHAR) pPddObject->LogicalAddress.LowPart))) {
        goto InitializeUHCI_Error;
    }
#else   // TRANSLATE_ADDRESSES
    // we should try to use HalAllocateCommonBuffer() instead of a hardcoded memory address
    if(!(pobMem = HcdMdd_CreateMemoryObject(gcTotalAvailablePhysicalMemory, gcHighPriorityPhysicalMemory, (PUCHAR) v_pOHCIDMABuffer, (PUCHAR)dwOhciDmaBufferPhysical/* OHCI_DMA_BUFFER_PHYSICAL*/))) {
        goto InitializeUHCI_Error;
    }
#endif  // TRANSLATE_ADDRESSES
 
    if (!(pobUhcd = HcdMdd_CreateHcdObject(pPddObject, pobMem, szDriverRegKey, ioPortBase, dwSysIntr))) {
        goto InitializeUHCI_Error;
    }

    pPddObject->lpvMemoryObject = pobMem;
    pPddObject->lpvUhcdMddObject = pobUhcd;
    _tcsncpy(pPddObject->szDriverRegKey, szDriverRegKey, MAX_PATH);
    pPddObject->ioPortBase = ioPortBase;
    pPddObject->dwSysIntr = dwSysIntr;

	// start the debug thread
//	RETAILMSG(1,(TEXT("InitializeUHCI: Starting OHCIPDDDebugThread.\r\n")));
//  CreateThread(NULL, 0, OHCIPDDDebugThread, pPddObject, 0, NULL);

    return TRUE;

InitializeUHCI_Error:
#ifndef OSV_LOCAL_MERLIN
    if (g_IsrHandle) {
        FreeIntChainHandler(g_IsrHandle);
        g_IsrHandle = NULL;
    }
#endif

    if (pobUhcd)
        HcdMdd_DestroyHcdObject(pobUhcd);
    if (pobMem)
        HcdMdd_DestroyMemoryObject(pobMem);
#ifndef OSV_LOCAL_MERLIN
    if(pPddObject->pvVirtualAddress)
        HalFreeCommonBuffer(&pPddObject->AdapterObject, gcTotalAvailablePhysicalMemory, pPddObject->LogicalAddress, pPddObject->pvVirtualAddress, FALSE);
#endif

    pPddObject->lpvMemoryObject = NULL;
    pPddObject->lpvUhcdMddObject = NULL;
    pPddObject->pvVirtualAddress = NULL;

    return FALSE;
}





#ifndef PLAT_LUBBOCK

// TurnOnUSBHostClocks:
//		This routine will make sure that the USB Host OHCI block in the
//		Bulverde core is getting clocks. If it is not getting clocks,
//		then some accesses to it may stall, especially if one needs to
//		wait for some OHCI register bits to change.
void
TurnOnUSBHostClocks()
{
	// The clock enable bit for the USB Host OHCI block in Bulverde
	// is bit number 20.
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOnUSBHostClocks: Initial Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
	v_pDCCLKReg->cken |= XLLP_CLKEN_USBHOST;
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOnUSBHostClocks: Final   Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
}


// TurnOnUSBHostClocks:
//		This routine will make sure that the USB Host OHCI block in the
//		Bulverde core is getting clocks. If it is not getting clocks,
//		then some accesses to it may stall, especially if one needs to
//		wait for some OHCI register bits to change.
void
TurnOnSRAMClocks()
{
	// The clock enable bit for the USB Host OHCI block in Bulverde
	// is bit number 20.
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOnSRAMClocks: Initial Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
	v_pDCCLKReg->cken |= (1u << 20);
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOnSRAMClocks: Final   Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
}


// TurnOffUSBHostClocks:
//		This routine will make sure that the USB Host OHCI block in the
//		Bulverde core is not getting clocks. If it is not getting clocks,
//		then there will be power savings.
void
TurnOffUSBHostClocks()
{
	// The clock enable bit for the USB Host OHCI block in Bulverde
	// is bit number 20.
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOfUSBHostClocks: Initial Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
	v_pDCCLKReg->cken &= ~XLLP_CLKEN_USBHOST;
	DEBUGMSG(ZONE_INIT,(TEXT("TurnOfUSBHostClocks: Final   Values: cccr: %08x cken: %08x oscc: %08x ccsr: %08x\n\r"), v_pDCCLKReg->cccr, v_pDCCLKReg->cken, v_pDCCLKReg->oscc, v_pDCCLKReg->ccsr));
}


// SetupUSBHostPWR:	
//
//		The root hub status register has some over-current indicator bits.
//
//		The USB Host cannot detect over-current indications itself. Over-
//		current detection must be performed by some external device on the
//		platform. In the case of the Mainstone, this is done by U53, a
//		MAX1693EUB USB Power Switch, which provides 5.0 volts to the USB
//		and also provides an over-current detection signal for use here.
//
//		Bulverde expects to get over-current indication as an input from
//		GPIO 88. Therefore, the nFAULT signal of the MAX1693EUB USB Power
//		switch on the Mainstone must be connected to GPIO 88.
//
//		GPIO 88 must be configured as an input and set to alternate function 1.
//
//		With the external circuitry wired in this fashion, and GPIO 88
//		configured as above, an assertion on the MAX1693EUB USB Power
//		Switch's nFAULT line will appear in the USB Host Root Hub status
//		register, UHCRHS, or a status register for a specific port on the 
//		root hub, UHCRHPS1 or UHCRHPS2, depending on the setting of the
//		UHCRHDA OverCurrentProtectionMode field.
//
//		Note: Over current detection must be enabled in the USB Host
//		Root Hub Descriptor A register, UHCRHDA, before assertions on 
//		GPIO 88 are detected. Furthermore, over current detection must
//		be selected as global or per-port, also via the UHCRHDA register.

void
SetupUSBHostPWR(
	int	Port
	)
{
	unsigned long	ulPinArrayParms[3];
	unsigned long	ulAlternateFunctionParms[3];
	
	// Configure GPIO 88 according to the discussion above:
	//		Direction: Input
	//		Alternate function: 1
	
	// direction & alternate function gpio apis both use the same pin array
	ulPinArrayParms[0]	= 1;
	ulPinArrayParms[1]	= 88;

	XllpGpioSetDirectionIn( v_pDCGPIOReg, ulPinArrayParms );

	ulAlternateFunctionParms[0]	= 1;
	ulAlternateFunctionParms[1] = XLLP_GPIO_ALT_FN_1;
	XllpGpioSetAlternateFn( v_pDCGPIOReg, ulPinArrayParms, ulAlternateFunctionParms );

}

// SetupUSBHostPEN:	
//
//		A USBHost platform must provide 5V to the USB. Bulverde cannot do this.
//		Bulverde cannot source 5 volts, so some external circuitry is required.
//		The MAX1693EUB USB Power Switch is a component used to provide 5 volts
//		for a USB; it also can provide an over-current indicator if any device
//		on the USB begins to draw too much current.
//
//		U53 on the Mainstone has a MAX1693EUB USB Power Switch. This part
//		is connected to a 5V power supply from the Mainstone. However, the
//		Bulverde USB Host is in control of enabling or disabling the MAX
//		1693EUB USB Power Switch. When the USB Host enables the MAX1693EUB
//		USB Power Switch by asserting the MAX1693EUB USB Power Switch's nON
//		signal, the USB V+ and V- signals provide 5 Volts. When the nON signal
//		is deasserted, the MAX1693EUB USB Power Switch turns the USB off.
//
//		The Bulverde USB Host expects to use GPIO 89 as a power enable signal.
//		The USB Host asserts or deasserts GPIO 89 by setting different bits
//		depending on the configuration of the USB Host. The configuration bits
//		that are important here are:
//
//			UHCRHDA:NoPowerSwitching (aka NPS)
//				0:	the port power will follow the global or per-port
//					power enable bits, depending UHCRHDA:PortSwitchingMode
//				1:	Not able to switch power on and off, so 
//					the port power will always be enabled.
//				
//			UHCRHDA:PowerSwitchingMode (aka PSM)
//				0:	Global Power Switching Mode, power for all ports is 
//					enabled or disabled in response to SetGlobalPower or
//					ClearGlobalPower commands.
//				1:	Per-Port Power Switching Mode, some ports can have
//					their power enabled or disabled individually with 
//					SetPortPower and ClearPortPower commands to the 
//					corresponding USB Host Root Hub Port Status registers
//					UHCRHPS1 or UHCRHPS2. In this mode, other ports can
//					respond to the global commands SetGlobalPower and 
//					ClearGlobalPower. Which type of power command the port
//					responds to is controlled by the setting of the Port
//					Power Control Mask bit for each port, found in the
//					UHCRHDB:PPCM field
//
//			Enabling / Disabling Global Power:
//				Enable:		Write 1 to UHCRHDB:LPSC
//				Disable:	Write 1 to UHCRHDB:LPS
//
//			Enabling / Disabling a specific Port's power
//				Enable:		Write 1 to UHCRHPSx:PPS
//				Disable:	Write 1 to UHCRHPSx:LDA
//				where x is 1 for Port1 or 2 for Port2
//
//			Inclusion / Exclusion from Global Set/Clear Port Power Commands
//				Inclusion:	Write 0 to UHCRHDB:PPCM[x], the corresponding port
//							will only recognize Global Set/Clear Power commands.
//							It will not respond to specific SetPortPower or
//							ClearPortPower commands.
//				Exclusion:	Write 1 to UHCRHDB:PPCM[x], the corresponding port
//							will not recognize Global Set/Clear Power commands.
//							It will only respond to specific SetPortPower or
//							ClearPortPower commands.
//				where x is 1 for Port1 or 2 for Prt2
//				note: x=0 or x>3 are reserved bits in the PPCM field.
//
//
//	Power Enable/Disable Configurations, in order of simplicity:
//
//	1.	No Power Switching:
//		Setup:
//			A. Set UHCRHDA:NoPowerSwitching to 1.	(Disallows power switching)
//
//		Comments:
//			The ports will be powered on as long as the USH Host block is on.
//
//
//	2.	Global Power Switching Mode Only:
//		Setup:
//			A. Set UHCRHDA:NoPowerSwitching to 0.	(Allows power switching)
//			B. Set UHCRHDA:PowerSwitchingMode to 0.	(Selects PowerSwitchingMode = Global)
//
//		To Enable Global Power:
//			Set UHCRHDB:LPSC to 1.					(Turn on power to all ports)
//
//		To Disable Global Power:
//			Set UHCRHDB:LPS to 1.					(Turn off power to all ports)
//
//		Comments:
//			Power switching is enabled.
//			Global Power Mode is enabled.
//			Power to all ports is enabled or disabled at the same time.
//
//
//	3.	Per Port Power Switching Mode Only:
//		Setup:
//			A. Set UHCRHDA:NoPowerSwitching to 0.	(Allows power switching)
//			B. Set UHCRHDA:PowerSwitchingMode to 1.	(Selects PowerSwitchingMode = Per-Port)
//			C. Set UHCRHDB:PPCM[1] to 1.			(Makes UHCRHP1 respond only to per port power commands)
//			D. Set UHCRHDB:PPCM[2] to 1.			(Makes UHCRHP2 respond only to per port power commands)
//
//		To Enable Port1 Power:
//			Set UHCRHPS1:PPS to 1					(Turn on power to port 1)
//
//		To Disable Port1 Power:
//			Set UHCRHPS1:LDA to 1					(Turn off power to port 1)
//
//		To Enable Port2 Power:
//			Set UHCRHPS2:PPS to 1					(Turn on power to port 2)
//
//		To Disable Port2 Power:
//			Set UHCRHPS2:LDA to 1					(Turn off power to port 2)
//
//		Comments:
//			Power switching is enabled.
//			Per Port Power switching mode is enabled.
//			Each port to participate in Per Port Power switching must set
//			its corresponding bit in the UHCRHDB:PPCM mask.
//			Power to individual ports is enabled or disabled without effecting other ports.
//			
//
//	4.	Combination Global Power Mode Switching and Per Port Power Switching Mode Only:
//		Setup:
//			A. Set UHCRHDA:NoPowerSwitching to 0.	(Allows power switching)
//			B. Set UHCRHDA:PowerSwitchingMode to 1.	(Selects PowerSwitchingMode = Per-Port)
//			C. Set UHCRHDB:PPCM[1] to 0.			(Makes UHCRHP1 respond only to per port power commands)
//			D. Set UHCRHDB:PPCM[2] to 1.			(Makes UHCRHP2 respond only to per port power commands)
//
//		To Enable Port1 Power:
//			Set UHCRHDB:LPSC to 1.					(A Global Power Command: port1 responds by turning on)
//													(Port2 remains unaffected)
//
//		To Disable Port1 Power:
//			Set UHCRHDB:LPS to 1.					(A Global Power Command: port1 responds by turning off)
//													(Port2 remains unaffected)
//
//		To Enable Port2 Power:
//			Set UHCRHPS2:PPS to 1					(Turn on power to port 2)
//													(Port1 remains unaffected)
//
//		To Disable Port2 Power:
//			Set UHCRHPS2:LDA to 1					(Turn off power to port 2)
//													(Port1 remains unaffected)
//
//		Comments:
//			This example shows port1 being controlled by Global Power Mode commands,
//			and port2 is controlled only by specific set or clear port power commands.
//			Power switching is enabled.
//			Per Port Power switching mode is enabled.
//			Each port to participate in Per Port Power switching must set
//			its corresponding bit in the UHCRHDB:PPCM mask.
//			In this case:
//				Port1 responds to Global Power Mode commands
//				Port2 response to Per Port Power Mode commands
//			All ports without their bits set in UHCRHDB:PPCM mask are effect by Global Power Mode commands.
//			Power to individual ports is enabled or disabled without effecting other ports.
//			
//

void
SetupUSBHostPEN(
	int	Port
	)
{
	unsigned long	ulPinArrayParms[3];
	unsigned long	ulAlternateFunctionParms[3];

	// Configure GPIO 89 according to the discussion above:
	//		Level: Low (enable)
	//		Direction: Output
	//		Alternate function: 2
	
	// level, direction & alternate function gpio apis all use the same pin array
	ulPinArrayParms[0]	= 1;
	ulPinArrayParms[1]	= 89;

	XllpGpioSetOutput0( v_pDCGPIOReg, ulPinArrayParms );

	XllpGpioSetDirectionOut( v_pDCGPIOReg, ulPinArrayParms );

	ulAlternateFunctionParms[0]	= 1;
	ulAlternateFunctionParms[1] = XLLP_GPIO_ALT_FN_2;
	XllpGpioSetAlternateFn( v_pDCGPIOReg, ulPinArrayParms, ulAlternateFunctionParms );

}

void
SelectUSBHOSTPowerManagementMode(
	int	Mode,
	int	NumPorts,
	int	*PortMode
	)
{
	switch(Mode)
	{
	case	XLLP_USBOHCI_PPM_NPS:
				// set NO Power Switching mode
				v_pDCUSBOHCIReg->uhcrhda |= XLLP_USBOHCI_UHCRHDA_NPS;			
				break;

⌨️ 快捷键说明

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