• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
HiKeyDetectUsbModeInit(IN 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
HiKeyGetUsbMode(IN VOID)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
HiKeyUsbPhyInit(IN UINT8 Mode)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
UartInit(IN 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
MtcmosInit(IN 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
HiKeyInitPeripherals(IN VOID)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