123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- /*++
- Copyright (c) 2013 Minoca Corp. All Rights Reserved
- Module Name:
- omap4usb.c
- Abstract:
- This module fires up the OMAP4 High Speed USB controller.
- Author:
- Evan Green 24-Mar-2013
- Environment:
- Firmware
- --*/
- //
- // ------------------------------------------------------------------- Includes
- //
- #include <uefifw.h>
- #include "pandafw.h"
- //
- // --------------------------------------------------------------------- Macros
- //
- #define ULPI_SET_REGISTER(_Register) (_Register + 1)
- #define ULPI_CLEAR_REGISTER(_Register) (_Register + 1)
- //
- // These macros read from and write to the L3 INIT CM2 block.
- //
- #define OMAP4_READ_L3_INIT_CM2_REGISTER(_Register) \
- *(volatile UINT32 *)((UINT8 *)EfiOmap4L3InitCm2Address + (_Register))
- #define OMAP4_WRITE_L3_INIT_CM2_REGISTER(_Register, _Value) \
- *((volatile UINT32 *)((UINT8 *)EfiOmap4L3InitCm2Address + (_Register))) = \
- (_Value)
- //
- // These macros read from and write to the OMAP4 SCRM.
- //
- #define OMAP4_READ_SCRM_REGISTER(_Register) \
- *(volatile UINT32 *)((UINT8 *)EfiOmap4ScrmAddress + (_Register))
- #define OMAP4_WRITE_SCRM_REGISTER(_Register, _Value) \
- *((volatile UINT32 *)((UINT8 *)EfiOmap4ScrmAddress + (_Register))) = \
- (_Value)
- //
- // These macros read from and write to the OMAP4 High Speed USB Host block.
- //
- #define OMAP4_READ_HS_USB_HOST_REGISTER(_Register) \
- *(volatile UINT32 *)((UINT8 *)EfiOmap4HsUsbHostAddress + (_Register))
- #define OMAP4_WRITE_HS_USB_HOST_REGISTER(_Register, _Value) \
- *((volatile UINT32 *)((UINT8 *)EfiOmap4HsUsbHostAddress + (_Register))) = \
- (_Value)
- //
- // These macros read from and write to the OMAP4 EHCI registers.
- //
- #define OMAP4_READ_EHCI_REGISTER(_Register) \
- *(volatile UINT32 *)((UINT8 *)EfiOmap4EhciAddress + (_Register))
- #define OMAP4_WRITE_EHCI_REGISTER(_Register, _Value) \
- *((volatile UINT32 *)((UINT8 *)EfiOmap4EhciAddress + (_Register))) = \
- (_Value)
- //
- // These macros read from and write to the OMAP4 USB TLL config registers.
- //
- #define OMAP4_READ_USB_TLL_CONFIG_REGISTER(_Register) \
- *(volatile UINT32 *)((UINT8 *)EfiOmap4UsbTllConfigAddress + (_Register))
- #define OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(_Register, _Value) \
- *((volatile UINT32 *)((UINT8 *)EfiOmap4UsbTllConfigAddress + \
- (_Register))) = (_Value)
- //
- // ---------------------------------------------------------------- Definitions
- //
- #define OMAP4_HS_USB_PORT_COUNT 1
- #define OMAP4_L3_INIT_CM2_USB_HOST_PORT_1_UTMI_EXTERNALLY_CLOCKED (1 << 24)
- #define OMAP4_L3_INIT_CM2_USB_HOST_48_MHZ_CLOCK_ENABLED (1 << 15)
- #define OMAP4_L3_INIT_CM2_USB_HOST_MODULE_ENABLED (0x2 << 0)
- #define OMAP4_L3_INIT_CM2_USB_TLL_ENABLED (0x1 << 0)
- #define OMAP4_L3_INIT_CM2_FULL_SPEED_USB_CLOCK_ENABLED (0x2 << 0)
- #define OMAP4_L3_INIT_CM2_USB_PHY_48_MHZ_CLOCK_ENABLE (1 << 8)
- #define OMAP4_L3_INIT_CM2_USB_PHY_ENABLED (0x1 << 0)
- #define OMAP4_USB_TLL_CLOCKS_ON_DURING_IDLE (1 << 8)
- #define OMAP4_USB_TLL_CONFIG_NO_IDLE (0x1 << 3)
- #define OMAP4_USB_TLL_CONFIG_WAKEUP_ENABLE (1 << 2)
- #define OMAP4_USB_TLL_CONFIG_SOFT_RESET (1 << 1)
- #define OMAP4_USB_TLL_STATUS_RESET_DONE (1 << 0)
- #define OMAP4_AUX_CLOCK_DIVIDE_BY_2 (0x1 << 16)
- #define OMAP4_AUX_CLOCK_ENABLED (1 << 8)
- #define OMAP4_ALT_CLOCK_ENABLE_EXT (1 << 3)
- #define OMAP4_ALT_CLOCK_ENABLE_INT (1 << 2)
- #define OMAP4_ALT_CLOCK_ACTIVE (0x1 << 0)
- #define OMAP4_HS_USB_SYSTEM_CONFIG_STANDBY_MASK (0x3 << 4)
- #define OMAP4_HS_USB_SYSTEM_CONFIG_NO_STANDBY (0x1 << 4)
- #define OMAP4_HS_USB_SYSTEM_CONFIG_IDLE_MASK (0x3 << 2)
- #define OMAP4_HS_USB_SYSTEM_CONFIG_NO_IDLE (0x1 << 2)
- #define OMAP4_HS_USB_HOST_CONFIG_INCR4_ENABLE (1 << 2)
- #define OMAP4_HS_USB_HOST_CONFIG_INCR8_ENABLE (1 << 3)
- #define OMAP4_HS_USB_HOST_CONFIG_INCR16_ENABLE (1 << 4)
- #define OMAP4_HS_USB_HOST_CONFIG_INCR_ALIGNED (1 << 5)
- #define OMAP4_HS_USB_P1_MODE_MASK (0x3 << 16)
- #define OMAP4_HS_USB_P2_MODE_MASK (0x3 << 18)
- #define OMAP4_EHCI_INSNREG4_DISABLE_UNSUSPEND (1 << 5)
- #define OMAP4_EHCI_INSNREG5_ULPI_DIRECT_REGISTER_ADDRESS_SHIFT 16
- #define OMAP4_EHCI_INSNREG5_ULPI_WRITE (0x2 << 22)
- #define OMAP4_EHCI_INSNREG5_ULPI_PORT_SHIFT 24
- #define OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS (1 << 31)
- #define ULPI_FUNCTION_CONTROL 0x04
- #define ULPI_FUNCTION_CONTROL_RESET (1 << 5)
- //
- // ----------------------------------------------- Internal Function Prototypes
- //
- //
- // ------------------------------------------------------ Data Type Definitions
- //
- typedef enum _OMAP4_L3_INIT_CM2_REGISTER {
- Omap4L3InitCm2UsbHostClockControl = 0x58, // CM_L3INIT_HSUSBHOST_CLKCTRL
- Omap4L3InitCm2UsbTllClockControl = 0x68, // CM_L3INIT_HSUSBTLL_CLKCTRL
- Omap4L3InitCm2FullSpeedUsbClockControl = 0xD0, // CM_L3INIT_FSUSB_CLKCTRL
- Omap4L3InitCm2UsbPhyClockControl = 0xE0, // CM_L3INIT_USBPHY_CLKCTRL
- } OMAP4_L3_INIT_CM2_REGISTER, POMAP4_L3_INIT_CM2_REGISTER;
- typedef enum _OMAP4_SCRM_REGISTER {
- Omap4ScrmAltClockSource = 0x110, // ALTCLKSRC
- Omap4ScrmAuxClock3 = 0x31C, // AUXCLK3
- } OMAP4_SCRM_REGISTER, *POMAP4_SCRM_REGISTER;
- typedef enum _OMAP4_HS_USB_HOST_REGISTER {
- Omap4HsUsbHostSystemConfiguration = 0x10, // UHH_SYSCONFIG
- Omap4HsUsbHostConfiguration = 0x40, // UHH_HOSTCONFIG
- } OMAP4_HS_USB_HOST_REGISTER, POMAP4_HS_USB_HOST_REGISTER;
- typedef enum _OMAP4_EHCI_REGISTER {
- Omap4EhciImplementationRegister4 = 0xA0, // INSNREG04
- Omap4EhciImplementationRegister5 = 0xA4, // INSNREG05
- } OMAP4_EHCI_REGISTER, *POMAP4_EHCI_REGISTER;
- typedef enum _OMAP4_USB_TLL_CONFIG_REGISTER {
- Omap4UsbTllSystemConfiguration = 0x10, // USBTLL_SYSCONFIG
- Omap4UsbTllSystemStatus = 0x14, // USBTLL_SYSSTATUS
- } OMAP4_USB_TLL_CONFIG_REGISTER, *POMAP4_USB_TLL_CONFIG_REGISTER;
- //
- // -------------------------------------------------------------------- Globals
- //
- //
- // Store a pointer to the L3 INIT CM2 register block.
- //
- VOID *EfiOmap4L3InitCm2Address = (VOID *)OMAP4430_L3_INIT_CM2_BASE;
- //
- // Store a pointer to the SCRM.
- //
- VOID *EfiOmap4ScrmAddress = (VOID *)OMAP4430_SCRM_BASE;
- //
- // Store a pointer to the High Speed USB Host block.
- //
- VOID *EfiOmap4HsUsbHostAddress = (VOID *)OMAP4430_HS_USB_HOST_BASE;
- //
- // Store a pointer to the EHCI register base.
- //
- VOID *EfiOmap4EhciAddress = (VOID *)OMAP4430_EHCI_BASE;
- //
- // Store a pointer to the USB TLL configuration register base.
- //
- VOID *EfiOmap4UsbTllConfigAddress = (VOID *)OMAP4430_USB_TLL_CONFIG_BASE;
- //
- // ------------------------------------------------------------------ Functions
- //
- VOID
- EfipOmap4UsbInitialize (
- VOID
- )
- /*++
- Routine Description:
- This routine performs any board-specific high speed USB initialization.
- Arguments:
- None.
- Return Value:
- None.
- --*/
- {
- UINT32 PortIndex;
- UINT32 Value;
- //
- // Enable the USB module's clocks.
- //
- Value = OMAP4_L3_INIT_CM2_USB_HOST_PORT_1_UTMI_EXTERNALLY_CLOCKED |
- OMAP4_L3_INIT_CM2_USB_HOST_MODULE_ENABLED;
- OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbHostClockControl, Value);
- Value = OMAP4_L3_INIT_CM2_FULL_SPEED_USB_CLOCK_ENABLED;
- OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2FullSpeedUsbClockControl,
- Value);
- Value = OMAP4_L3_INIT_CM2_USB_TLL_ENABLED;
- OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbTllClockControl, Value);
- Value = (1 << 9) |
- OMAP4_L3_INIT_CM2_USB_PHY_48_MHZ_CLOCK_ENABLE |
- OMAP4_L3_INIT_CM2_USB_PHY_ENABLED;
- OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbPhyClockControl, Value);
- //
- // Reset the USB TLL module, and wait for reset to complete.
- //
- Value = OMAP4_USB_TLL_CONFIG_SOFT_RESET;
- OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemConfiguration, Value);
- do {
- Value = OMAP4_READ_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemStatus);
- } while ((Value & OMAP4_USB_TLL_STATUS_RESET_DONE) == 0);
- Value = OMAP4_USB_TLL_CLOCKS_ON_DURING_IDLE |
- OMAP4_USB_TLL_CONFIG_NO_IDLE |
- OMAP4_USB_TLL_CONFIG_WAKEUP_ENABLE;
- OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemConfiguration, Value);
- //
- // The USB3320C ULPI PHY's clock is fed by fref_clk3_out, a pin sourced by
- // AUXCLK3. Enable that puppy and set it to run at the required 19.2MHz,
- // half of the system clock's 38.4MHz.
- //
- Value = OMAP4_AUX_CLOCK_DIVIDE_BY_2 | OMAP4_AUX_CLOCK_ENABLED;
- OMAP4_WRITE_SCRM_REGISTER(Omap4ScrmAuxClock3, Value);
- Value = OMAP4_ALT_CLOCK_ENABLE_EXT | OMAP4_ALT_CLOCK_ENABLE_INT |
- OMAP4_ALT_CLOCK_ACTIVE;
- OMAP4_WRITE_SCRM_REGISTER(Omap4ScrmAltClockSource, Value);
- //
- // Set up the serial configuration (ULPI bypass) and burst configuration.
- //
- Value = OMAP4_READ_HS_USB_HOST_REGISTER(Omap4HsUsbHostSystemConfiguration);
- Value &= ~(OMAP4_HS_USB_SYSTEM_CONFIG_STANDBY_MASK |
- OMAP4_HS_USB_SYSTEM_CONFIG_IDLE_MASK);
- Value |= OMAP4_HS_USB_SYSTEM_CONFIG_NO_STANDBY |
- OMAP4_HS_USB_SYSTEM_CONFIG_NO_IDLE;
- OMAP4_WRITE_HS_USB_HOST_REGISTER(Omap4HsUsbHostSystemConfiguration, Value);
- Value = OMAP4_READ_HS_USB_HOST_REGISTER(Omap4HsUsbHostConfiguration);
- Value |= OMAP4_HS_USB_HOST_CONFIG_INCR4_ENABLE |
- OMAP4_HS_USB_HOST_CONFIG_INCR8_ENABLE |
- OMAP4_HS_USB_HOST_CONFIG_INCR16_ENABLE;
- Value &= ~(OMAP4_HS_USB_HOST_CONFIG_INCR_ALIGNED |
- OMAP4_HS_USB_P1_MODE_MASK |
- OMAP4_HS_USB_P2_MODE_MASK);
- OMAP4_WRITE_HS_USB_HOST_REGISTER(Omap4HsUsbHostConfiguration, Value);
- //
- // Turn on the magic disable unsuspend bit to prevent the root hub from
- // coming out of suspend when the run bit is cleared.
- //
- OMAP4_WRITE_EHCI_REGISTER(Omap4EhciImplementationRegister4,
- OMAP4_EHCI_INSNREG4_DISABLE_UNSUSPEND);
- //
- // Set GPIO 62 to take the USB3320C PHY out of reset.
- //
- Value = READ_GPIO2_REGISTER(OmapGpioOutputEnable);
- WRITE_GPIO2_REGISTER(OmapGpioOutputEnable, Value & ~(1 << (62 - 32)));
- WRITE_GPIO2_REGISTER(OmapGpioOutputSet, (1 << (62 - 32)));
- //
- // Reset the PHY on each port.
- //
- for (PortIndex = 0; PortIndex < OMAP4_HS_USB_PORT_COUNT; PortIndex += 1) {
- //
- // Send a RESET command, which is a write, to the function control
- // address of the given port.
- //
- Value = ULPI_FUNCTION_CONTROL_RESET |
- (ULPI_SET_REGISTER(ULPI_FUNCTION_CONTROL) <<
- OMAP4_EHCI_INSNREG5_ULPI_DIRECT_REGISTER_ADDRESS_SHIFT) |
- OMAP4_EHCI_INSNREG5_ULPI_WRITE |
- ((PortIndex + 1) << OMAP4_EHCI_INSNREG5_ULPI_PORT_SHIFT) |
- OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS;
- OMAP4_WRITE_EHCI_REGISTER(Omap4EhciImplementationRegister5, Value);
- do {
- Value = OMAP4_READ_EHCI_REGISTER(Omap4EhciImplementationRegister5);
- } while ((Value & OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS) != 0);
- }
- //
- // Set GPIO 1 to enable the TPS73633 LDO which provides power to the root
- // hub slash ethernet combo. For the output enable register, when a bit is
- // 0, then the GPIO is in output mode.
- //
- Value = READ_GPIO1_REGISTER(OmapGpioOutputEnable);
- WRITE_GPIO1_REGISTER(OmapGpioOutputEnable, Value & ~(1 << 1));
- WRITE_GPIO1_REGISTER(OmapGpioOutputSet, (1 << 1));
- return;
- }
|