xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/newhost/drvUSBHwCtl.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 //#include <MsCommon.h> // NUSED
80 #include "drvUSBHwCtl.h"
81 #include "drvEHCI.h"
82 //#include "drvUSB.h" // NUSED
83 /* applying drvUSB.h (inside drvUSBHwCtl.h) */
84 
85 #ifdef _USB_ENABLE_BDMA_PATCH
86 #include <drvBDMA.h>
87 #endif
88 
ms_XBYTE_OR(MS_U32 Addr,MS_U8 offset,MS_U8 val)89 void ms_XBYTE_OR(MS_U32 Addr, MS_U8 offset, MS_U8 val)
90 {
91     MS_U16 temp;
92 
93     if (offset & 1)
94     {
95         temp=*(MS_U16 volatile   *)(Addr+(offset-1)*2);
96         *(MS_U16 volatile   *)(Addr+(offset-1)*2)=(((MS_U16)val)<<8) | (temp );
97     }
98     else
99     {
100         temp=*(MS_U16 volatile   *)(Addr+offset*2);
101         *(MS_U16 volatile   *)(Addr+offset*2)=(temp )|val;
102      }
103 }
104 
ms_XBYTE_AND(MS_U32 Addr,MS_U8 offset,MS_U8 val)105 void ms_XBYTE_AND(MS_U32 Addr, MS_U8 offset,MS_U8 val)
106 {
107     MS_U16 temp;
108 
109     if (offset &1)
110     {
111         temp=*(MS_U16 volatile   *)(Addr+(offset-1)*2);
112         *(MS_U16 volatile   *)(Addr+(offset-1)*2)=((((MS_U16)val)<<8)|0xff) & (temp );
113     }
114     else
115     {
116         temp=*(MS_U16 volatile   *)(Addr+offset*2);
117         *(MS_U16 volatile   *)(Addr+offset*2)=(temp & (0xff00|val) );
118 
119      }
120 }
121 
ms_XBYTE_SET(MS_U32 Addr,MS_U8 offset,MS_U8 val)122 void ms_XBYTE_SET(MS_U32 Addr, MS_U8 offset,MS_U8 val)
123 {
124     MS_U16 temp;
125 
126     if (offset &1)
127     {
128         temp=*(MS_U16 volatile   *)(Addr+(offset-1)*2);
129         *(MS_U16 volatile   *)(Addr+(offset-1)*2)=((temp & 0x00ff) | (((MS_U16)val)<<8));
130     }
131     else
132     {
133         temp=*(MS_U16 volatile   *)(Addr+offset*2);
134         *(MS_U16 volatile   *)(Addr+offset*2)=((temp & 0xff00) |val );
135      }
136 }
137 
ms_XBYTE_READ(MS_U32 Addr,MS_U8 offset)138 MS_U8 ms_XBYTE_READ(MS_U32 Addr, MS_U8 offset)
139 {
140     MS_U16 temp;
141     MS_U8  uRetVal = 0;
142 
143     if (offset &1)
144     {
145         temp=*(MS_U16 volatile   *)(Addr+(offset-1)*2);
146         uRetVal = (MS_U8) (temp >> 8);
147     }
148     else
149     {
150         temp=*(MS_U16 volatile   *)(Addr+offset*2);
151         uRetVal = (MS_U8) temp;
152     }
153 
154     //diag_printf("XBYTE_READ: Addr: %X, offset: %X, uRetVal: %X\n", Addr, offset, uRetVal);
155     return uRetVal;
156 }
157 // ------------------------------------------------------------------------
ms_RH_force_FSmode(struct usb_hcd * hcd,int enable)158 void ms_RH_force_FSmode(struct usb_hcd *hcd, int enable)
159 {
160 	U32 temp;
161 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
162 
163 	temp = hcd_reg_readl((U32)&ehci->op_regs->bus_control);
164 	if (enable) {
165 		hcd->isFSmode = 1;
166 		temp |= 0x80; //force enter FSmode
167 		diag_printf("[USB] force enter FSmode!\n");
168 	}
169 	else {
170 		hcd->isFSmode = 0;
171 		temp &= ~0x80;
172 		diag_printf("[USB] leave FSmode!\n");
173 	}
174 	hcd_reg_writel(temp, (U32)&ehci->op_regs->bus_control);
175 }
176 
177 extern void ms_ehci_softrst(struct ehci_hcd *);
ms_ResetMstarUsb(struct usb_hcd * hcd)178 void ms_ResetMstarUsb(struct usb_hcd *hcd)
179 {
180 	/* disable force enter FSmode, 20130220 place here */
181 	if (hcd->isFSmode)
182 		ms_RH_force_FSmode(hcd, 0);
183 	ms_ehci_softrst(hcd_to_ehci(hcd));
184 }
185 
ms_RoothubPortConnected(struct usb_hcd * hcd)186 inline BOOL ms_RoothubPortConnected(struct usb_hcd *hcd)
187 {
188     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
189     U32 regv;
190 
191     regv = hcd_reg_readw((U32)&ehci->op_regs->portsc[0]);
192     return (regv & PORTSC_CONNECT) ? TRUE : FALSE;
193 }
194 
ms_RoothubPortConnectChg(struct usb_hcd * hcd)195 inline BOOL ms_RoothubPortConnectChg(struct usb_hcd *hcd)
196 {
197     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
198     U32 regv;
199 
200     regv = hcd_reg_readw((U32)&ehci->op_regs->portsc[0]);
201     return (regv & PORTSC_CSC) ? TRUE : FALSE;
202 }
203 
ms_RoothubPortEnabled(struct usb_hcd * hcd)204 inline BOOL ms_RoothubPortEnabled(struct usb_hcd *hcd)
205 {
206     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
207     U32 regv;
208 
209     regv = hcd_reg_readw((U32)&ehci->op_regs->portsc[0]);
210     return (regv & PORTSC_PE) ? TRUE : FALSE;
211 }
212 
ms_isHcdRunning(struct usb_hcd * hcd)213 inline BOOL ms_isHcdRunning(struct usb_hcd *hcd)
214 {
215     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
216     U32 regv;
217 
218     regv = hcd_reg_readw((U32)&ehci->op_regs->usbcmd);
219     return (regv & USBCMD_RUN) ? TRUE : FALSE;
220 }
221 
ms_forceHcdRun(struct usb_hcd * hcd)222 inline void ms_forceHcdRun(struct usb_hcd *hcd)
223 {
224     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
225     U32 regv;
226 
227     regv = hcd_reg_readw((U32)&ehci->op_regs->usbsts);
228     if (regv & USBSTS_HALT)
229     {
230         //diag_printf("[UM-disconnect] force RUN!!!\n");
231         hcd_reg_writel(USBCMD_RUN | hcd_reg_readl((U32)&ehci->op_regs->usbcmd),
232             (U32)&ehci->op_regs->usbcmd);
233     }
234 }
235 
236 #ifdef DEBUG
ms_dumpHcdRegister(struct usb_hcd * hcd)237 inline void ms_dumpHcdRegister(struct usb_hcd *hcd)
238 {
239     struct ehci_hcd *ehci = hcd_to_ehci(hcd);
240 
241     diag_printf("[UM] usbcmd = %x\n", hcd_reg_readl((U32)&ehci->op_regs->usbcmd));
242     diag_printf("[UM] status = %x\n", hcd_reg_readl((U32)&ehci->op_regs->usbsts));
243     diag_printf("[UM] portsc = %x\n", hcd_reg_readl((U32)&ehci->op_regs->portsc[0]));
244 }
245 #endif
246 
247 // ------------------------------------------------------------------------
248 
ms_UTMI_ORXBYTE_EX(MS_U8 offset,MS_U8 val,MS_U32 base)249 void ms_UTMI_ORXBYTE_EX(MS_U8 offset,MS_U8 val, MS_U32 base)
250 {
251     ms_XBYTE_OR(base, offset, val);
252 }
253 
ms_UTMI_ANDXBYTE_EX(MS_U8 offset,MS_U8 val,MS_U32 base)254 void ms_UTMI_ANDXBYTE_EX(MS_U8 offset,MS_U8 val, MS_U32 base)
255 {
256     ms_XBYTE_AND(base, offset, val);
257 }
258 
ms_UTMI_SETXBYTE_EX(MS_U8 offset,MS_U8 val,MS_U32 base)259 void ms_UTMI_SETXBYTE_EX(MS_U8 offset,MS_U8 val, MS_U32 base)
260 {
261     ms_XBYTE_SET(base, offset, val);
262 }
263 
ms_UTMI_READXBYTE_EX(MS_U8 offset,MS_U32 base)264 MS_U8 ms_UTMI_READXBYTE_EX(MS_U8 offset, MS_U32 base)
265 {
266     return ms_XBYTE_READ(base, offset);
267 }
268 
ms_ehci_interrupt_enable(struct usb_hcd * hcd,int str_on)269 void ms_ehci_interrupt_enable (struct usb_hcd *hcd, int str_on)
270 {
271     struct ehci_hcd  *pEhci = hcd_to_ehci (hcd);
272     U32 u32Reg_t;
273 
274     u32Reg_t = (HOST20_USBINTR_IntOnAsyncAdvance |
275             HOST20_USBINTR_SystemError |
276             HOST20_USBINTR_PortChangeDetect |
277             HOST20_USBINTR_USBError |
278             HOST20_USBINTR_CompletionOfTransaction);
279     hcd_reg_writel (u32Reg_t, (U32)&pEhci->op_regs->usbintr);
280 
281     if (!str_on)
282         return;
283 
284     u32Reg_t = hcd_reg_readl((U32)&pEhci->op_regs->usbsts);
285     hcd_reg_writel (u32Reg_t, (U32)&pEhci->op_regs->usbsts); //clear all pending interrupt
286 
287     u32Reg_t = hcd_reg_readl((U32)&pEhci->op_regs->bus_control);
288     u32Reg_t|= INT_POLAR;
289     hcd_reg_writel (u32Reg_t, (U32)&pEhci->op_regs->bus_control); // set interrupt polarity high
290 }
291 
ms_ehci_interrupt_disable(struct usb_hcd * hcd)292 void ms_ehci_interrupt_disable (struct usb_hcd *hcd)
293 {
294     struct ehci_hcd  *pEhci = hcd_to_ehci (hcd);
295     U32 u32Reg_t;
296     hcd_reg_writel (0, (U32)&pEhci->op_regs->usbintr);
297 
298     u32Reg_t = hcd_reg_readl((U32)&pEhci->op_regs->usbsts);
299     hcd_reg_writel (u32Reg_t, (U32)&pEhci->op_regs->usbsts); //clear all pending interrupt
300 }
301 
302 /*
303   * @brief          ehci controller reset
304   *
305   * @param          struct usb_hcd *pHcd
306   *
307   * @return         none
308   */
309 extern void ms_qh_ehci_reinit(struct usb_hcd *, int);
ms_roothub_disconn_reinit(struct usb_hcd * pHcd)310 void ms_roothub_disconn_reinit(struct usb_hcd *pHcd)
311 {
312 	struct ehci_hcd *pEhci = hcd_to_ehci (pHcd);
313 	U32 t_portsc, t_uhcsts;
314 
315 	//diag_printf("root hub reinitial [usbdis]\n");
316 	t_portsc = hcd_reg_readl ((U32)&pEhci->op_regs->portsc [0]);
317 	t_uhcsts = hcd_reg_readl(((U32)&pEhci->op_regs->usbcmd)+0x76);
318 	//ms_qh_ehci_reinit(pHcd, 0); // deleted 20150505
319 	ms_qh_ehci_reinit(pHcd, 1); // check again
320 	/* check if HC falls into abnormal state, if yes, do HC reset */
321 	if ((t_portsc == 0x8) && ((t_uhcsts & 0xc00) == 0xc00)) {
322 		/* to simulate MStar linux patch
323 		* ms_ehci_end(pHcd);
324 		* ms_ehci_init(pHcd);
325 		* ms_ehci_begin(pHcd);
326 		*/
327 		ms_ResetMstarUsb(pHcd); // reset ehci
328 		diag_printf("IN-NAK reset UHC\n");
329 	}
330 }
331 
332 #ifdef _USB_ENABLE_BDMA_PATCH
m_BDMA_write(unsigned int s,unsigned int t)333 void m_BDMA_write(unsigned int s, unsigned int t)
334 #if 1 // BDMA API
335 {
336 	BDMA_Result ret;
337 
338 	ret = MDrv_BDMA_MemCopy(s, t, 4);
339 	if (ret != E_BDMA_OK) {
340 		diag_printf("[BDMA] write retuen fail (%d)!\n", ret);
341 	}
342 }
343 #else
344 {
345 //#define BDMA_RIU_BASE (MSTAR_PM_BASE+0x100900*2) // CH0
346 #define BDMA_RIU_BASE (_MSTAR_PM_BASE+0x100920*2) // CH1
347 #define MIU1_PHY_BASE_ADDR (0x40000000)
348 	int s_miu1, t_miu1, t_off2;
349 
350         //diag_printf("[USB] s %x, t %x\n", s, t);
351 	while (readw((void*)(BDMA_RIU_BASE+0x2*2)) & 0x1) {
352 		/* do nothing when last BDMA event not done */
353 	}
354 	/* decide which miu and calculate physical address */
355 	s_miu1 = (s >= MIU1_PHY_BASE_ADDR) ? 1 : 0;
356 	t_miu1 = (t >= MIU1_PHY_BASE_ADDR) ? 1 : 0;
357 	t_off2 = 0x4040 | s_miu1 | (t_miu1 << 8);
358 	s = s_miu1 ? (s - MIU1_PHY_BASE_ADDR) : s;
359 	t = t_miu1 ? (t - MIU1_PHY_BASE_ADDR) : t;
360         writew(t_off2, (void*)(BDMA_RIU_BASE+0x4*2));
361 	/* source address */
362         writew(s & 0xffff, (void*)(BDMA_RIU_BASE+0x8*2));
363         writew((s>>16) & 0xffff, (void*)(BDMA_RIU_BASE+0xA*2));
364 	/* destination address */
365         writew(t & 0xffff, (void*)(BDMA_RIU_BASE+0xC*2));
366         writew((t>>16) & 0xffff, (void*)(BDMA_RIU_BASE+0xE*2));
367 	/* transfer size by byte */
368         writew(0x4, (void*)(BDMA_RIU_BASE+0x10*2));
369 
370 	/* clear status */
371         writeb(readb((void*)(BDMA_RIU_BASE+0x2*2)) | 0x1c, (void*)(BDMA_RIU_BASE+0x2*2));
372 
373 	/* fire once */
374         writew(readw((void*)(BDMA_RIU_BASE)) | 0x1, (void*)(BDMA_RIU_BASE));
375 	while (1) {
376 		if ((readw((void*)(BDMA_RIU_BASE+0x2*2)) & 0x8) == 0x8)
377 			break;
378 	}
379 }
380 #endif
381 
382 static int en_64bit_OBF_cipher;
set_64bit_OBF_cipher(void)383 void set_64bit_OBF_cipher(void)
384 {
385 	int retv = 0;
386 	unsigned int tmp_t, tmp1_t;
387 
388 	tmp_t = readl((void*)(MIU0_RIU_BASE+MIU_DRAMOBF_READY_OFFSET));
389 	tmp1_t = readl((void*)(MIU0_RIU_BASE+MIU_64BIT_CIPHER_OFFSET));
390 	//diag_printf("[MIU0] offset(2A) = %x\n", tmp_t);
391 	//diag_printf("[MIU0] offset(D8) = %x\n", tmp1_t);
392 	if ((tmp_t & MIU_DRAMOBF_READY_BIT) != 0 &&
393 		(tmp1_t & MIU_64BIT_CIPHER_BIT) != 0)
394 		retv = 1;
395 	else
396 		retv = 0;
397 
398 	#if defined(EHCI_CHECK_MIU1) && (EHCI_CHECK_MIU1 == 1)
399 	tmp_t = readl((void*)(MIU1_RIU_BASE+MIU_DRAMOBF_READY_OFFSET));
400 	tmp1_t = readl((void*)(MIU1_RIU_BASE+MIU_64BIT_CIPHER_OFFSET));
401 	//diag_printf("[MIU1] offset(2A) = %x\n", tmp_t);
402 	//diag_printf("[MIU1] offset(D8) = %x\n", tmp1_t);
403 	if ((tmp_t & MIU_DRAMOBF_READY_BIT) != 0 &&
404 		(tmp1_t & MIU_64BIT_CIPHER_BIT) != 0)
405 		retv = retv ? 1 : 0;
406 	else
407 		retv = 0;
408 	#endif
409 
410 	en_64bit_OBF_cipher = retv;
411 	diag_printf("[MIU] 64-bit OBF cipher enabled!\n");
412 
413 	#if defined(EHCI_CHECK_ECO_VER) && (EHCI_CHECK_ECO_VER == 1)
414 	tmp_t = readl((void*)(CHIP_VER_TOP+CHIP_VER_OFFSET));
415 	tmp_t = (tmp_t >> CHIP_VER_SHIFT) & CHIP_VER_MASK;
416 	USB_ASSERT(tmp_t >= CHIP_BDMA_ECO_VER,
417 		"[BDMA] Chip ECO version %d NOT correct!\n");
418 	#endif
419 }
420 
get_64bit_OBF_cipher(void)421 int get_64bit_OBF_cipher(void)
422 {
423 	return en_64bit_OBF_cipher;
424 }
425 #endif
426 
427 #if USBC_IP_SUPPORT // USBC control
ms_usbc_irq(MS_U32 regUTMI,MS_U32 regUSBC,struct s_UsbcInfo * pUsbc)428 void ms_usbc_irq(MS_U32 regUTMI, MS_U32 regUSBC, struct s_UsbcInfo *pUsbc)
429 {
430     U16 status, vbus_t;
431 
432     pUsbc->intSts = status = usb_readw((void*)(regUSBC+0x6*2));
433     vbus_t = usb_readw((void*)(regUTMI+0x30*2)) & 0x20;  // bit[5]
434     pUsbc->eventType = vbus_t ? 1 : 0;
435     diag_printf("<usbc_irq> status change(%x) vbus(%x)\n", status, vbus_t);
436     status &= pUsbc->intEn;
437     usb_writew(status, (void*)(regUSBC+0x6*2)); // write 1 clear status
438     if (status)
439         pUsbc->eventFlag = 1;
440 }
441 
442 extern struct s_ChipUsbHostDef *pCurrentChip;
ms_usbc_on_intr(InterruptNum eIntNum)443 void ms_usbc_on_intr(InterruptNum eIntNum)
444 {
445     struct s_ChipUsbHostDef *pChip = pCurrentChip;
446     MS_U8 p;
447 
448     if (pChip == NULL)
449         return;
450     MsOS_DisableInterrupt(eIntNum);
451     for (p = 0; p < pChip->nRootHub; p++)
452     {
453         if (eIntNum == pChip->reg[p].usbcIRQ)
454             break;
455     }
456     ms_usbc_irq(pChip->reg[p].baseUTMI, pChip->reg[p].baseUSBC, &pChip->usbc_ip[p]);
457     MsOS_EnableInterrupt(eIntNum);
458 
459 }
ms_init_usbc_intr(MS_U8 p)460 void ms_init_usbc_intr(MS_U8 p)
461 {
462     struct s_ChipUsbHostDef *pChip = pCurrentChip;
463     struct s_UsbcInfo *pUsbc = &pChip->usbc_ip[p];
464     InterruptNum intNum = pChip->reg[p].usbcIRQ;
465     MS_U32 regUSBC = pChip->reg[p].baseUSBC;
466 
467     pUsbc->portNum = p;
468     pUsbc->eventFlag = 0;
469     pUsbc->intEn = USBCINTR_VBusValidChange;
470     //pUsbc->intEn = USBCINTR_AValidChange; // for testing
471     pUsbc->int_pol = 1;
472 
473     diag_printf("<init_usbc_intr> port: %d, enable %x\n", p, pUsbc->intEn);
474     //usb_writeb((pUsbc->int_pol << 2) || usb_readb((void*)(regUSBC+0x2*2)), (void*)(regUSBC+0x2*2)); // set interrupt polarity
475     usb_writew(pUsbc->intEn, (void*)(regUSBC+0x6*2)); // clear interrupt status
476     usb_writew(pUsbc->intEn, (void*)(regUSBC+0x4*2)); // set interrupt enable
477     MsOS_AttachInterrupt(intNum, ms_usbc_on_intr);
478     MsOS_EnableInterrupt(intNum);
479 }
480 #endif
481 
482 #ifdef ENABLE_XHC_COMPANION
483 //------- xHCI --------
xhci_ppc(struct xhc_comp * xhci,int bOn)484 void xhci_ppc(struct xhc_comp *xhci, int bOn)
485 {
486    MS_U16 addr_w, bit_num;
487    MS_U32 addr, gpio_addr;
488    MS_U8  value, low_active;
489 
490 
491    switch (xhci->port_index) {
492    case 0:
493        addr_w = usb_readw((void*)(xhci->u3top_base+0xFC*2));
494        addr = (MS_U32)addr_w << 8;
495        addr_w = usb_readw((void*)(xhci->u3top_base+0xFE*2));
496        addr |= addr_w & 0xFF;
497        bit_num = (addr_w >> 8) & 0x7;
498        low_active = (MS_U8)((addr_w >> 11) & 0x1);
499        break;
500    case 1:
501        addr_w = usb_readw((void*)(xhci->u3top_base+0xE6*2));
502        addr = (MS_U32)addr_w << 8;
503        addr_w = usb_readw((void*)(xhci->u3top_base+0xE8*2));
504        addr |= addr_w & 0xFF;
505        bit_num = (addr_w >> 8) & 0x7;
506        low_active = (MS_U8)((addr_w >> 11) & 0x1);
507        break;
508    default:        /* "can't happen" */
509        return;
510    }
511 
512    if (addr)
513    {
514        diag_printf("xhci_ppc: turn %s USB3.0 port %d power \n", (bOn) ? "on" : "off", xhci->port_index);
515        diag_printf("Addr: 0x%x bit_num: %d low_active:%d\n", addr, bit_num, low_active);
516 
517        value = (MS_U8)(1 << bit_num);
518        if (addr & 0x1)
519            gpio_addr = _MSTAR_PM_BASE+addr*2-1;
520        else
521            gpio_addr = _MSTAR_PM_BASE+addr*2;
522 
523        if (low_active^bOn)
524        {
525            usb_writeb(usb_readb((void*)gpio_addr) | value, (void*)gpio_addr);
526        }
527        else
528        {
529            usb_writeb(usb_readb((void*)gpio_addr) & (MS_U8)(~value), (void*)gpio_addr);
530        }
531    }
532    else {
533        diag_printf("\n\n!!!! ERROR : xhci: no GPIO information for vbus port power control  !!!! \n\n");
534        return;
535    }
536 }
537 
U3phy_MS28_init(struct xhc_comp * xhci)538 void U3phy_MS28_init(struct xhc_comp *xhci)
539 {
540 #ifdef XHCI_SINGLE_PORT_ENABLE_MAC
541         writeb(readb((void*)(xhci->u3phy_D_base+0x84*2))|0x40, (void*)(xhci->u3phy_D_base+0x84*2)); // open XHCI MAC clock
542 #endif
543 
544 	//-- 28 hpm mstar only---
545 	writew(0x0104, (void*) (xhci->u3phy_A_base+0x6*2));  // for Enable 1G clock pass to UTMI //[2] reg_pd_usb3_purt [7:6] reg_gcr_hpd_vsel
546 
547 	//U3phy initial sequence
548 	writew(0x0,    (void*) (xhci->u3phy_A_base)); 		 // power on rx atop
549 	writew(0x0,    (void*) (xhci->u3phy_A_base+0x2*2));	 // power on tx atop
550 	//writew(0x0910, (void*) (U3PHY_D_base+0x4*2));        // the same as default
551 	writew(0x0,    (void*) (xhci->u3phy_A_base+0x3A*2));  // overwrite power on rx/tx atop
552 	writew(0x0160, (void*) (xhci->u3phy_D_base+0x18*2));
553 	writew(0x0,    (void*) (xhci->u3phy_D_base+0x20*2));	 // power on u3_phy clockgen
554 	writew(0x0,    (void*) (xhci->u3phy_D_base+0x22*2));	 // power on u3_phy clockgen
555 
556 #ifdef XHCI_ENABLE_PD_OVERRIDE
557         writew(0x308,    (void*) (xhci->u3phy_A_base+0x3A*2)); // [9,8,3] PD_TXCLK_USB3TXPLL, PD_USB3_IBIAS, PD_USB3TXPLL override enable
558         writeb(readb((void*)(xhci->u3phy_A_base+0x3*2-1)) & 0xbb,     (void*)(xhci->u3phy_A_base+0x3*2-1)); // override value 0
559 #endif
560 	writeb(0xF4,   (void*) (xhci->u3phy_D_base+0x12*2));	  //TX lock threshold
561 }
562 
xhci_enable_clock(void)563 void xhci_enable_clock(void)
564 {
565 	static int clock_enable = 0;
566 #ifdef XHCI_PORT0_ADDR
567 	struct xhc_comp xc = XHC_COMP_PORT0;
568 #endif
569 #ifdef XHCI_PORT1_ADDR
570 	struct xhc_comp xc1 = XHC_COMP_PORT1;
571 #endif
572 
573 	if (clock_enable)
574 		return;
575 
576 #ifdef XHCI_PORT0_ADDR
577 	diag_printf("xhci_enable_clock\n");
578 	U3phy_MS28_init(&xc);
579 	clock_enable = 1;
580 #endif
581 #ifdef XHCI_PORT1_ADDR
582 	#ifdef XHCI_2PORTS
583 	U3phy_MS28_init(&xc1);
584 	#endif
585 #endif
586 }
587 
xhci_port_state_to_neutral(MS_U32 state)588 MS_U32 xhci_port_state_to_neutral(MS_U32 state)
589 {
590     /* Save read-only status and port state */
591     return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS);
592 }
593 
xhci_ssport_set_state(struct xhc_comp * xhci,int bOn)594 void xhci_ssport_set_state(struct xhc_comp *xhci, int bOn)
595 {
596     MS_U32 temp;
597 
598     temp = readl((void*)(xhci->xhci_port_addr));
599     diag_printf("port status 0x%lx: 0x%lx\n", xhci->xhci_port_addr, temp);
600     if (bOn) {
601         if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_SS_DISABLED) {
602 
603             temp = xhci_port_state_to_neutral(temp);
604             temp &= ~PORT_PLS_MASK;
605             temp |= PORT_LINK_STROBE | USB_SS_PORT_LS_RX_DETECT;
606 
607             writel(temp, (void*)(xhci->xhci_port_addr));
608 
609             wait_ms(10);
610             temp = readl((void*)(xhci->xhci_port_addr));
611             diag_printf("port status: 0x%lx\n", temp);
612         }
613     } else {
614         if ((temp & PORT_PLS_MASK) != USB_SS_PORT_LS_SS_DISABLED) {
615 
616             temp = xhci_port_state_to_neutral(temp);
617             writel(temp | PORT_PE, (void*)(xhci->xhci_port_addr));
618 
619             wait_ms(10);
620             temp = readl((void*)(xhci->xhci_port_addr));
621             diag_printf("port status: 0x%lx\n", temp);
622         }
623     }
624 }
625 //--------------------
626 #endif
627