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 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
80 #include "include/drvPorts.h"
81 #include "drvEHCI.h"
82
83 #if 1
84
ehci_hcd_free(struct usb_hcd * hcd)85 void ehci_hcd_free (struct usb_hcd *hcd)
86 {
87 kfree (hcd_to_ehci (hcd));
88 }
89
90 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_hcd_alloc(void)91 struct usb_hcd *ehci_hcd_alloc (void)
92 {
93
94 struct ehci_hcd *ehci;
95
96 ehci = (struct ehci_hcd *)
97 kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
98
99 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
100 if (ehci != 0)
101 {
102 diag_printf("ehci: %lx\n", (U32) ehci);
103 memset (ehci, 0, sizeof (struct ehci_hcd));
104 //ehci->hcd.product_desc = "EHCI Host Controller";
105 memcpy(ehci->hcd.product_desc, "EHCI Host Controller", sizeof(ehci->hcd.product_desc));
106 return &ehci->hcd;
107 }
108
109 return 0;
110 }
111 static __inline__ void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma);
112
113 /*-------------------------------------------------------------------------*/
114 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_qtd_alloc(struct ehci_hcd * ehci,int flags)115 static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
116 {
117 struct ehci_qtd *qtd;
118 dma_addr_t dma;
119
120 qtd = (struct ehci_qtd*) pci_pool_alloc (ehci->qtd_pool, flags, &dma);
121 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
122 if (qtd != 0)
123 {
124 ehci_qtd_init (qtd, dma);
125 }
126
127 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
128 return qtd;
129 }
130
131
ehci_qtd_init(struct ehci_qtd * qtd,dma_addr_t dma)132 static __inline__ void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
133 {
134 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
135 memset (qtd, 0, sizeof *qtd);
136 qtd->qtd_dma = dma;
137 qtd->hw_token = CPUToLE32 (QTD_STS_HALT);
138 qtd->hw_next = EHCI_LIST_END;
139 qtd->hw_alt_next = EHCI_LIST_END;
140 INIT_LIST_HEAD (&qtd->qtd_list);
141 }
142
143 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_qtd_free(struct ehci_hcd * ehci,struct ehci_qtd * qtd)144 static __inline__ void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
145 {
146 pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
147 }
148
149
ehci_qh_alloc(struct ehci_hcd * ehci,int flags)150 static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
151 {
152 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
153 struct ehci_qh *qh;
154 dma_addr_t dma;
155
156 qh = (struct ehci_qh *)
157 pci_pool_alloc (ehci->qh_pool, flags, &dma);
158 if (!qh)
159 return qh;
160
161 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
162 memset (qh, 0, sizeof *qh);
163 atomic_set (&qh->refcount, 1);
164 qh->qh_dma = dma;
165 // INIT_LIST_HEAD (&qh->qh_list);
166 diag_printf("qh: %p, qh->qh_dma: %p\n", (MS_U32)qh, qh->qh_dma);
167 INIT_LIST_HEAD (&qh->qtd_list);
168
169 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
170 qh->dummy = ehci_qtd_alloc (ehci, flags);
171 if (qh->dummy == 0)
172 {
173 ehci_dbg (ehci, "no dummy td%s%s","\n","");
174 pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
175 qh = 0;
176 }
177
178 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
179 return qh;
180 }
181
182 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
qh_get(struct ehci_qh * qh)183 static __inline__ struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
184 {
185 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
186 atomic_inc (&qh->refcount);
187 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
188 return qh;
189 }
190
191 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
qh_put(struct ehci_hcd * ehci,struct ehci_qh * qh)192 static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
193 {
194 if (!atomic_dec_and_test (&qh->refcount))
195 return;
196 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
197 if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr)
198 {
199 ehci_dbg (ehci, "unused qh not empty%s%s","!","\n");
200 BUG ();
201 }
202
203 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
204 if (qh->dummy)
205 ehci_qtd_free (ehci, qh->dummy);
206
207 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
208 pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
209 }
210
211 /*-------------------------------------------------------------------------*/
212
213 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_mem_cleanup(struct ehci_hcd * ehci)214 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
215 {
216 if (ehci->async)
217 qh_put (ehci, ehci->async);
218 ehci->async = 0;
219
220 /* PCI consistent memory and pools */
221 if (ehci->qtd_pool)
222 pci_pool_destroy (ehci->qtd_pool);
223 ehci->qtd_pool = 0;
224
225 if (ehci->qh_pool) {
226 pci_pool_destroy (ehci->qh_pool);
227 ehci->qh_pool = 0;
228 }
229
230 if (ehci->itd_pool)
231 pci_pool_destroy (ehci->itd_pool);
232 ehci->itd_pool = 0;
233
234 if (ehci->sitd_pool)
235 pci_pool_destroy (ehci->sitd_pool);
236 ehci->sitd_pool = 0;
237
238 if (ehci->periodic)
239 {
240 /*
241 pci_free_consistent (ehci->hcd.pdev,
242 ehci->periodic_size * sizeof (u32),
243 ehci->periodic, ehci->periodic_dma);
244 ehci->periodic = 0;
245 */
246 //free(ehci->periodic_rptr);
247 hcd_buffer_free(&ehci->hcd.self, ehci->periodic_size * sizeof (void *), ehci->periodic, ehci->periodic_dma);
248 }
249 ehci->periodic = 0;
250 ehci->periodic_dma = 0;
251
252 /* shadow periodic table */
253 if (ehci->pshadow)
254 kfree (ehci->pshadow);
255 ehci->pshadow = 0;
256 }
257
258 /*******************************************************************************
259 * Function name: alloc_ehci_periodic
260 * returns :
261 * Created by : Peter Liao
262 * Date created : 2003/12/10
263 * Description : It will allocate memory for ohci hcca (32-byte boundary) from
264 * global memory.(32-byte boundary)
265 * Notes :
266 ******************************************************************************/
267 /*
268 static struct u32 *alloc_ehci_periodic(struct ohci_hcca **rptr,unsigned long size)
269 {
270 *rptr = (struct u32 *)malloc(size+32);
271 if ( *rptr != NULL ) {
272 return (struct u32 *)( (u32)((char *)(*rptr) + 31) & ~31 );
273 }
274 else {
275 return NULL;
276 }
277 }
278 */
279
280
281 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_mem_init(struct ehci_hcd * ehci,int flags)282 static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
283 {
284
285 U32 i;
286
287 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
288 vdbg("Creat Page memory poof for qtd%s","\n");
289 ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev,
290 sizeof (struct ehci_qtd),
291 32 /* byte alignment (for hw parts) */,
292 4096 /* can't cross 4K */);
293 if (!ehci->qtd_pool)
294 {
295 goto fail;
296 }
297
298 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
299 vdbg("Creat Page memory poof for qh%s","\n");
300 ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev,
301 sizeof (struct ehci_qh),
302 32 /* byte alignment (for hw parts) */,
303 4096 /* can't cross 4K */);
304 if (!ehci->qh_pool)
305 {
306 goto fail;
307 }
308 ehci->async = ehci_qh_alloc (ehci, flags);
309 if (!ehci->async)
310 {
311 goto fail;
312 }
313
314 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
315 vdbg("Creat Page memory poof for itd%s","\n");
316 ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev,
317 sizeof (struct ehci_itd),
318 32 /* byte alignment (for hw parts) */,
319 4096 /* can't cross 4K */);
320 if (!ehci->itd_pool)
321 {
322 goto fail;
323 }
324 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
325 vdbg("Creat Page memory poof for sitd%s","\n");
326 ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev,
327 sizeof (struct ehci_sitd),
328 32 /* byte alignment (for hw parts) */,
329 4096 /* can't cross 4K */);
330 if (!ehci->sitd_pool)
331 {
332 goto fail;
333 }
334
335 /* Hardware periodic table */
336 /*
337 ehci->periodic = (u32 *)
338 pci_alloc_consistent (ehci->hcd.pdev,
339 ehci->periodic_size * sizeof (u32),
340 &ehci->periodic_dma);
341 */
342 /*
343 ehci->periodic = alloc_ehci_periodic ( ehci->periodic_rptr, ehci->periodic_size * sizeof (u32));
344 ehci->periodic_dma = ehci->periodic;
345 */
346 ehci->periodic = (U32*) hcd_buffer_alloc(&ehci->hcd.self,ehci->periodic_size * sizeof (void *),0,&ehci->periodic_dma);
347 //ehci->periodic_dma = (dma_addr_t) ehci->periodic; //Note_HC_Test
348 vdbg("Allocate a non-cacheable memory poof for periodic frame list array %p\n",ehci->periodic);
349 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
350 if (ehci->periodic == 0)
351 {
352 goto fail;
353 }
354 for (i = 0; i < ehci->periodic_size; i++)
355 ehci->periodic [i] = EHCI_LIST_END;
356
357 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
358 ehci->pshadow = (union ehci_shadow *) kmalloc (ehci->periodic_size * sizeof (void *), flags);
359 if (ehci->pshadow == 0)
360 {
361 goto fail;
362 }
363 memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
364 return 0;
365
366 fail:
367 ehci_dbg (ehci, "couldn't init memory%s","");
368 ehci_mem_cleanup (ehci);
369 return -ENOMEM;
370 }
371 #endif //#ifdef
372
373