xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/newhost/drvUSBEntry.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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