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