Root/package/platform/lantiq/ltq-hcd/src/ifxusb_cif_d.c

1/*****************************************************************************
2 ** FILE NAME : ifxusb_cif_d.c
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
5 ** SRC VERSION : 3.2
6 ** DATE : 1/Jan/2011
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : The Core Interface provides basic services for accessing and
9 ** managing the IFX USB hardware. These services are used by the
10 ** Peripheral Controller Driver only.
11 ** FUNCTIONS :
12 ** COMPILER : gcc
13 ** REFERENCE : Synopsys DWC-OTG Driver 2.7
14 ** COPYRIGHT : Copyright (c) 2010
15 ** LANTIQ DEUTSCHLAND GMBH,
16 ** Am Campeon 3, 85579 Neubiberg, Germany
17 **
18 ** This program is free software; you can redistribute it and/or modify
19 ** it under the terms of the GNU General Public License as published by
20 ** the Free Software Foundation; either version 2 of the License, or
21 ** (at your option) any later version.
22 **
23 ** Version Control Section **
24 ** $Author$
25 ** $Date$
26 ** $Revisions$
27 ** $Log$ Revision history
28 *****************************************************************************/
29
30/*
31 * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
32 * For this code the following notice is applicable:
33 *
34 * ==========================================================================
35 *
36 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
37 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
38 * otherwise expressly agreed to in writing between Synopsys and you.
39 *
40 * The Software IS NOT an item of Licensed Software or Licensed Product under
41 * any End User Software License Agreement or Agreement for Licensed Product
42 * with Synopsys or any supplement thereto. You are permitted to use and
43 * redistribute this Software in source and binary forms, with or without
44 * modification, provided that redistributions of source code must retain this
45 * notice. You may not view, use, disclose, copy or distribute this file or
46 * any information contained herein except pursuant to this license grant from
47 * Synopsys. If you do not agree with this notice, including the disclaimer
48 * below, then you are not authorized to use the Software.
49 *
50 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
51 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
54 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 * DAMAGE.
61 * ========================================================================== */
62
63/*!
64 \file ifxusb_cif_d.c
65 \ingroup IFXUSB_DRIVER_V3
66 \brief This file contains the interface to the IFX USB Core.
67*/
68
69#include <linux/version.h>
70#include "ifxusb_version.h"
71
72
73#include <asm/byteorder.h>
74#include <asm/unaligned.h>
75
76#ifdef __DEBUG__
77    #include <linux/jiffies.h>
78#endif
79
80#include "ifxusb_plat.h"
81#include "ifxusb_regs.h"
82#include "ifxusb_cif.h"
83
84#include "ifxpcd.h"
85
86
87
88/*!
89 \brief Initializes the DevSpd field of the DCFG register depending on the PHY type
90 and the enumeration speed of the device.
91 \param _core_if Pointer of core_if structure
92 */
93void ifxusb_dev_init_spd(ifxusb_core_if_t *_core_if)
94{
95    uint32_t val;
96    dcfg_data_t dcfg;
97
98    IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
99    if (_core_if->params.speed == IFXUSB_PARAM_SPEED_FULL)
100        /* High speed PHY running at full speed */
101        val = 0x1;
102    else
103        /* High speed PHY running at high speed and full speed*/
104        val = 0x0;
105
106    IFX_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
107    dcfg.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dcfg);
108    dcfg.b.devspd = val;
109    ifxusb_wreg(&_core_if->dev_global_regs->dcfg, dcfg.d32);
110}
111
112
113/*!
114 \brief This function enables the Device mode interrupts.
115 \param _core_if Pointer of core_if structure
116 */
117void ifxusb_dev_enable_interrupts(ifxusb_core_if_t *_core_if)
118{
119    gint_data_t intr_mask ={ .d32 = 0};
120    ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
121
122    IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
123    IFX_DEBUGPL(DBG_CIL, "%s()\n", __func__);
124
125    /* Clear any pending OTG Interrupts */
126    ifxusb_wreg( &global_regs->gotgint, 0xFFFFFFFF);
127
128    /* Clear any pending interrupts */
129    ifxusb_wreg( &global_regs->gintsts, 0xFFFFFFFF);
130
131    /* Enable the interrupts in the GINTMSK.*/
132    intr_mask.b.modemismatch = 1;
133    intr_mask.b.conidstschng = 1;
134    intr_mask.b.wkupintr = 1;
135    intr_mask.b.disconnect = 1;
136    intr_mask.b.usbsuspend = 1;
137
138    intr_mask.b.usbreset = 1;
139    intr_mask.b.enumdone = 1;
140    intr_mask.b.inepintr = 1;
141    intr_mask.b.outepintr = 1;
142    intr_mask.b.erlysuspend = 1;
143    #ifndef __DED_FIFO__
144        #ifndef __DED_INTR__
145            intr_mask.b.epmismatch = 1;
146        #endif
147    #endif
148
149    ifxusb_mreg( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
150    IFX_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, ifxusb_rreg( &global_regs->gintmsk));
151}
152
153/*!
154 \brief Gets the current USB frame number. This is the frame number from the last SOF packet.
155 \param _core_if Pointer of core_if structure
156 */
157uint32_t ifxusb_dev_get_frame_number(ifxusb_core_if_t *_core_if)
158{
159    dsts_data_t dsts;
160    IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
161    dsts.d32 = ifxusb_rreg(&_core_if->dev_global_regs->dsts);
162    /* read current frame/microfreme number from DSTS register */
163    return dsts.b.soffn;
164}
165
166
167/*!
168 \brief Set the EP STALL.
169 */
170void ifxusb_dev_ep_set_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _is_in)
171{
172    depctl_data_t depctl;
173    volatile uint32_t *depctl_addr;
174
175    IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
176
177    depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
178                            (&(_core_if->out_ep_regs[_epno]->doepctl));
179    depctl.d32 = ifxusb_rreg(depctl_addr);
180    depctl.b.stall = 1;
181
182    if (_is_in && depctl.b.epena)
183        depctl.b.epdis = 1;
184
185    ifxusb_wreg(depctl_addr, depctl.d32);
186    IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
187    return;
188}
189
190/*!
191\brief Clear the EP STALL.
192 */
193void ifxusb_dev_ep_clear_stall(ifxusb_core_if_t *_core_if, uint8_t _epno, uint8_t _ep_type, uint8_t _is_in)
194{
195    depctl_data_t depctl;
196    volatile uint32_t *depctl_addr;
197
198    IFX_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _epno, (_is_in?"IN":"OUT"));
199
200    depctl_addr = (_is_in)? (&(_core_if->in_ep_regs [_epno]->diepctl)):
201                            (&(_core_if->out_ep_regs[_epno]->doepctl));
202
203    depctl.d32 = ifxusb_rreg(depctl_addr);
204    /* clear the stall bits */
205    depctl.b.stall = 0;
206
207    /*
208     * USB Spec 9.4.5: For endpoints using data toggle, regardless
209     * of whether an endpoint has the Halt feature set, a
210     * ClearFeature(ENDPOINT_HALT) request always results in the
211     * data toggle being reinitialized to DATA0.
212     */
213    if (_ep_type == IFXUSB_EP_TYPE_INTR || _ep_type == IFXUSB_EP_TYPE_BULK)
214        depctl.b.setd0pid = 1; /* DATA0 */
215
216    ifxusb_wreg(depctl_addr, depctl.d32);
217    IFX_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",ifxusb_rreg(depctl_addr));
218    return;
219}
220
221/*!
222   \brief This function initializes the IFXUSB controller registers for Device mode.
223 This function flushes the Tx and Rx FIFOs and it flushes any entries in the
224 request queues.
225   \param _core_if Pointer of core_if structure
226   \param _params parameters to be set
227 */
228void ifxusb_dev_core_init(ifxusb_core_if_t *_core_if, ifxusb_params_t *_params)
229{
230    ifxusb_core_global_regs_t *global_regs = _core_if->core_global_regs;
231
232    gusbcfg_data_t usbcfg ={.d32 = 0};
233    gahbcfg_data_t ahbcfg ={.d32 = 0};
234    dcfg_data_t dcfg ={.d32 = 0};
235    grstctl_t resetctl ={.d32 = 0};
236    gotgctl_data_t gotgctl ={.d32 = 0};
237
238    uint32_t dir;
239    int i;
240
241    IFX_DEBUGPL(DBG_ENTRY, "%s() %d\n", __func__, __LINE__ );
242    IFX_DEBUGPL(DBG_CILV, "%s(%p)\n",__func__,_core_if);
243
244    /* Copy Params */
245    _core_if->params.dma_burst_size = _params->dma_burst_size;
246    _core_if->params.speed = _params->speed;
247    if(_params->max_transfer_size < 2048 || _params->max_transfer_size > ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1) )
248        _core_if->params.max_transfer_size = ((1 << (_core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1);
249    else
250        _core_if->params.max_transfer_size = _params->max_transfer_size;
251
252    if(_params->max_packet_count < 16 || _params->max_packet_count > ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1) )
253        _core_if->params.max_packet_count= ((1 << (_core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
254    else
255        _core_if->params.max_packet_count= _params->max_packet_count;
256    _core_if->params.phy_utmi_width = _params->phy_utmi_width;
257    _core_if->params.turn_around_time_hs = _params->turn_around_time_hs;
258    _core_if->params.turn_around_time_fs = _params->turn_around_time_fs;
259    _core_if->params.timeout_cal_hs = _params->timeout_cal_hs;
260    _core_if->params.timeout_cal_fs = _params->timeout_cal_fs;
261
262    #ifdef __DED_FIFO__
263        _core_if->params.thr_ctl = _params->thr_ctl;
264        _core_if->params.tx_thr_length = _params->tx_thr_length;
265        _core_if->params.rx_thr_length = _params->rx_thr_length;
266    #endif
267
268    /* Reset the Controller */
269    do
270    {
271        while(ifxusb_core_soft_reset_d( _core_if ))
272            ifxusb_hard_reset_d(_core_if);
273    } while (ifxusb_is_host_mode(_core_if));
274
275    usbcfg.d32 = ifxusb_rreg(&global_regs->gusbcfg);
276
277    usbcfg.b.ForceDevMode = 1;
278    usbcfg.b.ForceHstMode = 0;
279
280    usbcfg.b.term_sel_dl_pulse = 0;
281    ifxusb_wreg (&global_regs->gusbcfg, usbcfg.d32);
282
283    /* This programming sequence needs to happen in FS mode before any other
284     * programming occurs */
285    /* High speed PHY. */
286    if (!_core_if->phy_init_done)
287    {
288        _core_if->phy_init_done = 1;
289        /* HS PHY parameters. These parameters are preserved
290         * during soft reset so only program the first time. Do
291         * a soft reset immediately after setting phyif. */
292        usbcfg.b.ulpi_utmi_sel = 0; //UTMI+
293        usbcfg.b.phyif = ( _core_if->params.phy_utmi_width == 16)?1:0;
294        ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
295        /* Reset after setting the PHY parameters */
296        ifxusb_core_soft_reset_d( _core_if );
297    }
298
299    /* Program the GAHBCFG Register.*/
300    switch (_core_if->params.dma_burst_size)
301    {
302        case 0 :
303            ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_SINGLE;
304            break;
305        case 1 :
306            ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR;
307            break;
308        case 4 :
309            ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR4;
310            break;
311        case 8 :
312            ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR8;
313            break;
314        case 16:
315            ahbcfg.b.hburstlen = IFXUSB_GAHBCFG_INT_DMA_BURST_INCR16;
316            break;
317    }
318    #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
319        _core_if->unaligned_mask=3;
320        #if defined(__UNALIGNED_BUF_BURST__)
321            switch (_core_if->params.dma_burst_size)
322            {
323                case 4 :
324                    _core_if->unaligned_mask=15;
325                    break;
326                case 8 :
327                    _core_if->unaligned_mask=31;
328                    break;
329                case 16:
330                    _core_if->unaligned_mask=63;
331                    break;
332                case 0 :
333                case 1 :
334                    break;
335            }
336        #endif //defined(__UNALIGNED_BUF_BURST__)
337    #endif //defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
338    ahbcfg.b.dmaenable = 1;
339    ifxusb_wreg(&global_regs->gahbcfg, ahbcfg.d32);
340
341    /* Program the GUSBCFG register. */
342    usbcfg.d32 = ifxusb_rreg( &global_regs->gusbcfg );
343    usbcfg.b.hnpcap = 0;
344    usbcfg.b.srpcap = 0;
345    ifxusb_wreg( &global_regs->gusbcfg, usbcfg.d32);
346
347    {
348        dctl_data_t dctl = {.d32=0};
349        dctl.d32=ifxusb_rreg(&_core_if->dev_global_regs->dctl);
350        dctl.b.sftdiscon=1;
351        ifxusb_wreg(&_core_if->dev_global_regs->dctl,dctl.d32);
352    }
353
354    /* Restart the Phy Clock */
355    ifxusb_wreg(_core_if->pcgcctl, 0);
356
357    /* Device configuration register */
358    ifxusb_dev_init_spd(_core_if);
359    dcfg.d32 = ifxusb_rreg( &_core_if->dev_global_regs->dcfg);
360    dcfg.b.perfrint = IFXUSB_DCFG_FRAME_INTERVAL_80;
361    #if defined(__DED_FIFO__)
362        #if defined(__DESC_DMA__)
363            dcfg.b.descdma = 1;
364        #else
365            dcfg.b.descdma = 0;
366        #endif
367    #endif
368
369    ifxusb_wreg( &_core_if->dev_global_regs->dcfg, dcfg.d32 );
370
371    /* Configure data FIFO sizes */
372    _core_if->params.data_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
373    _core_if->params.rx_fifo_size = ifxusb_rreg(&global_regs->grxfsiz);
374    IFX_DEBUGPL(DBG_CIL, "Initial: FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
375    IFX_DEBUGPL(DBG_CIL, " Rx FIFO Size=0x%06X\n", _core_if->params.rx_fifo_size);
376
377    _core_if->params.tx_fifo_size[0]= ifxusb_rreg(&global_regs->gnptxfsiz) >> 16;
378
379    #ifdef __DED_FIFO__
380        for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
381            _core_if->params.tx_fifo_size[i] =
382                ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]) >> 16;
383    #else
384        for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
385            _core_if->params.tx_fifo_size[i+1] =
386                ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
387    #endif
388
389    #ifdef __DEBUG__
390        #ifdef __DED_FIFO__
391            for (i=0; i <= _core_if->hwcfg4.b.num_in_eps; i++)
392                IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i]);
393        #else
394            IFX_DEBUGPL(DBG_CIL, " NPTx FIFO Size=0x%06X\n", _core_if->params.tx_fifo_size[0]);
395            for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
396                IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO Size=0x%06X\n",i, _core_if->params.tx_fifo_size[i+1]);
397        #endif
398    #endif
399
400    {
401        fifosize_data_t txfifosize;
402        if(_params->data_fifo_size >=0 && _params->data_fifo_size < _core_if->params.data_fifo_size)
403            _core_if->params.data_fifo_size = _params->data_fifo_size;
404
405
406        if(_params->rx_fifo_size >=0 && _params->rx_fifo_size < _core_if->params.rx_fifo_size)
407            _core_if->params.rx_fifo_size = _params->rx_fifo_size;
408        if(_core_if->params.data_fifo_size < _core_if->params.rx_fifo_size)
409            _core_if->params.rx_fifo_size = _core_if->params.data_fifo_size;
410        ifxusb_wreg( &global_regs->grxfsiz, _core_if->params.rx_fifo_size);
411
412        for (i=0; i < MAX_EPS_CHANNELS; i++)
413            if(_params->tx_fifo_size[i] >=0 && _params->tx_fifo_size[i] < _core_if->params.tx_fifo_size[i])
414                _core_if->params.tx_fifo_size[i] = _params->tx_fifo_size[i];
415
416        txfifosize.b.startaddr = _core_if->params.rx_fifo_size;
417        #ifdef __DED_FIFO__
418            if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
419                _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
420            txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
421            ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
422            txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
423            for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
424            {
425                if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i] > _core_if->params.data_fifo_size)
426                    _core_if->params.tx_fifo_size[i]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
427                txfifosize.b.depth=_core_if->params.tx_fifo_size[i];
428                ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i-1], txfifosize.d32);
429                txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i];
430            }
431        #else
432            if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[0] > _core_if->params.data_fifo_size)
433                _core_if->params.tx_fifo_size[0]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
434            txfifosize.b.depth=_core_if->params.tx_fifo_size[0];
435            ifxusb_wreg( &global_regs->gnptxfsiz, txfifosize.d32);
436            txfifosize.b.startaddr += _core_if->params.tx_fifo_size[0];
437            for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
438            {
439                if(txfifosize.b.startaddr + _core_if->params.tx_fifo_size[i+1] > _core_if->params.data_fifo_size)
440                    _core_if->params.tx_fifo_size[i+1]= _core_if->params.data_fifo_size - txfifosize.b.startaddr;
441                //txfifosize.b.depth=_core_if->params.tx_fifo_size[i+1];
442                ifxusb_wreg( &global_regs->dptxfsiz_dieptxf[i], txfifosize.d32);
443                txfifosize.b.startaddr += _core_if->params.tx_fifo_size[i+1];
444            }
445        #endif
446    }
447
448    #ifdef __DEBUG__
449    {
450        fifosize_data_t fifosize;
451        IFX_DEBUGPL(DBG_CIL, "Result : FIFO Size=0x%06X\n" , _core_if->params.data_fifo_size);
452
453        IFX_DEBUGPL(DBG_CIL, " Rx FIFO =0x%06X Sz=0x%06X\n", 0,ifxusb_rreg(&global_regs->grxfsiz));
454        #ifdef __DED_FIFO__
455            fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
456            IFX_DEBUGPL(DBG_CIL, " Tx[00] FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
457            for (i=1; i <= _core_if->hwcfg4.b.num_in_eps; i++)
458            {
459                fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i-1]);
460                IFX_DEBUGPL(DBG_CIL, " Tx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
461            }
462        #else
463            fifosize.d32=ifxusb_rreg(&global_regs->gnptxfsiz);
464            IFX_DEBUGPL(DBG_CIL, " NPTx FIFO =0x%06X Sz=0x%06X\n", fifosize.b.startaddr,fifosize.b.depth);
465            for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++)
466            {
467                fifosize.d32=ifxusb_rreg(&global_regs->dptxfsiz_dieptxf[i]);
468                IFX_DEBUGPL(DBG_CIL, " PTx[%02d] FIFO 0x%06X Sz=0x%06X\n",i, fifosize.b.startaddr,fifosize.b.depth);
469            }
470        #endif
471    }
472    #endif
473
474    /* Clear Host Set HNP Enable in the OTG Control Register */
475    gotgctl.b.hstsethnpen = 1;
476    ifxusb_mreg( &global_regs->gotgctl, gotgctl.d32, 0);
477
478    /* Flush the FIFOs */
479    ifxusb_flush_tx_fifo_d(_core_if, 0x10); /* all Tx FIFOs */
480    ifxusb_flush_rx_fifo_d(_core_if);
481
482    /* Flush the Learning Queue. */
483    resetctl.b.intknqflsh = 1;
484    ifxusb_wreg( &global_regs->grstctl, resetctl.d32);
485
486    /* Clear all pending Device Interrupts */
487    ifxusb_wreg( &_core_if->dev_global_regs->diepmsk , 0 );
488    ifxusb_wreg( &_core_if->dev_global_regs->doepmsk , 0 );
489    ifxusb_wreg( &_core_if->dev_global_regs->daint , 0xFFFFFFFF );
490    ifxusb_wreg( &_core_if->dev_global_regs->daintmsk, 0 );
491
492    dir=_core_if->hwcfg1.d32;
493    for (i=0; i <= _core_if->hwcfg2.b.num_dev_ep ; i++,dir>>=2)
494    {
495        depctl_data_t depctl;
496        if((dir&0x03)==0 || (dir&0x03) ==1)
497        {
498            depctl.d32 = ifxusb_rreg(&_core_if->in_ep_regs[i]->diepctl);
499            if (depctl.b.epena)
500            {
501                depctl.d32 = 0;
502                depctl.b.epdis = 1;
503                depctl.b.snak = 1;
504            }
505            else
506                depctl.d32 = 0;
507            ifxusb_wreg( &_core_if->in_ep_regs[i]->diepctl, depctl.d32);
508            #ifndef __DESC_DMA__
509                ifxusb_wreg( &_core_if->in_ep_regs[i]->dieptsiz, 0);
510            #endif
511            ifxusb_wreg( &_core_if->in_ep_regs[i]->diepdma, 0);
512            ifxusb_wreg( &_core_if->in_ep_regs[i]->diepint, 0xFF);
513        }
514
515        if((dir&0x03)==0 || (dir&0x03) ==2)
516        {
517            depctl.d32 = ifxusb_rreg(&_core_if->out_ep_regs[i]->doepctl);
518            if (depctl.b.epena)
519            {
520                depctl.d32 = 0;
521                depctl.b.epdis = 1;
522                depctl.b.snak = 1;
523            }
524            else
525                depctl.d32 = 0;
526            ifxusb_wreg( &_core_if->out_ep_regs[i]->doepctl, depctl.d32);
527            #ifndef __DESC_DMA__
528                ifxusb_wreg( &_core_if->out_ep_regs[i]->doeptsiz, 0);
529            #endif
530            ifxusb_wreg( &_core_if->out_ep_regs[i]->doepdma, 0);
531            ifxusb_wreg( &_core_if->out_ep_regs[i]->doepint, 0xFF);
532        }
533    }
534}
535
536

Archive Download this file



interactive