1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ///////////////////////////////////////////////////////////////////////////////////////////////////
79 /// File name: usbentry.c
80 /// @brief USB host driver Entry function.
81 /// @author MStar Semiconductor Inc.
82 ///////////////////////////////////////////////////////////////////////////////////////////////////
83 //#include <MsCommon.h> // NUSED
84
85 #include "include/drvConfig.h"
86 //#include "include/drvPorts.h" // NUSED
87 #include "include/drvKernel.h"
88 //#include "include/drvTimer.h" // NUSED
89 //#include "include/drvCPE_EHCI.h" // NUSED
90 //#include "include/drvCPE_AMBA.h" // NUSED
91
92 //#include "drvUsbd.h" // NUSED
93 #include "drvMassStor.h"
94 //#include "drvUSB.h" // NUSED
95 #include "drvUSBHwCtl.h"
96 //#include "drvEHCI.h" // NUSED
97 #if USB_MASS_STORAGE_SUPPORT
98 #include "drvMSC.h"
99 #endif
100 #if USB_HID_SUPPORT
101 #include "drvHIDGlue.h"
102 #endif
103 #if USB_CDC_SUPPORT
104 #include "drvCDCDev.h"
105 #endif
106 /* applying drvUsbHostConfig.h (inside drvUSBHwCtl.h) */
107
108 struct s_ChipUsbHostDef *pCurrentChip;
109 struct s_ChipUsbHostDef chipDESC;
110
111 mem_Alloc pfnAllocCachedMem=NULL, pfnAllocNoncachedMem=NULL;
112 mem_Free pfnFreeCachedMem=NULL, pfnFreeNoncachedMem=NULL;
113 mem_VA2PA pfnVA2PA=NULL;
114 mem_PA2VA pfnPA2VA=NULL;
115 mem_Cached2Noncached pfnCached2Noncached=NULL;
116 mem_NonCached2Cached pfnNoncached2Cached=NULL;
117
118 MS_S32 _s32UsbEventId = -1;
119 MS_U8 gUsbChipID = 0xFF;
120
121 USBCallback _DrvUSBC_CBFun = NULL;
122
123 USBCallback _DrvUSB_CBFun = NULL;
124
125 void ms_ehci_irq (struct usb_hcd *pHcd, struct stPtRegs *pRegs);
126
127 static MS_U8 u8HubStackBuffer[HUB_STACK_SIZE];
128
129 //-------------------------------------------------------------------------------------------------
130 /// Register a callback function to process the usb plug event
131 /// @param pCallbackFn \b IN: callback function used in interrupt context.
132 /// @return None
133 /// @note call after USB has been initialized
134 /// The last registered callback will overwrite the previous ones.
135 //-------------------------------------------------------------------------------------------------
MDrv_USB_RegisterCallBack(USBCallback pCallbackFn)136 void MDrv_USB_RegisterCallBack (USBCallback pCallbackFn)
137 {
138 //Register a callback function for application to process the data received
139 _DrvUSB_CBFun = pCallbackFn;
140 }
141
ms_USBGetChipID(void)142 MS_U8 ms_USBGetChipID(void)
143 {
144 #if defined(USB_LIB_CHIPID)
145 return USB_LIB_CHIPID;
146 #else
147 if (gUsbChipID == 0xFF)
148 gUsbChipID = usb_readb(OS_BASE_ADDR+0x1ecc*2);
149
150 //diag_printf("GetChipID: 0x%x\n", gUsbChipID);
151 return gUsbChipID;
152 #endif
153 }
154
155 extern MS_U8 MDrv_SYS_GetChipRev(void);
ms_U4_series_usb_init(struct s_ChipUsbHostDef * pChip,MS_U8 u8Hostid)156 void ms_U4_series_usb_init(struct s_ChipUsbHostDef *pChip, MS_U8 u8Hostid)
157 {
158 unsigned int UTMI_base = pChip->reg[u8Hostid].baseUTMI;
159 unsigned int USBC_base = pChip->reg[u8Hostid].baseUSBC;
160 unsigned int UHC_base = pChip->reg[u8Hostid].baseUHC;
161 unsigned int USBBC_base = pChip->reg[u8Hostid].baseUSBBC;
162 unsigned int flag = pChip->reg[u8Hostid].iFlag;
163
164 MS_U8 chipID = pChip->chipID;
165
166 diag_printf("[USB] constant upll NLib, UTMI base %p, USBC base %p, UHC base %p, USBBC base %p\n",
167 (void *)UTMI_base, (void *)USBC_base, (void *)UHC_base, (void *)USBBC_base);
168
169 if (flag & EHCFLAG_TESTPKG)
170 {
171 usb_writew(0x2084, (void*) (UTMI_base+0x2*2));
172 usb_writew(0x0003, (void*) (UTMI_base+0x20*2));
173 }
174
175 #if _USB_HS_CUR_DRIVE_DM_ALLWAYS_HIGH_PATCH
176 /*
177 * patch for DM always keep high issue
178 * init overwrite register
179 */
180 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) & (MS_U8)(~BIT3), (void*) (UTMI_base+0x0*2)); //DP_PUEN = 0
181 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) & (MS_U8)(~BIT4), (void*) (UTMI_base+0x0*2)); //DM_PUEN = 0
182
183 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) & (MS_U8)(~BIT5), (void*) (UTMI_base+0x0*2)); //R_PUMODE = 0
184
185 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT6, (void*) (UTMI_base+0x0*2)); //R_DP_PDEN = 1
186 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT7, (void*) (UTMI_base+0x0*2)); //R_DM_PDEN = 1
187
188 usb_writeb(usb_readb((void*)(UTMI_base+0x10*2)) | BIT6, (void*) (UTMI_base+0x10*2)); //hs_txser_en_cb = 1
189 usb_writeb(usb_readb((void*)(UTMI_base+0x10*2)) & (MS_U8)(~BIT7), (void*) (UTMI_base+0x10*2)); //hs_se0_cb = 0
190
191 /* turn on overwrite mode */
192 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT1, (void*) (UTMI_base+0x0*2)); //tern_ov = 1
193 #endif
194
195 // disable battery charger function
196 if (flag & EHCFLAG_USBBC_OFF)
197 {
198 usb_writeb(usb_readb((void*)(USBBC_base+0x03*2-1)) & ~0x40, (void*) (USBBC_base+0x03*2-1));
199 usb_writeb(usb_readb((void*)(USBBC_base+0x0c*2)) & ~0x40, (void*) (USBBC_base+0x0c*2));
200 usb_writeb(usb_readb((void*)(UTMI_base+0x01*2-1)) & ~0x40, (void*) (UTMI_base+0x01*2-1));
201 }
202
203 usb_writeb(0x0a, (void*) (USBC_base)); // Disable MAC initial suspend, Reset UHC
204 usb_writeb(0x28, (void*) (USBC_base)); // Release UHC reset, enable UHC and OTG XIU function
205
206 #if 0 // don't touch UPLL setting again. set UPLL only in boot code.
207 if ((chipID == CHIPID_KRONUS) || (chipID == CHIPID_KAISERIN))
208 {
209 U16 reg_t;
210
211 usb_writeb(usb_readb((void*)(UTMI_base+0x0D*2-1)) | 0x01, (void*) (UTMI_base+0x0D*2-1)); // set reg_double_data_rate, To get better jitter performance
212
213 reg_t = usb_readw(UTMI_base+0x22*2);
214 if ((reg_t & 0x10e0) != 0x10e0)
215 usb_writew(0x10e0, (void*) (UTMI_base+0x22*2));
216 reg_t = usb_readw(UTMI_base+0x24*2);
217 if (reg_t != 0x1)
218 usb_writew(0x1, (void*) (UTMI_base+0x24*2));
219 //usb_writeb(usb_readb((void*)(UTMI_base+0x22*2)) | 0xE0, (void*) (UTMI_base+0x22*2)); // Set PLL_TEST[23:21] for enable 480MHz clock
220 //usb_writeb(usb_readb((void*)(UTMI_base+0x20*2)) | 0x02, (void*) (UTMI_base+0x20*2)); // Set PLL_TEST[1] for PLL multiplier 20X
221 //usb_writeb(0, (void*) (UTMI_base+0x21*2-1));
222 //usb_writeb(0x10, (void*) (UTMI_base+0x23*2-1));
223 //usb_writeb(0x01, (void*) (UTMI_base+0x24*2));
224 }
225 #endif
226
227 if (flag & EHCFLAG_DOUBLE_DATARATE)
228 {
229 if ((flag & EHCFLAG_DDR_MASK) == EHCFLAG_DDR_x15)
230 {
231 usb_writeb(usb_readb((void*)(UTMI_base+0x20*2)) | 0x76, (void*) (UTMI_base+0x20*2)); // Set usb bus = 480MHz x 1.5
232 }
233 else if ((flag & EHCFLAG_DDR_MASK) == EHCFLAG_DDR_x18)
234 {
235 usb_writeb(usb_readb((void*)(UTMI_base+0x20*2)) | 0x8e, (void*) (UTMI_base+0x20*2)); // Set usb bus = 480MHz x 1.8
236 }
237 //else if ((flag & EHCFLAG_DDR_MASK) == EHCFLAG_DDR_x20)
238 //{
239 // usb_writeb(usb_readb((void*)(UTMI_base+0xD*2-1)) | 0x01, (void*) (UTMI_base+0xD*2-1)); // Set usb bus = 480MHz x2
240 //}
241
242 usb_writeb(usb_readb((void*)(UTMI_base+0x2c*2)) |0x1, (void*) (UTMI_base+0x2c*2)); //Set slew rate control for overspeed (or 960MHz)
243 }
244
245 usb_writeb(usb_readb((void*)(UTMI_base+0x09*2-1)) & ~0x08, (void*) (UTMI_base+0x09*2-1)); // Disable force_pll_on
246 usb_writeb(usb_readb((void*)(UTMI_base+0x08*2)) & ~0x80, (void*) (UTMI_base+0x08*2)); // Enable band-gap current
247 usb_writeb(0xC3, (void*)(UTMI_base)); // reg_pdn: bit<15>, bit <2> ref_pdn
248 mdelay(1); // delay 1ms
249
250 usb_writeb(0x69, (void*) (UTMI_base+0x01*2-1)); // Turn on UPLL, reg_pdn: bit<9>
251 mdelay(2); // delay 2ms
252
253 usb_writeb(0x01, (void*) (UTMI_base)); // Turn all (including hs_current) use override mode
254 usb_writeb(0, (void*) (UTMI_base+0x01*2-1)); // Turn on UPLL, reg_pdn: bit<9>
255
256 usb_writeb(usb_readb((void*)(UTMI_base+0x3C*2)) | 0x01, (void*) (UTMI_base+0x3C*2)); // set CA_START as 1
257 mdelay(1); // 10 -> 1
258
259 usb_writeb(usb_readb((void*)(UTMI_base+0x3C*2)) & ~0x01, (void*) (UTMI_base+0x3C*2)); // release CA_START
260
261 while ((usb_readb((void*)(UTMI_base+0x3C*2)) & 0x02) == 0); // polling bit <1> (CA_END)
262
263 if (flag & EHCFLAG_DPDM_SWAP)
264 usb_writeb(usb_readb((void*)(UTMI_base+0x0b*2-1)) |0x20, (void*) (UTMI_base+0x0b*2-1)); // dp dm swap
265
266 usb_writeb(usb_readb((void*)(USBC_base+0x02*2)) & ~0x03, (void*) (USBC_base+0x02*2)); //UHC select enable
267 usb_writeb(usb_readb((void*)(USBC_base+0x02*2)) | 0x01, (void*) (USBC_base+0x02*2)); //UHC select enable
268
269 usb_writeb(usb_readb((void*)(UHC_base+0x40*2)) & ~0x10, (void*) (UHC_base+0x40*2)); //0: VBUS On.
270 mdelay(1); // delay 1ms
271
272 usb_writeb(usb_readb((void*)(UHC_base+0x40*2)) | 0x08, (void*) (UHC_base+0x40*2)); // Active HIGH
273 //mdelay(1); // NUSED
274
275 usb_writeb(usb_readb((void*)(UHC_base+0x81*2-1)) | 0x8F, (void*) (UHC_base+0x81*2-1)); //improve the efficiency of USB access MIU when system is busy
276
277 if ((chipID == CHIPID_KRONUS) || (chipID == CHIPID_URANUS4))
278 usb_writeb(usb_readb((void*)(UHC_base+0x83*2-1)) | 0x40, (void*) (UHC_base+0x83*2-1)); //set MIU1_sel to 128MB
279 // Kaiserin will keep the defaut "00" to be as 512MB support
280
281 usb_writeb((usb_readb((void*)(UTMI_base+0x06*2)) & 0x9F) | 0x40, (void*) (UTMI_base+0x06*2)); //reg_tx_force_hs_current_enable
282
283 usb_writeb(usb_readb((void*)(UTMI_base+0x03*2-1)) | 0x28, (void*) (UTMI_base+0x03*2-1)); //Disconnect window select
284 usb_writeb(usb_readb((void*)(UTMI_base+0x03*2-1)) & 0xef, (void*) (UTMI_base+0x03*2-1)); //Disconnect window select
285
286 usb_writeb(usb_readb((void*)(UTMI_base+0x07*2-1)) & 0xfd, (void*) (UTMI_base+0x07*2-1)); //Disable improved CDR
287 #ifdef ENABLE_UTMI_240_AS_120_PHASE_ECO
288 usb_writeb(usb_readb((void*)(UTMI_base+0x08*2)) | 0x08, (void*) (UTMI_base+0x08*2));
289 #endif
290 #if _USB_CLOCK_PHASE_ADJ_PATCH
291 if ((chipID == CHIPID_KERES) && (MDrv_SYS_GetChipRev() == 0x0))
292 usb_writeb(usb_readb((void*)(UTMI_base+0x08*2)) & ~0x08, (void*) (UTMI_base+0x08*2));
293 #endif
294
295 usb_writeb(usb_readb((void*)(UTMI_base+0x09*2-1)) |0x81, (void*) (UTMI_base+0x09*2-1)); // UTMI RX anti-dead-loc, ISI effect improvement
296 #if _USB_CLOCK_PHASE_ADJ_PATCH
297 if ((chipID == CHIPID_KERES) && (MDrv_SYS_GetChipRev() == 0x0))
298 usb_writeb(usb_readb((void*)(UTMI_base+0x0b*2-1)) & ~0x80, (void*) (UTMI_base+0x0b*2-1));
299 #else
300 if ((flag & EHCFLAG_DOUBLE_DATARATE)==0)
301 usb_writeb(usb_readb((void*)(UTMI_base+0x0b*2-1)) |0x80, (void*) (UTMI_base+0x0b*2-1)); // TX timing select latch path
302 #endif
303 usb_writeb(usb_readb((void*)(UTMI_base+0x15*2-1)) |0x20, (void*) (UTMI_base+0x15*2-1)); // Chirp signal source select
304 #ifdef ENABLE_UTMI_55_INTERFACE
305 usb_writeb(usb_readb((void*)(UTMI_base+0x15*2-1)) |0x40, (void*) (UTMI_base+0x15*2-1)); // Change to 55 interface
306 #endif
307
308 usb_writeb( UTMI_EYE_SETTING_2C, (void*) (UTMI_base+0x2c*2));
309 usb_writeb( UTMI_EYE_SETTING_2D, (void*) (UTMI_base+0x2d*2-1));
310 usb_writeb( UTMI_EYE_SETTING_2E, (void*) (UTMI_base+0x2e*2));
311 usb_writeb( UTMI_EYE_SETTING_2F, (void*) (UTMI_base+0x2f*2-1));
312
313 /* Add hardware ECO items here */
314 // Kaiserin U02 patch code (K2S only)
315 if ((chipID == CHIPID_KAISERIN) && (MDrv_SYS_GetChipRev() >= 0x01)) // && U02 and Newer IC
316 {
317 diag_printf("K2S software patch!!!\n");
318
319 // enable LS cross point ECO
320 usb_writeb(usb_readb((void*)(UTMI_base+0x39*2-1)) | 0x04, (void*) (UTMI_base+0x39*2-1)); //enable deglitch SE0��(low-speed cross point)
321
322 // enable power noise ECO
323 usb_writeb(usb_readb((void*)(USBC_base+0x02*2)) | 0x40, (void*) (USBC_base+0x02*2)); //enable use eof2 to reset state machine�� (power noise)
324
325 // enable TX/RX reset clock gating ECO
326 usb_writeb(usb_readb((void*)(UTMI_base+0x39*2-1)) | 0x02, (void*) (UTMI_base+0x39*2-1)); //enable hw auto deassert sw reset(tx/rx reset)
327
328 // enable loss short packet interrupt ECO, default 0 on
329 //usb_writeb(usb_readb((void*)(USBC_base+0x04*2)) & 0x7f, (void*) (USBC_base+0x04*2)); //enable patch for the assertion of interrupt(Lose short packet interrupt)
330
331 // enable babble ECO
332 usb_writeb(usb_readb((void*)(USBC_base+0x04*2)) | 0x40, (void*) (USBC_base+0x04*2)); //enable add patch to Period_EOF1(babble problem)
333
334 // enable MDATA single TT ECO
335 usb_writeb(usb_readb((void*)(USBC_base+0x0A*2)) | 0x40, (void*) (USBC_base+0x0A*2)); //enable short packet MDATA in Split transaction clears ACT bit (LS dev under a HS hub)
336 }
337
338 // Kaiser and Newer IC patch code
339 if ((chipID == CHIPID_KAISER))
340 {
341 diag_printf("Applied hardware ECO patch!!!\n");
342
343 // enable LS cross point ECO (manually all)
344 usb_writeb(usb_readb((void*)(UTMI_base+0x04*2)) | 0x40, (void*) (UTMI_base+0x04*2)); //enable deglitch SE0��(low-speed cross point)
345
346 // enable power noise ECO (manually all)
347 usb_writeb(usb_readb((void*)(USBC_base+0x02*2)) | 0x40, (void*) (USBC_base+0x02*2)); //enable use eof2 to reset state machine�� (power noise)
348
349 // enable TX/RX reset clock gating ECO (manually all)
350 usb_writeb(usb_readb((void*)(UTMI_base+0x04*2)) | 0x20, (void*) (UTMI_base+0x04*2)); //enable hw auto deassert sw reset(tx/rx reset)
351
352 // enable loss short packet interrupt ECO, default 0 on
353 //usb_writeb(usb_readb((void*)(USBC_base+0x04*2)) & 0x7f, (void*) (USBC_base+0x04*2)); //enable patch for the assertion of interrupt(Lose short packet interrupt)
354
355 // enable babble ECO, default on
356 //usb_writeb(usb_readb((void*)(USBC_base+0x04*2)) | 0x40, (void*) (USBC_base+0x04*2)); //enable add patch to Period_EOF1(babble problem)
357
358 // enable MDATA single TT ECO, default on
359 //writeb(readb((void*)(USBC_base+0x0A*2)) | 0x40, (void*) (USBC_base+0x0A*2)); //enable short packet MDATA in Split transaction clears ACT bit (LS dev under a HS hub)
360
361 // enable DM always high ECO
362 usb_writeb(usb_readb((void*)(UTMI_base+0x10*2)) | 0x40, (void*) (UTMI_base+0x10*2)); // monkey test
363 }
364
365 // enable miu new bridge ECO
366 #if defined(ENABLE_PV2MI_BRIDGE_ECO)
367 usb_writeb(usb_readb((void*)(USBC_base+0x0a*2)) | 0x40, (void*) (USBC_base+0xa*2)); //fix pv2mi bridge mis-behavior
368 #endif
369
370 #if _USB_HS_CUR_DRIVE_DM_ALLWAYS_HIGH_PATCH
371 /*
372 * patch for DM always keep high issue
373 * init overwrite register
374 */
375 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT6, (void*) (UTMI_base+0x0*2)); //R_DP_PDEN = 1
376 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT7, (void*) (UTMI_base+0x0*2)); //R_DM_PDEN = 1
377
378 /* turn on overwrite mode */
379 usb_writeb(usb_readb((void*)(UTMI_base+0x0*2)) | BIT1, (void*) (UTMI_base+0x0*2)); //tern_ov = 1
380 #endif
381
382 #if _USB_MINI_PV2MI_BURST_SIZE
383 usb_writeb(usb_readb((void*)(USBC_base+0x0b*2-1)) & ~(BIT1|BIT2|BIT3|BIT4), (void*)(USBC_base+0x0b*2-1));
384 #endif
385
386 #ifdef ENABLE_HS_CONNECTION_FAIL_INTO_VFALL_ECO
387 usb_writeb(usb_readb((void*)(USBC_base+0x11*2-1)) | BIT1, (void*)(USBC_base+0x11*2-1));
388 #endif
389
390 #if _USB_MIU_WRITE_WAIT_LAST_DONE_Z_PATCH
391 /* Enabe PVCI i_miwcplt wait for mi2uh_last_done_z */
392 usb_writeb(usb_readb((void*)(UHC_base+0x83*2-1)) | BIT4, (void*)(UHC_base+0x83*2-1));
393 #endif
394
395 #ifdef ENABLE_HS_DISCONNECTION_DEBOUNCE_ECO
396 usb_writeb(usb_readb((void*)(USBC_base+0x1*2-1)) | BIT4, (void*)(USBC_base+0x1*2-1));
397 #endif
398
399 #if defined(ENABLE_UHC_PREAMBLE_ECO)
400 /* [7]: reg_etron_en, to enable utmi Preamble function */
401 usb_writeb(usb_readb((void*)(UTMI_base+0x3f*2-1)) | BIT7, (void*)(UTMI_base+0x3f*2-1));
402
403 /* [3:]: reg_preamble_en, to enable Faraday Preamble */
404 usb_writeb(usb_readb((void*)(USBC_base+0x0f*2-1)) | BIT3, (void*)(USBC_base+0x0f*2-1));
405
406 /* [0]: reg_preamble_babble_fix, to patch Babble occurs in Preamble */
407 usb_writeb(usb_readb((void*)(USBC_base+0x10*2)) | BIT0, (void*)(USBC_base+0x10*2));
408
409 /* [1]: reg_preamble_fs_within_pre_en, to patch FS crash problem */
410 usb_writeb(usb_readb((void*)(USBC_base+0x10*2)) | BIT1, (void*)(USBC_base+0x10*2));
411
412 /* [2]: reg_fl_sel_override, to override utmi to have FS drive strength */
413 usb_writeb(usb_readb((void*)(UTMI_base+0x03*2-1)) | BIT2, (void*)(UTMI_base+0x03*2-1));
414 #endif
415
416 #if defined(ENABLE_HS_ISO_IN_CORNER_ECO)
417 usb_writeb(usb_readb((void*)(USBC_base+0x13*2-1)) | BIT0, (void*)(USBC_base+0x13*2-1));
418 #endif
419
420 #if defined(ENABLE_UHC_RUN_BIT_ALWAYS_ON_ECO)
421 /* Don't close RUN bit when device disconnect */
422 usb_writeb(usb_readb((void*)(UHC_base+0x34*2)) | BIT7, (void*)(UHC_base+0x34*2));
423 #endif
424
425 #if defined(ENABLE_DISCONNECT_PE_CLR_ECO)
426 /*Enable Port is disabled when device is dosconnected ECO*/
427 usb_writeb(usb_readb((void*)(USBC_base+0x12*2)) | BIT7, (void*) (USBC_base+0x12*2));
428 #endif
429
430 #if !defined(_EHC_SINGLE_SOF_TO_CHK_DISCONN)
431 /* Use 2 SOFs to check disconnection */
432 usb_writeb((usb_readb((void*)(USBC_base+0x03*2-1)) & BIT7) | (0x02<<1 | BIT0), (void*)(USBC_base+0x03*2-1));
433 #endif
434
435 #if defined(ENABLE_DISCONNECT_SPEED_REPORT_RESET_ECO)
436 /* UHC speed type report should be reset by device disconnection */
437 usb_writeb(usb_readb((void*)(USBC_base+0x20*2)) | BIT0, (void*)(USBC_base+0x20*2));
438 #endif
439
440 #if defined(ENABLE_BABBLE_PCD_ONE_PULSE_TRIGGER_ECO)
441 /* Port Change Detect (PCD) is triggered by babble.
442 * Pulse trigger will not hang this condition.
443 */
444 usb_writeb(usb_readb((void*)(USBC_base+0x20*2)) | BIT1, (void*)(USBC_base+0x20*2));
445 #endif
446
447 #if defined(ENABLE_HC_RESET_FAIL_ECO)
448 /* generation of hhc_reset_u */
449 usb_writeb(usb_readb((void*)(USBC_base+0x20*2)) | BIT2, (void*)(USBC_base+0x20*2));
450 #endif
451
452 #if defined(ENABLE_SRAM_CLK_GATING_ECO)
453 /* do SRAM clock gating automatically to save power */
454 usb_writeb(usb_readb((void*)(USBC_base+0x20*2)) & (U8)(~BIT4), (void*)(USBC_base+0x20*2));
455 #endif
456
457 if (flag & EHCFLAG_TESTPKG)
458 {
459 usb_writew(0x0210, (void*) (UTMI_base+0x2C*2)); //
460 usb_writew(0x8100, (void*) (UTMI_base+0x2E*2)); //
461
462 usb_writew(0x0600, (void*) (UTMI_base+0x14*2)); //
463 usb_writew(0x0038, (void*) (UTMI_base+0x10*2)); //
464 usb_writew(0x0BFE, (void*) (UTMI_base+0x32*2)); //
465 }
466 }
467
MDrv_Usb_Init(mem_Alloc pfn_Cachedmem_Alloc,mem_Free pfn_Cachedmem_Free,mem_Alloc pfn_NonCachedmem_Alloc,mem_Free pfn_NonCachedmem_Free,mem_VA2PA pfn_mem_VA2PA,mem_PA2VA pfn_mem_PA2VA,mem_Cached2Noncached pfn_mem_Cached2Noncached,mem_NonCached2Cached pfn_mem_NonCached2Cached)468 void MDrv_Usb_Init(
469 mem_Alloc pfn_Cachedmem_Alloc,
470 mem_Free pfn_Cachedmem_Free,
471 mem_Alloc pfn_NonCachedmem_Alloc,
472 mem_Free pfn_NonCachedmem_Free,
473 mem_VA2PA pfn_mem_VA2PA,
474 mem_PA2VA pfn_mem_PA2VA,
475 mem_Cached2Noncached pfn_mem_Cached2Noncached,
476 mem_NonCached2Cached pfn_mem_NonCached2Cached
477 )
478 {
479 diag_printf("USB initial, %d port supported\n", NUM_OF_ROOT_HUB);
480
481 pfnAllocCachedMem = pfn_Cachedmem_Alloc;
482 pfnFreeCachedMem = pfn_Cachedmem_Free;
483 pfnAllocNoncachedMem = pfn_NonCachedmem_Alloc;
484 pfnFreeNoncachedMem = pfn_NonCachedmem_Free;
485 pfnVA2PA = pfn_mem_VA2PA;
486 pfnPA2VA = pfn_mem_PA2VA;
487 pfnCached2Noncached = pfn_mem_Cached2Noncached;
488 pfnNoncached2Cached = pfn_mem_NonCached2Cached;
489
490 ms_init_sys();
491
492 USB_ASSERT(-1 == _s32UsbEventId, "USB event ID not valid!\n");
493 _s32UsbEventId = MsOS_CreateEventGroup("UHC_Event");
494
495 quirk_list_init();
496
497 diag_printf("Init USB MSC\n");
498 if (ms_usb_register(&usb_storage_driver) < 0)
499 USB_ASSERT( 0, "Init USB MSC fail..\n");
500
501 #if USB_HID_SUPPORT
502 usb_hid_init();
503 #endif
504
505 #if USB_CDC_SUPPORT
506 usb_cdc_init();
507 #endif
508
509 // Decide the current chip
510 pCurrentChip = &chipDESC;
511 #if defined(CHIP_K2)
512 diag_printf("Chip Kaiserin!\n");
513 if (MDrv_SYS_GetChipRev() >= 0x01) // U02 and Newer IC
514 {
515 // chip top performance tuning [11:9]
516 usb_writew(usb_readw((void*)(KAISERIN_CHIP_TOP_BASE+0x46*2)) | 0xe00, (void*) (KAISERIN_CHIP_TOP_BASE+0x46*2));
517 }
518 #endif
519 // set the current chipID
520 pCurrentChip->chipID = ms_USBGetChipID();
521
522 #ifdef _USB_ENABLE_BDMA_PATCH
523 /* get the registers and decide to turn on BDMA SW patch */
524 set_64bit_OBF_cipher();
525 #endif
526 // show Lib Infomation
527 diag_printf("[USB] MS USB Host Lib for %s only\n", pCurrentChip->name);
528 }
529
MDrv_UsbClose(void)530 void MDrv_UsbClose(void)
531 {
532 ms_usb_deregister(&usb_storage_driver);
533 MsOS_DeleteEventGroup(_s32UsbEventId);
534 _s32UsbEventId = -1;
535
536 ms_exit_sys();
537 diag_printf("[USB] End of MDrv_UsbClose...\n");
538 }
539
540 #if 0 // NUSED
541 /*
542 <1>.Disable RunStop
543 <1.1>. Chirp hardware patch 1
544 <2> .Write PortReset=1
545 <3>.Wait time=>50ms
546 <3.1>. Chirp hardware patch 2
547 <3.2>. Wait time=>20ms
548 <4>.Write PortReset=0
549 <4.1>. Chirp hardware patch 3
550 <5>.Waiting for PortReset==0
551 <6>.Enable RunStop Bit
552 <6.1>.reset UTMI
553 <6.2> Write RunStop Bit=1
554 <6.3>.Wait time 5ms, wait some slow device to be ready
555 <7>.Detect Speed
556 */
557 #define MSTAR_CHIRP_PATCH 1
558 #define MSTAR_EHC_RTERM_PATCH 1
559
560 int ms_PortReset(unsigned int regUTMI, unsigned int regUHC)
561 {
562 MS_U32 wTmp;
563
564 diag_printf("PortReset: UTMI 0x%x, UHC 0x%x\n", regUTMI, regUHC);
565
566 writeb(readb((void*)(regUHC+0x10*2)) | 0x1, (void*)(regUHC+0x10*2)); //Set UHC run
567
568 #if MSTAR_CHIRP_PATCH
569 writeb(0x10, (void*)(regUTMI+0x2C*2));
570 writeb(0x00, (void*)(regUTMI+0x2D*2-1));
571 writeb(0x00, (void*)(regUTMI+0x2F*2-1));
572 writeb(0x80 ,(void*)(regUTMI+0x2A*2));
573 //writeb(0x20 ,(void*)(regUTMI+0x2A*2));
574 #endif
575
576 #if (MSTAR_EHC_RTERM_PATCH)
577 writeb(readb((void*)(regUTMI+0x13*2-1))|0x70, (void*)(regUTMI+0x13*2-1));
578 #endif
579
580 // Write PortReset bit
581 writeb(readb((void*)(regUHC+0x31*2-1)) | 0x01,(void*)(regUHC+0x31*2-1));
582 mdelay(50); //shorten the reset period for Transcend USB3.0 HDD
583 #if MSTAR_CHIRP_PATCH
584 writeb(0x0 ,(void*)(regUTMI+0x2A*2));
585 #endif
586 mdelay(20);
587
588 // Clear PortReset bit
589 writeb(readb((void*)(regUHC+0x31*2-1)) & 0xfe,(void*)(regUHC+0x31*2-1));
590
591 wTmp=0;
592
593 while (1)
594 {
595 if ((readb((void*)(regUHC+0x31*2-1)) & 0x1)==0) break;
596
597 wTmp++;
598 //udelay(1);
599 if (wTmp>20000)
600 {
601 diag_printf("??? Error waiting for Bus Reset Fail...==> Reset HW Control\n");
602 //mbHost20_USBCMD_HCReset_Set();
603 writeb(readb((void*)(regUHC+0x10*2)) | 0x2,(void*)(regUHC+0x10*2));
604
605 //while(mbHost20_USBCMD_HCReset_Rd()==1);
606 while(readb((void*)(regUHC+0x10*2)) && 0x2);
607 return (1);
608 }
609 }
610
611
612 #if (MSTAR_CHIRP_PATCH)
613 writeb(readb((void*)(regUTMI+0x2c*2)) |0x10, (void*) (regUTMI+0x2c*2));
614 writeb(readb((void*)(regUTMI+0x2d*2-1)) |0x02, (void*) (regUTMI+0x2d*2-1));
615 writeb(readb((void*)(regUTMI+0x2f*2-1)) |0x81, (void*) (regUTMI+0x2f*2-1));
616 #endif
617
618 #if (MSTAR_EHC_RTERM_PATCH)
619 writeb(readb((void*)(regUTMI+0x13*2-1))&0x8F, (void*)(regUTMI+0x13*2-1));
620 #endif
621
622 writeb(readb((void*)(regUTMI+0x06*2))|0x03, (void*)(regUTMI+0x06*2)); //reset UTMI
623 writeb(readb((void*)(regUTMI+0x06*2))&(~0x03), (void*)(regUTMI+0x06*2)); //reset UTMI
624
625 writeb(readb((void*)(regUHC+0x10*2)) | 0x1, (void*)(regUHC+0x10*2)); //Set UHC run
626
627 mdelay(5); //wait some slow device to be ready
628
629 return (0);
630 }
631 #endif
632
633 extern BOOL ms_usb_get_connected_dev_state(int *pdevstate,
634 unsigned char *pDevClass, struct usb_device *pusbdev, BOOL *pIntfDrvMatched);
635
__ms_USBCriticalSectionIn(MS_U8 u8Hostid,MS_U32 WaitMs)636 MS_BOOL __ms_USBCriticalSectionIn(MS_U8 u8Hostid, MS_U32 WaitMs)
637 {
638 MS_BOOL retval = false;
639 struct s_gVar4UsbPort *pRootHub = pCurrentChip->p_roothub[u8Hostid];
640
641 retval = MsOS_ObtainMutex(pRootHub->_s32MutexUSB, WaitMs);
642
643 //lock_usb_core(); // NUSED
644
645 return retval;
646 }
647
ms_USBCriticalSectionIn_TimeOut(MS_U8 Port,MS_U32 WaitMs)648 MS_BOOL ms_USBCriticalSectionIn_TimeOut(MS_U8 Port, MS_U32 WaitMs)
649 {
650 return __ms_USBCriticalSectionIn(Port, WaitMs);
651 }
652
ms_USBCriticalSectionIn(MS_U8 Port)653 MS_BOOL ms_USBCriticalSectionIn(MS_U8 Port)
654 {
655 return __ms_USBCriticalSectionIn(Port, MSOS_WAIT_FOREVER);
656 }
657
ms_USBCriticalSectionOut(MS_U8 u8Hostid)658 void ms_USBCriticalSectionOut(MS_U8 u8Hostid)
659 {
660 struct s_gVar4UsbPort *pRootHub = pCurrentChip->p_roothub[u8Hostid];
661
662 //unlock_usb_core(); // NUSED
663 MsOS_ReleaseMutex(pRootHub->_s32MutexUSB);
664 }
665
666 // ------------------------------------------------------------------------
667
668 struct s_gVar4UsbPort gVar4UsbPort0 =
669 {
670 "USB Hub Task",
671 0,
672 { 0*MAX_USTOR, 1*MAX_USTOR},
673 "cpe_ehci",
674 "CPE_AMBA EHCI",
675 u8HubStackBuffer,
676 "USB_MUTEX",
677 };
678
679 #ifdef ENABLE_THIRD_EHC
680 MS_U8 u8HubStackBuffer_Port2[HUB_STACK_SIZE];
681 struct s_gVar4UsbPort gVar4UsbPort2 =
682 {
683 "USB Hub Task 2",
684 2,
685 { 2*MAX_USTOR, 3*MAX_USTOR},
686 "cpe_ehci_2",
687 "CPE_AMBA EHCI 2",
688 u8HubStackBuffer_Port2,
689 "USB_MUTEX_Port2",
690 };
691 #endif
692
693 static MS_U8 u8HubStackBuffer_Port1[HUB_STACK_SIZE];
694 struct s_gVar4UsbPort gVar4UsbPort1 =
695 {
696 "USB Hub Task 1",
697 1,
698 { MAX_USTOR, 2*MAX_USTOR},
699 "cpe_ehci_1",
700 "CPE_AMBA EHCI 1",
701 u8HubStackBuffer_Port1,
702 "USB_MUTEX_Port1",
703 };
704
705 #ifdef ENABLE_FOURTH_EHC
706 static MS_U8 u8HubStackBuffer_Port3[HUB_STACK_SIZE];
707 struct s_gVar4UsbPort gVar4UsbPort3 =
708 {
709 "USB Hub Task 3",
710 3,
711 { 3*MAX_USTOR, 4*MAX_USTOR},
712 "cpe_ehci_3",
713 "CPE_AMBA EHCI 3",
714 u8HubStackBuffer_Port3,
715 "USB_MUTEX_Port3",
716 };
717 #endif
718
719 #ifdef ENABLE_FIFTH_EHC
720 static MS_U8 u8HubStackBuffer_Port4[HUB_STACK_SIZE];
721 struct s_gVar4UsbPort gVar4UsbPort4 =
722 {
723 "USB Hub Task 4",
724 4,
725 { 4*MAX_USTOR, 5*MAX_USTOR},
726 "cpe_ehci_4",
727 "CPE_AMBA EHCI 4",
728 u8HubStackBuffer_Port4,
729 "USB_MUTEX_Port4",
730 };
731 #endif
732
733 /* USB host declaration by chip ID */
734 #if defined(CHIP_U4)
735 struct s_ChipUsbHostDef chipDESC =
736 {
737 CHIPID_URANUS4,
738 "URANUS4",
739 3,
740 {
741 {0, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC_NULL, E_IRQ_UHC, E_IRQ_USBC},
742 {0, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC_NULL, E_IRQ_UHC1, E_IRQ_USBC1},
743 {EHCFLAG_DPDM_SWAP, BASE_UTMI2, BASE_UHC2, BASE_USBC2, BASE_USBBC_NULL, E_IRQ_UHC2, E_IRQ_USBC2},
744 },
745 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
746 };
747 #elif defined(CHIP_K1)
748 struct s_ChipUsbHostDef chipDESC =
749 {
750 CHIPID_KRONUS,
751 "KRONUS",
752 2,
753 {
754 {EHCFLAG_DPDM_SWAP, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC_NULL, E_IRQ_UHC, E_IRQ_USBC },
755 {EHCFLAG_DPDM_SWAP, BASE_UTMI2, BASE_UHC2, BASE_USBC2, BASE_USBBC_NULL, E_IRQ_UHC2, E_IRQ_USBC2},
756 },
757 {&gVar4UsbPort0, &gVar4UsbPort1, }
758 };
759 #elif defined(CHIP_K2)
760 struct s_ChipUsbHostDef chipDESC =
761 {
762 CHIPID_KAISERIN,
763 "KAISERIN",
764 4,
765 {
766 {0, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC_NULL, E_IRQ_UHC, E_IRQ_USBC},
767 {0, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC_NULL, E_IRQ_UHC1, E_IRQ_USBC1},
768 {0, BASE_UTMI2, BASE_UHC2, BASE_USBC2, BASE_USBBC_NULL, E_IRQ_UHC2, E_IRQ_USBC2},
769 {0, BASE_UTMI3, BASE_UHC3, BASE_USBC3, BASE_USBBC_NULL, E_IRQ_UHC3, E_IRQ_USBC3},
770 },
771 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2, &gVar4UsbPort3}
772 };
773 #elif defined(CHIP_KAPPA)
774 struct s_ChipUsbHostDef chipDESC =
775 {
776 CHIPID_KAPPA,
777 "KAPPA",
778 1,
779 {
780 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KAPPA, E_IRQ_UHC, E_IRQ_USBC},
781 },
782 {&gVar4UsbPort0}
783 };
784 #elif defined(CHIP_KRITI)
785 struct s_ChipUsbHostDef chipDESC =
786 {
787 CHIPID_KRITI,
788 "KRITI",
789 1,
790 {
791 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KAPPA, E_IRQ_UHC, E_IRQ_USBC},
792 },
793 {&gVar4UsbPort0}
794 };
795 #elif defined(CHIP_KRATOS)
796 struct s_ChipUsbHostDef chipDESC =
797 {
798 CHIPID_KRATOS,
799 "KRATOS",
800 2,
801 {
802 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KRATOS, E_IRQ_UHC, E_IRQ_USBC},
803 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KRATOS, E_IRQ_UHC1, E_IRQ_USBC1},
804 },
805 {&gVar4UsbPort0, &gVar4UsbPort1}
806 };
807 #elif defined(CHIP_KELTIC)
808 struct s_ChipUsbHostDef chipDESC =
809 {
810 CHIPID_KELTIC,
811 "KELTIC",
812 1,
813 {
814 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KELTIC, E_IRQ_UHC, E_IRQ_USBC},
815 },
816 {&gVar4UsbPort0}
817 };
818 #elif defined(CHIP_KENYA)
819 struct s_ChipUsbHostDef chipDESC =
820 {
821 CHIPID_KENYA,
822 "KENYA",
823 2,
824 {
825 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KENYA, E_IRQ_UHC, E_IRQ_USBC},
826 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KENYA, E_IRQ_UHC1, E_IRQ_USBC1},
827 },
828 {&gVar4UsbPort0, &gVar4UsbPort1}
829 };
830 #elif defined(CHIP_KAISER)
831 struct s_ChipUsbHostDef chipDESC =
832 {
833 CHIPID_KAISER,
834 "KAISER",
835 3,
836 {
837 {EHCFLAG_USBBC_OFF | EHCFLAG_DPDM_SWAP, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KAISER, E_IRQ_UHC, E_IRQ_USBC},
838 {EHCFLAG_USBBC_OFF | EHCFLAG_DPDM_SWAP, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KAISER, E_IRQ_UHC1, E_IRQ_USBC1},
839 {EHCFLAG_USBBC_OFF, BASE_UTMI2, BASE_UHC2, BASE_USBC2, BASE_USBBC2_KAISER, E_IRQ_UHC2, E_IRQ_USBC2},
840 },
841 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
842 };
843 #elif defined(CHIP_KERES)
844 struct s_ChipUsbHostDef chipDESC =
845 {
846 CHIPID_KERES,
847 "KERES",
848 2,
849 {
850 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KERES, E_IRQ_UHC, E_IRQ_USBC},
851 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KERES, E_IRQ_UHC1, E_IRQ_USBC1},
852 },
853 {&gVar4UsbPort0, &gVar4UsbPort1}
854 };
855 #elif defined(CHIP_KIRIN)
856 struct s_ChipUsbHostDef chipDESC =
857 {
858 CHIPID_KIRIN,
859 "KIRIN",
860 2,
861 {
862 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KERES, E_IRQ_UHC, E_IRQ_USBC},
863 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KERES, E_IRQ_UHC1, E_IRQ_USBC1},
864 },
865 {&gVar4UsbPort0, &gVar4UsbPort1}
866 };
867 #elif defined(CHIP_KRIS)
868 struct s_ChipUsbHostDef chipDESC =
869 {
870 CHIPID_KRIS,
871 "KRIS",
872 2,
873 {
874 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KERES, E_IRQ_UHC, E_IRQ_USBC},
875 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KERES, E_IRQ_UHC1, E_IRQ_USBC1},
876 },
877 {&gVar4UsbPort0, &gVar4UsbPort1}
878 };
879 #elif defined(CHIP_KIWI)
880 struct s_ChipUsbHostDef chipDESC =
881 {
882 CHIPID_KIWI,
883 "KIWI",
884 2,
885 {
886 {EHCFLAG_USBBC_OFF | EHCFLAG_DPDM_SWAP, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KIWI, E_IRQ_UHC, E_IRQ_USBC},
887 {EHCFLAG_USBBC_OFF | EHCFLAG_DPDM_SWAP, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KIWI, E_IRQ_UHC1, E_IRQ_USBC1},
888 },
889 {&gVar4UsbPort0, &gVar4UsbPort1}
890 };
891 #elif defined(CHIP_CLIPPERS)
892 struct s_ChipUsbHostDef chipDESC =
893 {
894 CHIPID_CLIPPERS,
895 "CLIPPERS",
896 3,
897 {
898 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_CLIPPERS, E_IRQ_UHC, E_IRQ_USBC},
899 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_CLIPPERS, E_IRQ_UHC1, E_IRQ_USBC1},
900 {EHCFLAG_USBBC_OFF, BASE_UTMI2_CLIPPERS, BASE_UHC2_CLIPPERS, BASE_USBC2_CLIPPERS, BASE_USBBC2_CLIPPERS, E_IRQ_UHC2, E_IRQ_USBC2},
901 },
902 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
903 };
904 #elif defined(CHIP_CURRY)
905 struct s_ChipUsbHostDef chipDESC =
906 {
907 CHIPID_CURRY,
908 "CURRY",
909 3,
910 {
911 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_CURRY, E_IRQ_UHC, E_IRQ_USBC},
912 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_CURRY, E_IRQ_UHC1, E_IRQ_USBC1},
913 {EHCFLAG_USBBC_OFF, BASE_UTMI2_CURRY, BASE_UHC2, BASE_USBC2, BASE_USBBC2_CURRY, E_IRQ_UHC2, E_IRQ_USBC2},
914 },
915 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
916 };
917 #elif defined(CHIP_KAYLA)
918 struct s_ChipUsbHostDef chipDESC =
919 {
920 CHIPID_KAYLA,
921 "KAYLA",
922 2,
923 {
924 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KERES, E_IRQ_UHC, E_IRQ_USBC},
925 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KERES, E_IRQ_UHC1, E_IRQ_USBC1},
926 },
927 {&gVar4UsbPort0, &gVar4UsbPort1}
928 };
929 #elif defined(CHIP_KANO)
930 #if 1 // for compile
931 #define E_INT_IRQ_UHC4 0xff
932 #define E_INT_IRQ_USB4 0xff
933 #endif
934 struct s_ChipUsbHostDef chipDESC =
935 {
936 CHIPID_KANO,
937 "KANO",
938 #ifdef ENABLE_XHC_COMPANION
939 5,
940 {
941 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KANO, E_IRQ_UHC, E_IRQ_USBC, XHC_COMP_NONE},
942 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KANO, E_IRQ_UHC1, E_IRQ_USBC1, XHC_COMP_NONE},
943 {EHCFLAG_USBBC_OFF, BASE_UTMI2_KANO, BASE_UHC2, BASE_USBC2, BASE_USBBC2_KANO, E_IRQ_UHC2, E_IRQ_USBC2, XHC_COMP_NONE},
944 {EHCFLAG_USBBC_OFF | EHCFLAF_XHC_COMP, BASE_UTMI3_KANO, BASE_UHC3_KANO, BASE_USBC3_KANO, BASE_USBBC3_KANO, E_IRQ_UHC3, E_IRQ_USBC3, XHC_COMP_PORT0},
945 {EHCFLAG_USBBC_OFF | EHCFLAF_XHC_COMP, BASE_UTMI4_KANO, BASE_UHC4_KANO, BASE_USBC4_KANO, BASE_USBBC4_KANO, E_IRQ_UHC4, E_IRQ_USBC4, XHC_COMP_PORT1},
946 },
947 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2, &gVar4UsbPort3, &gVar4UsbPort4}
948 #else
949 3,
950 {
951 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KANO, E_IRQ_UHC, E_IRQ_USBC},
952 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KANO, E_IRQ_UHC1, E_IRQ_USBC1},
953 {EHCFLAG_USBBC_OFF, BASE_UTMI2_KANO, BASE_UHC2, BASE_USBC2, BASE_USBBC2_KANO, E_IRQ_UHC2, E_IRQ_USBC2},
954 },
955 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
956 #endif
957 };
958 #elif defined(CHIP_K6)
959 struct s_ChipUsbHostDef chipDESC =
960 {
961 CHIPID_K6,
962 "K6",
963 #ifdef ENABLE_XHC_COMPANION
964 3,
965 {
966 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_K6, E_IRQ_UHC, E_IRQ_USBC, XHC_COMP_NONE},
967 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_K6, E_IRQ_UHC1, E_IRQ_USBC1, XHC_COMP_NONE},
968 {EHCFLAG_USBBC_OFF | EHCFLAF_XHC_COMP, BASE_UTMI2_K6, BASE_UHC2_K6, BASE_USBC2_K6, BASE_USBBC2_K6, E_IRQ_UHC2_K6, E_IRQ_USBC2_K6, XHC_COMP_PORT0},
969 },
970 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
971 #else
972 2,
973 {
974 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_K6, E_IRQ_UHC, E_IRQ_USBC},
975 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_K6, E_IRQ_UHC1, E_IRQ_USBC1},
976 },
977 {&gVar4UsbPort0, &gVar4UsbPort1}
978 #endif
979 };
980 #elif defined(CHIP_K6LITE)
981 struct s_ChipUsbHostDef chipDESC =
982 {
983 CHIPID_K6LITE,
984 "K6LITE",
985 3,
986 {
987 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_K6LITE, E_IRQ_UHC, E_IRQ_USBC},
988 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_K6LITE, E_IRQ_UHC1, E_IRQ_USBC1},
989 {EHCFLAG_USBBC_OFF, BASE_UTMI2_K6LITE, BASE_UHC2_K6LITE, BASE_USBC2_K6LITE, BASE_USBBC2_K6LITE, E_IRQ_UHC2, E_IRQ_USBC2},
990 },
991 {&gVar4UsbPort0, &gVar4UsbPort1, &gVar4UsbPort2}
992 };
993 #elif defined(CHIP_K5TN)
994 struct s_ChipUsbHostDef chipDESC =
995 {
996 CHIPID_K5TN,
997 "K5TN",
998 2,
999 {
1000 {EHCFLAG_USBBC_OFF, BASE_UTMI0, BASE_UHC0, BASE_USBC0, BASE_USBBC0_KERES, E_IRQ_UHC, E_IRQ_USBC},
1001 {EHCFLAG_USBBC_OFF, BASE_UTMI1, BASE_UHC1, BASE_USBC1, BASE_USBBC1_KERES, E_IRQ_UHC1, E_IRQ_USBC1},
1002 },
1003 {&gVar4UsbPort0, &gVar4UsbPort1}
1004 };
1005 #else
1006 #error No USB Chip definition
1007 #endif
1008
1009 // any new chip added here ^^^
1010 //
1011
1012 /**
1013 * @brief USB port N interrupt service routine
1014 *
1015 * @param InterruptNum eIntNum
1016 *
1017 * @return none
1018 */
ms_DrvUSB_OnInterrupt_EX(InterruptNum eIntNum)1019 static void ms_DrvUSB_OnInterrupt_EX(InterruptNum eIntNum)
1020 {
1021 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1022 struct usb_hcd *hcd;
1023 MS_U8 p;
1024
1025 if (pChip == NULL)
1026 return;
1027 MsOS_DisableInterrupt(eIntNum);
1028 for (p = 0; p < pChip->nRootHub; p++)
1029 {
1030 if (eIntNum == pChip->reg[p].uhcIRQ)
1031 break;
1032 }
1033 hcd = pChip->p_roothub[p]->cpe_ehci_dev.dev.driver_data;
1034 ms_ehci_irq(hcd, NULL);
1035 MsOS_EnableInterrupt(eIntNum);
1036 }
1037
1038 /**
1039 * @brief initial USB port N interrupt service routine
1040 *
1041 * @param InterruptNum eIntNum
1042 *
1043 * @return none
1044 */
ms_InitUSBIntr_EX(struct usb_hcd * hcd,int str_on)1045 void ms_InitUSBIntr_EX(struct usb_hcd * hcd, int str_on)
1046 {
1047 ms_ehci_interrupt_enable(hcd, str_on);
1048 MsOS_AttachInterrupt(hcd->ehci_irq, ms_DrvUSB_OnInterrupt_EX);
1049 MsOS_EnableInterrupt(hcd->ehci_irq);
1050 }
1051
ms_UnInitUSBIntr_EX(struct usb_hcd * hcd)1052 void ms_UnInitUSBIntr_EX(struct usb_hcd * hcd)
1053 {
1054 MsOS_DisableInterrupt(hcd->ehci_irq);
1055 MsOS_DetachInterrupt(hcd->ehci_irq);
1056 ms_ehci_interrupt_disable(hcd);
1057 }
1058
1059 /**
1060 * @brief USB port connect status and safe guard disconnect ehci reset
1061 *
1062 * @param struct usb_hcd *hcd
1063 *
1064 * @return true/false
1065 */
ms_UsbDeviceConnect_EX(struct usb_hcd * hcd)1066 MS_BOOL ms_UsbDeviceConnect_EX(struct usb_hcd *hcd)
1067 {
1068 static MS_U32 usbStartTime = 0;
1069
1070 if (ms_RoothubPortConnected(hcd))
1071 {
1072 return TRUE;
1073 }
1074 else
1075 {
1076 if (MsOS_GetSystemTime()-usbStartTime > 1000 )
1077 {
1078 usbStartTime=MsOS_GetSystemTime();
1079 ms_ResetMstarUsb(hcd);
1080 hcd->isRootHubPortReset = TRUE;
1081 hcd->isBadDeviceRH = FALSE;
1082 hcd->isBadDevice = FALSE;
1083 hcd->badDeviceCnt = 0;
1084 }
1085 return FALSE;
1086 }
1087 }
1088
1089 extern int ms_hub_poll(struct s_gVar4UsbPort *pRootHub);
1090 /**
1091 * @brief USB port N hub event polling task
1092 *
1093 * @param MS_U32 argc
1094 * @param VOID *argv
1095 *
1096 * @return none
1097 */
ms_UsbTask_EX(MS_U32 argc,VOID * argv)1098 void ms_UsbTask_EX(MS_U32 argc, VOID *argv)
1099 {
1100 MS_BOOL isConnect;
1101 int DevState, numConnDev;
1102 MS_U8 DevClass = USB_INTERFACE_CLASS_NONE;
1103 MS_U8 kk;
1104 #if USB_HID_SUPPORT
1105 MS_BOOL isHIDPlugIn;
1106 #endif
1107 struct s_gVar4UsbPort *pRootHub = (struct s_gVar4UsbPort *) argc;
1108 const MS_U8 hostID = pRootHub->hostid;
1109
1110 diag_printf("UTask EX>> ... port %d starting\n", hostID);
1111 while (pRootHub->taskRunning)
1112 {
1113 #if USB_HID_SUPPORT
1114 isHIDPlugIn = FALSE;
1115 #endif
1116
1117 // Waiting for USB port connection
1118 while(pRootHub->taskRunning)
1119 {
1120 ms_USBCriticalSectionIn(hostID);
1121 isConnect = ms_UsbDeviceConnect_EX(pRootHub->p_UsbHcd);
1122 ms_USBCriticalSectionOut(hostID);
1123
1124 #if USBC_IP_SUPPORT // USBC IP control
1125 if ((pCurrentChip->usbc_ip[hostID].portNum == hostID) && (pCurrentChip->usbc_ip[hostID].eventFlag))
1126 if (_DrvUSBC_CBFun)
1127 {
1128 if (pCurrentChip->usbc_ip[hostID].eventType)
1129 _DrvUSBC_CBFun(USBC_NON_OVER_CURRENT, hostID, NULL);
1130 else
1131 _DrvUSBC_CBFun(USBC_OVER_CURRENT, hostID, NULL);
1132 pCurrentChip->usbc_ip[hostID].eventFlag = 0;
1133 }
1134 #endif
1135 if(isConnect)
1136 break;
1137 #ifdef USB_SYSTEM_STR_SUPPORT
1138 if (pCurrentChip->u8Park)
1139 pRootHub->bPark_ok = TRUE;
1140 #endif
1141 MsOS_DelayTask(100);
1142 }
1143
1144 // removing any delay before USB bus reset
1145 //MsOS_DelayTask(1000);
1146 diag_printf("UTask EX>> USB Port %d is connected\n", hostID);
1147
1148 while (pRootHub->taskRunning)
1149 {
1150 #ifdef USB_SYSTEM_STR_SUPPORT
1151 while(pCurrentChip->u8Park)
1152 {
1153 pRootHub->bPark_ok = TRUE;
1154 MsOS_DelayTask(50);
1155 }
1156 #endif
1157
1158 if (pRootHub->p_UsbHcd->isBadDeviceRH)
1159 {
1160 diag_printf("UTask EX>> A bad device found on root port %d\n", pRootHub->hostid);
1161 break;
1162 }
1163
1164 kk = 0;
1165 while(kk<HUB_DEBOUNCE_STABLE)
1166 {
1167 ms_USBCriticalSectionIn(hostID);
1168 isConnect = ms_RoothubPortConnected(pRootHub->p_UsbHcd);
1169 ms_USBCriticalSectionOut(hostID);
1170 if ( !isConnect )
1171 {
1172 #if USB_MASS_STORAGE_SUPPORT
1173 if (pRootHub->taskRunning) // guard for port close
1174 ms_MSC_fast_device_disconnect(pRootHub->vPortRange.vPortDevStart, pRootHub->vPortRange.vPortDevEnd);
1175 #endif
1176 goto PORT_DISCONNECT_EX;
1177 }
1178 kk++;
1179 MsOS_DelayTask(HUB_DEBOUNCE_STEP);
1180 }
1181
1182 // Device is connecting to the port
1183 numConnDev = 0;
1184 if (pRootHub->taskRunning) // guard for port close
1185 numConnDev = ms_hub_poll(pRootHub);
1186
1187 announce_new_dev:
1188 // Mass storage disk mount
1189 #if USB_MASS_STORAGE_SUPPORT
1190 if (pRootHub->taskRunning) // guard for port close
1191 ms_MSC_device_inquiry(pRootHub->vPortRange.vPortDevStart, pRootHub->vPortRange.vPortDevEnd);
1192 #endif
1193
1194 #if USB_HID_SUPPORT
1195 // TODO: correct HIDGlue API pointer type
1196 //if (pRootHub->p_UsbHcd == pCurrentChip->p_roothub[pRootHub->hostid]->cpe_ehci_dev.dev.driver_data)
1197 // diag_printf("Yes, matched\n");
1198 if (pRootHub->taskRunning) // guard for port close
1199 isHIDPlugIn = ms_HID_device_in_inquiry((void *)pRootHub->p_UsbHcd, isHIDPlugIn);
1200 #endif
1201
1202 while (numConnDev-- && pRootHub->taskRunning)
1203 {
1204 USB_ASSERT(numConnDev>=0, "BUG()!!!! numConndev<0\n");
1205 BOOL IntfDrvMatched = FALSE;
1206
1207 if ( ms_usb_get_connected_dev_state(&DevState, &DevClass, pRootHub->arConnDev[numConnDev].connDev, &IntfDrvMatched) )
1208 {
1209 if (DevState < USB_STATE_CONFIGURED)
1210 {
1211 diag_printf("UTask EX>> Usb device not configured (dev#%d)\n", numConnDev);
1212 if (pRootHub->p_UsbHcd->isBadDevice || pRootHub->p_UsbHcd->isBadDeviceRH)
1213 {
1214 diag_printf("UTask EX>> Usb device no responding (dev#%d)\n", numConnDev);
1215 if ( _DrvUSB_CBFun != NULL )
1216 _DrvUSB_CBFun(USB_PLUG_IN, USB_EVENT_DEV_NO_RESPONSE, NULL);
1217 }
1218 }
1219 else
1220 {
1221 switch (DevClass)
1222 {
1223 #if USB_MASS_STORAGE_SUPPORT
1224 case USB_INTERFACE_CLASS_MSD: // list of device class supported
1225 #endif
1226 #if USB_HID_SUPPORT
1227 case USB_INTERFACE_CLASS_HID:
1228 #endif
1229 break;
1230 #ifndef USB_NOT_SUPPORT_EX_HUB
1231 case USB_INTERFACE_CLASS_HUB:
1232 diag_printf("UTask EX>> Port %d external Hub is connected (dev#%d)\n", hostID, numConnDev);
1233 break;
1234 #endif
1235 default:
1236 diag_printf("UTask EX>> found Non-classical deivce (dev#%d)\n", numConnDev);
1237 if ( _DrvUSB_CBFun != NULL )
1238 {
1239 if(IntfDrvMatched == TRUE)
1240 {
1241 diag_printf("UTask EX>> Usb device Vendor supported (dev#%d)\n", numConnDev);
1242 _DrvUSB_CBFun(USB_PLUG_IN, USB_EVENT_DEV_TYPE_VENDOR, NULL);
1243 }
1244 else
1245 {
1246 diag_printf("UTask EX>> Usb device not supported (dev#%d)\n", numConnDev);
1247 _DrvUSB_CBFun(USB_PLUG_IN, USB_EVENT_DEV_TYPE_UNKNOW, NULL);
1248 }
1249 }
1250 }
1251 }
1252 }
1253 }
1254
1255 #if USBC_IP_SUPPORT // USBC IP control
1256 if ((pCurrentChip->usbc_ip[hostID].portNum == hostID) && (pCurrentChip->usbc_ip[hostID].eventFlag))
1257 if (ms_RoothubPortConnected(pRootHub->p_UsbHcd))
1258 if (_DrvUSBC_CBFun)
1259 {
1260 if (pCurrentChip->usbc_ip[hostID].eventType)
1261 _DrvUSBC_CBFun(USBC_NON_OVER_CURRENT, hostID, NULL);
1262 else
1263 _DrvUSBC_CBFun(USBC_OVER_CURRENT, hostID, NULL);
1264 pCurrentChip->usbc_ip[hostID].eventFlag = 0;
1265 }
1266 #endif
1267
1268 //MsOS_DelayTask(1000);
1269 }
1270
1271 PORT_DISCONNECT_EX:
1272 diag_printf("UTask EX>> USB root port %d disconnecting...\n", hostID);
1273 //if (pRootHub->taskRunning)
1274 //{
1275 // MsOS_DelayTask(100); //By Jonas! for hub event!
1276 //}
1277 //else
1278 //{
1279 //MsOS_DelayTask(600); //By Jonas! for hub event!
1280 //}
1281 numConnDev = 0;
1282 if (pRootHub->taskRunning) // guard for port close
1283 numConnDev = ms_hub_poll(pRootHub); //for disconnect hub event
1284
1285 #if USB_HID_SUPPORT
1286 if (pRootHub->taskRunning) // guard for port close
1287 ms_HID_device_out_inquiry((void *)pRootHub->p_UsbHcd, isHIDPlugIn);
1288 #endif
1289
1290 if(numConnDev != 0)
1291 {
1292 diag_printf("[USB] get new device after disconnecting...\n");
1293 goto announce_new_dev;
1294 }
1295
1296 //device is disconnected
1297 kk = 0;
1298 while(pRootHub->taskRunning)
1299 {
1300 ms_USBCriticalSectionIn(hostID);
1301 isConnect = ms_RoothubPortConnected(pRootHub->p_UsbHcd);
1302 ms_USBCriticalSectionOut(hostID);
1303 if(isConnect == FALSE)
1304 {
1305 diag_printf("UTask EX>> device plug out!\n");
1306 break;
1307 }
1308 if (pRootHub->p_UsbHcd->isBadDeviceRH && (kk % 10 == 0))
1309 {
1310 diag_printf("UTask EX>> a bad device waiting plug-out!\n");
1311 }
1312 #ifdef USB_SYSTEM_STR_SUPPORT
1313 if (pCurrentChip->u8Park)
1314 pRootHub->bPark_ok = TRUE;
1315 #endif
1316 MsOS_DelayTask(100);
1317 kk++;
1318 }
1319 if (pRootHub->p_UsbHcd) // guard for port close
1320 {
1321 ms_USBCriticalSectionIn(hostID);
1322 diag_printf("UTask EX>> reset ms USB\n");
1323 /* enable QH Head re-link flow */
1324 pRootHub->p_UsbHcd->rh_disconn = 1;
1325 ms_ResetMstarUsb(pRootHub->p_UsbHcd);
1326 pRootHub->p_UsbHcd->rh_disconn = 0;
1327 ms_USBCriticalSectionOut(hostID);
1328 }
1329
1330 }
1331 diag_printf("UTask EX>> ... port %d finished\n", hostID);
1332 pRootHub->taskFinish = TRUE;
1333 }
1334
1335 /**
1336 * @brief creating USB mutex for selected port
1337 *
1338 * @param U8 port
1339 *
1340 * @return USB mutex
1341 */
ms_Create_USB_Mutex(MS_U8 u8Hostid)1342 MS_S32 ms_Create_USB_Mutex(MS_U8 u8Hostid)
1343 {
1344 struct s_gVar4UsbPort *pRootHub = pCurrentChip->p_roothub[u8Hostid];
1345
1346 return pRootHub->_s32MutexUSB = MsOS_CreateMutex(E_MSOS_FIFO, pRootHub->usb_mutex_name, MSOS_PROCESS_SHARED);
1347 }
1348
1349 /**
1350 * @brief deleting USB mutex for selected port
1351 *
1352 * @param U8 port
1353 *
1354 * @return none
1355 */
ms_Delete_USB_Mutex(MS_U8 u8Hostid)1356 void ms_Delete_USB_Mutex(MS_U8 u8Hostid)
1357 {
1358 struct s_gVar4UsbPort *pRootHub = pCurrentChip->p_roothub[u8Hostid];
1359
1360 MsOS_DeleteMutex(pRootHub->_s32MutexUSB);
1361 }
1362
1363 /**
1364 * @brief creating USB port N hub event polling task
1365 *
1366 * @param struct s_gVar4UsbPort *pRootHub
1367 *
1368 * @return none
1369 */
ms_USB_Start_EX(struct s_gVar4UsbPort * pRootHub)1370 void ms_USB_Start_EX(struct s_gVar4UsbPort *pRootHub)
1371 {
1372 MS_U8 *HubStack;
1373
1374 diag_printf("\nUsb start EX..., pRootHub = %x\n\n", (unsigned int)pRootHub);
1375
1376 HubStack = pRootHub->u8pHubStackBuffer;
1377
1378 if (ms_Create_USB_Mutex(pRootHub->hostid) < 0)
1379 {
1380 diag_printf("create USB mutex failed\n");
1381 GEN_EXCEP;
1382 return;
1383 }
1384
1385 //Create Task
1386 pRootHub->taskRunning = TRUE;
1387 pRootHub->taskFinish = FALSE;
1388
1389 pRootHub->pid = MsOS_CreateTask((TaskEntry) ms_UsbTask_EX,
1390 (MS_U32)pRootHub,
1391 E_TASK_PRI_HIGH,
1392 TRUE,
1393 HubStack,
1394 HUB_STACK_SIZE,
1395 pRootHub->name);
1396 if (pRootHub->pid < 0)
1397 {
1398 diag_printf("create USB Task failed\n");
1399 ms_Delete_USB_Mutex(pRootHub->hostid);
1400 GEN_EXCEP;
1401 return;
1402 }
1403 }
1404
ms_USB_Stop_EX(struct s_gVar4UsbPort * pRootHub)1405 void ms_USB_Stop_EX(struct s_gVar4UsbPort *pRootHub)
1406 {
1407 while(!pRootHub->taskFinish)
1408 {
1409 MsOS_DelayTask(100);
1410 }
1411 diag_printf("[ms_USB_Stop_EX] DeleteTask ++\n");
1412 /* 20150608 remove MsOS_DeleteTask per system's request */
1413 //MsOS_DeleteTask(pRootHub->pid);
1414 pRootHub->pid = -1;
1415 ms_USBCriticalSectionIn(pRootHub->hostid);
1416 ms_USBCriticalSectionOut(pRootHub->hostid);
1417 ms_Delete_USB_Mutex(pRootHub->hostid);
1418 diag_printf("[ms_USB_Stop_EX] delete Mutex --\n");
1419 }
1420
1421
1422 extern int ms_create_cpe_hcd(struct cpe_dev *dev);
1423 extern void ms_usb_hcd_cpe_ehci_remove (struct usb_hcd *pHcd);
1424
1425 /**
1426 * @brief USB port N initial
1427 *
1428 * @param MS_U8 u8PortNum
1429 *
1430 * @return true/false
1431 */
MDrv_USB_Port_Init(MS_U8 u8Hostid)1432 MS_BOOL MDrv_USB_Port_Init(MS_U8 u8Hostid)
1433 {
1434 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1435
1436 if (pChip->nRootHub <= u8Hostid)
1437 {
1438 diag_printf("Chip %s does not not support port %d\n", pChip->name, u8Hostid);
1439 return FALSE;
1440 }
1441 else
1442 {
1443 diag_printf("Init chip %s, port %d\n", pChip->name, u8Hostid);
1444 // bind chip reg definition with cpe_dev
1445 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.uhcbase = pChip->reg[u8Hostid].baseUHC;
1446 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.utmibase = pChip->reg[u8Hostid].baseUTMI;
1447 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.usbcbase = pChip->reg[u8Hostid].baseUSBC;
1448 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.intNum = pChip->reg[u8Hostid].uhcIRQ;
1449 }
1450 /* initial hub event list */
1451 ms_list_init(&pChip->p_roothub[u8Hostid]->hub_event);
1452 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.pHubEvent = &pChip->p_roothub[u8Hostid]->hub_event;
1453 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.bus_name = pChip->p_roothub[u8Hostid]->bus_name;
1454 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.product_desc = pChip->p_roothub[u8Hostid]->product_desc;
1455 pChip->p_roothub[u8Hostid]->cpe_ehci_dev.devid = pChip->p_roothub[u8Hostid]->hostid;
1456
1457 // do Usb Host initial
1458 ms_U4_series_usb_init(pChip, u8Hostid);
1459
1460 #ifdef ENABLE_XHC_COMPANION
1461 if(pChip->reg[u8Hostid].iFlag & EHCFLAF_XHC_COMP)
1462 {
1463 //enable xHCI clock
1464 xhci_enable_clock();
1465 //disable port
1466 xhci_ssport_set_state(&pChip->reg[u8Hostid].xhci, false);
1467 //turn on power
1468 xhci_ppc(&pChip->reg[u8Hostid].xhci, true);
1469 }
1470 #endif
1471
1472 ms_create_cpe_hcd(&pChip->p_roothub[u8Hostid]->cpe_ehci_dev); // create hcd base on cpe info
1473 if (pChip->p_roothub[u8Hostid]->cpe_ehci_dev.dev.driver_data == NULL)
1474 {
1475 diag_printf("port %d hcd not allocated!!!\n", u8Hostid);
1476 return FALSE;
1477 }
1478 pChip->p_roothub[u8Hostid]->p_UsbHcd = pChip->p_roothub[u8Hostid]->cpe_ehci_dev.dev.driver_data; // for MDrv_UsbDeviceConnect()
1479
1480 ms_USB_Start_EX(pChip->p_roothub[u8Hostid]);
1481
1482 return TRUE;
1483 }
1484
1485 /**
1486 * @brief Halt USB port N
1487 *
1488 * @param MS_U8 u8Hostid
1489 *
1490 * @return true/false
1491 */
MDrv_USB_Port_Close(MS_U8 u8Hostid)1492 MS_BOOL MDrv_USB_Port_Close(MS_U8 u8Hostid)
1493 {
1494 struct s_gVar4UsbPort *pRootHub = pCurrentChip->p_roothub[u8Hostid];
1495 struct usb_hcd *pHcd = pRootHub->p_UsbHcd;
1496
1497 diag_printf("[USB] try to shutdown UHC(%d)\n", u8Hostid);
1498
1499 if(!pHcd)
1500 {
1501 diag_printf("[USB] Error UHC%d is not inited ??\n", u8Hostid);
1502 return FALSE;
1503 }
1504
1505 pRootHub->taskRunning= FALSE;
1506 pHcd->state = HCD_STATE_HALT; // speed up port close flow
1507 ms_usb_set_device_state(pHcd->self.root_hub, USB_STATE_NOTATTACHED);
1508 diag_printf("[USB] disable Port %d interrupt\n", u8Hostid);
1509 ms_UnInitUSBIntr_EX(pHcd);
1510
1511 diag_printf("[USB] ms_USB_Stop_EX(%d)\n", u8Hostid);
1512 ms_USB_Stop_EX(pRootHub);
1513
1514 #ifdef ENABLE_XHC_COMPANION
1515 if(pCurrentChip->reg[u8Hostid].iFlag & EHCFLAF_XHC_COMP)
1516 {
1517 //turn off power
1518 xhci_ppc(&pCurrentChip->reg[u8Hostid].xhci, false);
1519 //enable port
1520 xhci_ssport_set_state(&pCurrentChip->reg[u8Hostid].xhci, true);
1521 mdelay(1000);
1522 }
1523 #endif
1524
1525 diag_printf("[USB] ms_usb_hcd_cpe_ehci_remove\n");
1526 ms_usb_hcd_cpe_ehci_remove(pHcd);
1527
1528 pRootHub->cpe_ehci_dev.dev.driver_data = NULL;
1529 pRootHub->p_UsbHcd = NULL;
1530 diag_printf("[USB] End of MDrv_USB_Port_Close(%d)\n", u8Hostid);
1531 return TRUE;
1532 }
1533
1534 extern void ms_init_usbc_intr(MS_U8 p);
1535 /**
1536 * @brief register call back function of over current detection
1537 *
1538 * @param USBCallback pCallbackFn
1539 * @param MS_U8 port_mask
1540 *
1541 * @return none
1542 */
MDrv_OverCurrentDetect_RegisterCallBack(USBCallback pCallbackFn,MS_U8 port_mask)1543 void MDrv_OverCurrentDetect_RegisterCallBack (USBCallback pCallbackFn, MS_U8 port_mask)
1544 {
1545 #if USBC_IP_SUPPORT // USBC IP control
1546 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1547 MS_U8 p;
1548
1549 diag_printf("<MDrv_OverCurrentDetect_RegisterCallBack> %p, port_mask(%x)\n", pCallbackFn, port_mask);
1550 _DrvUSBC_CBFun = pCallbackFn;
1551 for (p = 0; p < pChip->nRootHub; p++)
1552 if (port_mask & (1<<p))
1553 ms_init_usbc_intr(p);
1554 #else
1555 diag_printf("<MDrv_OverCurrentDetect_RegisterCallBack> NOT support!!! Please turn on USBC_IP_SUPPORT in drvUSB.h\n");
1556 #endif
1557 }
1558
1559 /**
1560 * @brief return connection bit for portN
1561 *
1562 * @param MS_U8 u8Hostid
1563 *
1564 * @return connection bit
1565 */
1566
MDrv_UsbDeviceConnectBitEx(MS_U8 u8Hostid)1567 int MDrv_UsbDeviceConnectBitEx(MS_U8 u8Hostid)
1568 {
1569 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1570 struct usb_hcd *hcd;
1571
1572 if (pChip == NULL)
1573 {
1574 diag_printf("[USB] Error!!! pChip is Null\n");
1575 return -1;
1576 }
1577
1578 hcd = pChip->p_roothub[u8Hostid]->cpe_ehci_dev.dev.driver_data;
1579
1580 if(hcd == NULL)
1581 {
1582 diag_printf("[USB] Error!!! hcd is Null, host_id %d\n", u8Hostid);
1583 return -1;
1584 }
1585
1586 if(ms_RoothubPortConnected(hcd))
1587 return 1;
1588
1589 return 0;
1590 }
1591
1592 #ifdef USB_SYSTEM_STR_SUPPORT
MDrv_Usb_STR_Off(MS_U8 u8Hostid)1593 void MDrv_Usb_STR_Off(MS_U8 u8Hostid)
1594 {
1595 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1596 struct usb_hcd *hcd;
1597
1598 if (pChip == NULL)
1599 {
1600 diag_printf("[USB] Error!!! pChip is Null\n");
1601 return;
1602 }
1603 hcd = pChip->p_roothub[u8Hostid]->cpe_ehci_dev.dev.driver_data;
1604
1605 if(hcd == NULL)
1606 {
1607 diag_printf("[USB] Error!!! hcd is Null, host_id %d\n", u8Hostid);
1608 return;
1609 }
1610 diag_printf("[USB] STR off...port %d\n", u8Hostid);
1611 pChip->u8Park = 1;
1612 hcd->state = HCD_STATE_HALT; // spped up urb flow
1613 diag_printf("[USB] STR waiting for park ");
1614 while(pChip->p_roothub[u8Hostid]->bPark_ok == FALSE)
1615 {
1616 diag_printf(".");
1617 MsOS_DelayTask(50);
1618 }
1619 diag_printf(" ok\n");
1620 ms_UnInitUSBIntr_EX(hcd);
1621 }
1622
1623 extern void ms_ehci_periodic_size_init (struct usb_hcd *hcd);
MDrv_Usb_STR_On(MS_U8 u8Hostid)1624 void MDrv_Usb_STR_On(MS_U8 u8Hostid)
1625 {
1626 struct s_ChipUsbHostDef *pChip = pCurrentChip;
1627 struct usb_hcd *hcd;
1628
1629 if (pChip == NULL)
1630 {
1631 diag_printf("[USB] Error!!! pChip is Null\n");
1632 return;
1633 }
1634 hcd = pChip->p_roothub[u8Hostid]->cpe_ehci_dev.dev.driver_data;
1635
1636 if(hcd == NULL)
1637 {
1638 diag_printf("[USB] Error!!! hcd is Null, host_id %d\n", u8Hostid);
1639 return;
1640 }
1641 diag_printf("[USB] STR on...port %d\n", u8Hostid);
1642 ms_U4_series_usb_init(pChip, u8Hostid);
1643 ms_ehci_periodic_size_init(hcd);
1644 ms_InitUSBIntr_EX(hcd, 1);
1645 hcd->isBadDeviceRH = FALSE;
1646 pChip->u8Park = 0;
1647 pChip->p_roothub[u8Hostid]->bPark_ok = FALSE;
1648 }
1649 #endif
1650
1651