1 /** @file 2 * 3 * Copyright (c) 2015, Linaro Ltd. All rights reserved. 4 * Copyright (c) 2015, Hisilicon Ltd. All rights reserved. 5 * 6 * This program and the accompanying materials 7 * are licensed and made available under the terms and conditions of the BSD License 8 * which accompanies this distribution. The full text of the license may be found at 9 * http://opensource.org/licenses/bsd-license.php 10 * 11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 * 14 **/ 15 16 #include <Library/IoLib.h> 17 #include <Library/TimerLib.h> 18 #include <Library/UefiLib.h> 19 #include <Library/UefiRuntimeServicesTableLib.h> 20 21 #include <Protocol/EmbeddedGpio.h> 22 #include <Protocol/DwUsb.h> 23 24 #include <Hi6220.h> 25 26 #include "Hi6220RegsPeri.h" 27 #include "HiKeyDxeInternal.h" 28 29 #define USB_SEL_GPIO0_3 3 // GPIO 0_3 30 #define USB_5V_HUB_EN 7 // GPIO 0_7 31 #define USB_ID_DET_GPIO2_5 21 // GPIO 2_5 32 #define USB_VBUS_DET_GPIO2_6 22 // GPIO 2_6 33 34 // Jumper on pin5-6 of J15 determines whether boot to fastboot 35 #define DETECT_J15_FASTBOOT 24 // GPIO 3_0 36 37 STATIC EMBEDDED_GPIO *mGpio; 38 39 STATIC 40 VOID 41 HiKeyDetectUsbModeInit ( 42 IN VOID 43 ) 44 { 45 EFI_STATUS Status; 46 47 /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */ 48 MmioWrite32 (0xf8001864, 1); 49 MmioWrite32 (0xf8001868, 1); 50 51 Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&mGpio); 52 ASSERT_EFI_ERROR (Status); 53 Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0); 54 ASSERT_EFI_ERROR (Status); 55 Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0); 56 ASSERT_EFI_ERROR (Status); 57 MicroSecondDelay (1000); 58 59 Status = mGpio->Set (mGpio, USB_ID_DET_GPIO2_5, GPIO_MODE_INPUT); 60 ASSERT_EFI_ERROR (Status); 61 Status = mGpio->Set (mGpio, USB_VBUS_DET_GPIO2_6, GPIO_MODE_INPUT); 62 ASSERT_EFI_ERROR (Status); 63 } 64 65 UINTN 66 HiKeyGetUsbMode ( 67 IN VOID 68 ) 69 { 70 EFI_STATUS Status; 71 UINTN GpioId, GpioVbus; 72 UINTN Value; 73 74 Status = mGpio->Get (mGpio, USB_ID_DET_GPIO2_5, &Value); 75 ASSERT_EFI_ERROR (Status); 76 GpioId = Value; 77 Status = mGpio->Get (mGpio, USB_VBUS_DET_GPIO2_6, &Value); 78 ASSERT_EFI_ERROR (Status); 79 GpioVbus = Value; 80 81 if ((GpioId == 1) && (GpioVbus == 0)) 82 return USB_DEVICE_MODE; 83 else if ((GpioId == 0) && (GpioVbus == 1)) 84 return USB_CABLE_NOT_ATTACHED; 85 return USB_HOST_MODE; 86 } 87 88 EFI_STATUS 89 HiKeyUsbPhyInit ( 90 IN UINT8 Mode 91 ) 92 { 93 UINTN Value; 94 UINT32 Data; 95 96 HiKeyDetectUsbModeInit (); 97 98 //setup clock 99 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN0, BIT4); 100 do { 101 Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CLKSTAT0); 102 } while ((Value & BIT4) == 0); 103 104 //setup phy 105 Data = RST0_USBOTG_BUS | RST0_POR_PICOPHY | 106 RST0_USBOTG | RST0_USBOTG_32K; 107 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, Data); 108 do { 109 Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT0); 110 Value &= Data; 111 } while (Value); 112 113 Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4); 114 Value &= ~(CTRL4_PICO_SIDDQ | CTRL4_FPGA_EXT_PHY_SEL | 115 CTRL4_OTG_PHY_SEL); 116 Value |= CTRL4_PICO_VBUSVLDEXT | CTRL4_PICO_VBUSVLDEXTSEL; 117 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4, Value); 118 MicroSecondDelay (1000); 119 120 //If Mode = 1, USB in Device Mode 121 //If Mode = 0, USB in Host Mode 122 if (Mode == USB_DEVICE_MODE) { 123 if (HiKeyGetUsbMode () == USB_DEVICE_MODE) { 124 DEBUG ((EFI_D_ERROR, "usb work as device mode.\n")); 125 } else { 126 return EFI_INVALID_PARAMETER; 127 } 128 129 Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5); 130 Value &= ~CTRL5_PICOPHY_BC_MODE; 131 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value); 132 MicroSecondDelay (20000); 133 } else { 134 if (HiKeyGetUsbMode () == USB_HOST_MODE) { 135 DEBUG ((EFI_D_ERROR, "usb work as host mode.\n")); 136 } else { 137 return EFI_INVALID_PARAMETER; 138 } 139 140 /*CTRL5*/ 141 Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5); 142 Data &= ~CTRL5_PICOPHY_BC_MODE; 143 Data |= CTRL5_USBOTG_RES_SEL | CTRL5_PICOPHY_ACAENB | 144 CTRL5_PICOPHY_VDATDETENB | CTRL5_PICOPHY_DCDENB; 145 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Data); 146 MicroSecondDelay (20000); 147 MmioWrite32 (PERI_CTRL_BASE + 0x018, 0x70533483); //EYE_PATTERN 148 149 MicroSecondDelay (5000); 150 } 151 152 return EFI_SUCCESS; 153 } 154 155 STATIC 156 VOID 157 UartInit ( 158 IN VOID 159 ) 160 { 161 UINT32 Val; 162 163 /* make UART1 out of reset */ 164 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART1); 165 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART1); 166 /* make UART2 out of reset */ 167 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART2); 168 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART2); 169 /* make UART3 out of reset */ 170 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART3); 171 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART3); 172 /* make UART4 out of reset */ 173 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART4); 174 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART4); 175 176 /* make DW_MMC2 out of reset */ 177 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, PERIPH_RST0_MMC2); 178 179 /* enable clock for BT/WIFI */ 180 Val = MmioRead32 (PMUSSI_REG(0x1c)) | 0x40; 181 MmioWrite32 (PMUSSI_REG(0x1c), Val); 182 } 183 184 STATIC 185 VOID 186 MtcmosInit ( 187 IN VOID 188 ) 189 { 190 UINT32 Data; 191 192 /* enable MTCMOS for GPU */ 193 MmioWrite32 (AO_CTRL_BASE + SC_PW_MTCMOS_EN0, PW_EN0_G3D); 194 do { 195 Data = MmioRead32 (AO_CTRL_BASE + SC_PW_MTCMOS_ACK_STAT0); 196 } while ((Data & PW_EN0_G3D) == 0); 197 } 198 199 EFI_STATUS 200 HiKeyInitPeripherals ( 201 IN VOID 202 ) 203 { 204 UINT32 Data, Bits; 205 206 /* make I2C0/I2C1/I2C2/SPI0 out of reset */ 207 Bits = PERIPH_RST3_I2C0 | PERIPH_RST3_I2C1 | PERIPH_RST3_I2C2 | \ 208 PERIPH_RST3_SSP; 209 MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, Bits); 210 211 do { 212 Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT3); 213 } while (Data & Bits); 214 215 UartInit (); 216 MtcmosInit (); 217 218 return EFI_SUCCESS; 219 } 220