LCOV - code coverage report
Current view: top level - drivers/usb/host/dwc_otg - dwc_otg_hcd.h (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 24 36 66.7 %
Date: 2020-09-30 20:25:40 Functions: 3 4 75.0 %
Branches: 5 14 35.7 %

           Branch data     Line data    Source code
       1                 :            : /* ==========================================================================
       2                 :            :  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $
       3                 :            :  * $Revision: #58 $
       4                 :            :  * $Date: 2011/09/15 $
       5                 :            :  * $Change: 1846647 $
       6                 :            :  *
       7                 :            :  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
       8                 :            :  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
       9                 :            :  * otherwise expressly agreed to in writing between Synopsys and you.
      10                 :            :  *
      11                 :            :  * The Software IS NOT an item of Licensed Software or Licensed Product under
      12                 :            :  * any End User Software License Agreement or Agreement for Licensed Product
      13                 :            :  * with Synopsys or any supplement thereto. You are permitted to use and
      14                 :            :  * redistribute this Software in source and binary forms, with or without
      15                 :            :  * modification, provided that redistributions of source code must retain this
      16                 :            :  * notice. You may not view, use, disclose, copy or distribute this file or
      17                 :            :  * any information contained herein except pursuant to this license grant from
      18                 :            :  * Synopsys. If you do not agree with this notice, including the disclaimer
      19                 :            :  * below, then you are not authorized to use the Software.
      20                 :            :  *
      21                 :            :  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
      22                 :            :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24                 :            :  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
      25                 :            :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26                 :            :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27                 :            :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
      28                 :            :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
      31                 :            :  * DAMAGE.
      32                 :            :  * ========================================================================== */
      33                 :            : #ifndef DWC_DEVICE_ONLY
      34                 :            : #ifndef __DWC_HCD_H__
      35                 :            : #define __DWC_HCD_H__
      36                 :            : 
      37                 :            : #include "dwc_otg_os_dep.h"
      38                 :            : #include "usb.h"
      39                 :            : #include "dwc_otg_hcd_if.h"
      40                 :            : #include "dwc_otg_core_if.h"
      41                 :            : #include "dwc_list.h"
      42                 :            : #include "dwc_otg_cil.h"
      43                 :            : #include "dwc_otg_fiq_fsm.h"
      44                 :            : #include "dwc_otg_driver.h"
      45                 :            : 
      46                 :            : 
      47                 :            : /**
      48                 :            :  * @file
      49                 :            :  *
      50                 :            :  * This file contains the structures, constants, and interfaces for
      51                 :            :  * the Host Contoller Driver (HCD).
      52                 :            :  *
      53                 :            :  * The Host Controller Driver (HCD) is responsible for translating requests
      54                 :            :  * from the USB Driver into the appropriate actions on the DWC_otg controller.
      55                 :            :  * It isolates the USBD from the specifics of the controller by providing an
      56                 :            :  * API to the USBD.
      57                 :            :  */
      58                 :            : 
      59                 :            : struct dwc_otg_hcd_pipe_info {
      60                 :            :         uint8_t dev_addr;
      61                 :            :         uint8_t ep_num;
      62                 :            :         uint8_t pipe_type;
      63                 :            :         uint8_t pipe_dir;
      64                 :            :         uint16_t mps;
      65                 :            : };
      66                 :            : 
      67                 :            : struct dwc_otg_hcd_iso_packet_desc {
      68                 :            :         uint32_t offset;
      69                 :            :         uint32_t length;
      70                 :            :         uint32_t actual_length;
      71                 :            :         uint32_t status;
      72                 :            : };
      73                 :            : 
      74                 :            : struct dwc_otg_qtd;
      75                 :            : 
      76                 :            : struct dwc_otg_hcd_urb {
      77                 :            :         void *priv;
      78                 :            :         struct dwc_otg_qtd *qtd;
      79                 :            :         void *buf;
      80                 :            :         dwc_dma_t dma;
      81                 :            :         void *setup_packet;
      82                 :            :         dwc_dma_t setup_dma;
      83                 :            :         uint32_t length;
      84                 :            :         uint32_t actual_length;
      85                 :            :         uint32_t status;
      86                 :            :         uint32_t error_count;
      87                 :            :         uint32_t packet_count;
      88                 :            :         uint32_t flags;
      89                 :            :         uint16_t interval;
      90                 :            :         struct dwc_otg_hcd_pipe_info pipe_info;
      91                 :            :         struct dwc_otg_hcd_iso_packet_desc iso_descs[0];
      92                 :            : };
      93                 :            : 
      94                 :            : static inline uint8_t dwc_otg_hcd_get_ep_num(struct dwc_otg_hcd_pipe_info *pipe)
      95                 :            : {
      96                 :    7077032 :         return pipe->ep_num;
      97                 :            : }
      98                 :            : 
      99                 :            : static inline uint8_t dwc_otg_hcd_get_pipe_type(struct dwc_otg_hcd_pipe_info
     100                 :            :                                                 *pipe)
     101                 :            : {
     102         [ #  # ]:   16699762 :         return pipe->pipe_type;
     103                 :            : }
     104                 :            : 
     105                 :            : static inline uint16_t dwc_otg_hcd_get_mps(struct dwc_otg_hcd_pipe_info *pipe)
     106                 :            : {
     107                 :       3105 :         return pipe->mps;
     108                 :            : }
     109                 :            : 
     110                 :            : static inline uint8_t dwc_otg_hcd_get_dev_addr(struct dwc_otg_hcd_pipe_info
     111                 :            :                                                *pipe)
     112                 :            : {
     113                 :    7077032 :         return pipe->dev_addr;
     114                 :            : }
     115                 :            : 
     116                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_isoc(struct dwc_otg_hcd_pipe_info
     117                 :            :                                                *pipe)
     118                 :            : {
     119                 :            :         return (pipe->pipe_type == UE_ISOCHRONOUS);
     120                 :            : }
     121                 :            : 
     122                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_int(struct dwc_otg_hcd_pipe_info
     123                 :            :                                               *pipe)
     124                 :            : {
     125                 :            :         return (pipe->pipe_type == UE_INTERRUPT);
     126                 :            : }
     127                 :            : 
     128                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_bulk(struct dwc_otg_hcd_pipe_info
     129                 :            :                                                *pipe)
     130                 :            : {
     131                 :            :         return (pipe->pipe_type == UE_BULK);
     132                 :            : }
     133                 :            : 
     134                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_control(struct dwc_otg_hcd_pipe_info
     135                 :            :                                                   *pipe)
     136                 :            : {
     137                 :            :         return (pipe->pipe_type == UE_CONTROL);
     138                 :            : }
     139                 :            : 
     140                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_in(struct dwc_otg_hcd_pipe_info *pipe)
     141                 :            : {
     142                 :    7174424 :         return (pipe->pipe_dir == UE_DIR_IN);
     143                 :            : }
     144                 :            : 
     145                 :            : static inline uint8_t dwc_otg_hcd_is_pipe_out(struct dwc_otg_hcd_pipe_info
     146                 :            :                                               *pipe)
     147                 :            : {
     148                 :      94287 :         return (!dwc_otg_hcd_is_pipe_in(pipe));
     149                 :            : }
     150                 :            : 
     151                 :            : static inline void dwc_otg_hcd_fill_pipe(struct dwc_otg_hcd_pipe_info *pipe,
     152                 :            :                                          uint8_t devaddr, uint8_t ep_num,
     153                 :            :                                          uint8_t pipe_type, uint8_t pipe_dir,
     154                 :            :                                          uint16_t mps)
     155                 :            : {
     156                 :     134695 :         pipe->dev_addr = devaddr;
     157                 :     134695 :         pipe->ep_num = ep_num;
     158                 :     134695 :         pipe->pipe_type = pipe_type;
     159                 :     134695 :         pipe->pipe_dir = pipe_dir;
     160                 :     134695 :         pipe->mps = mps;
     161                 :            : }
     162                 :            : 
     163                 :            : /**
     164                 :            :  * Phases for control transfers.
     165                 :            :  */
     166                 :            : typedef enum dwc_otg_control_phase {
     167                 :            :         DWC_OTG_CONTROL_SETUP,
     168                 :            :         DWC_OTG_CONTROL_DATA,
     169                 :            :         DWC_OTG_CONTROL_STATUS
     170                 :            : } dwc_otg_control_phase_e;
     171                 :            : 
     172                 :            : /** Transaction types. */
     173                 :            : typedef enum dwc_otg_transaction_type {
     174                 :            :         DWC_OTG_TRANSACTION_NONE          = 0,
     175                 :            :         DWC_OTG_TRANSACTION_PERIODIC      = 1,
     176                 :            :         DWC_OTG_TRANSACTION_NON_PERIODIC  = 2,
     177                 :            :         DWC_OTG_TRANSACTION_ALL           = DWC_OTG_TRANSACTION_PERIODIC + DWC_OTG_TRANSACTION_NON_PERIODIC
     178                 :            : } dwc_otg_transaction_type_e;
     179                 :            : 
     180                 :            : struct dwc_otg_qh;
     181                 :            : 
     182                 :            : /**
     183                 :            :  * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
     184                 :            :  * interrupt, or isochronous transfer. A single QTD is created for each URB
     185                 :            :  * (of one of these types) submitted to the HCD. The transfer associated with
     186                 :            :  * a QTD may require one or multiple transactions.
     187                 :            :  *
     188                 :            :  * A QTD is linked to a Queue Head, which is entered in either the
     189                 :            :  * non-periodic or periodic schedule for execution. When a QTD is chosen for
     190                 :            :  * execution, some or all of its transactions may be executed. After
     191                 :            :  * execution, the state of the QTD is updated. The QTD may be retired if all
     192                 :            :  * its transactions are complete or if an error occurred. Otherwise, it
     193                 :            :  * remains in the schedule so more transactions can be executed later.
     194                 :            :  */
     195                 :            : typedef struct dwc_otg_qtd {
     196                 :            :         /**
     197                 :            :          * Determines the PID of the next data packet for the data phase of
     198                 :            :          * control transfers. Ignored for other transfer types.<br>
     199                 :            :          * One of the following values:
     200                 :            :          *      - DWC_OTG_HC_PID_DATA0
     201                 :            :          *      - DWC_OTG_HC_PID_DATA1
     202                 :            :          */
     203                 :            :         uint8_t data_toggle;
     204                 :            : 
     205                 :            :         /** Current phase for control transfers (Setup, Data, or Status). */
     206                 :            :         dwc_otg_control_phase_e control_phase;
     207                 :            : 
     208                 :            :         /** Keep track of the current split type
     209                 :            :          * for FS/LS endpoints on a HS Hub */
     210                 :            :         uint8_t complete_split;
     211                 :            : 
     212                 :            :         /** How many bytes transferred during SSPLIT OUT */
     213                 :            :         uint32_t ssplit_out_xfer_count;
     214                 :            : 
     215                 :            :         /**
     216                 :            :          * Holds the number of bus errors that have occurred for a transaction
     217                 :            :          * within this transfer.
     218                 :            :          */
     219                 :            :         uint8_t error_count;
     220                 :            : 
     221                 :            :         /**
     222                 :            :          * Index of the next frame descriptor for an isochronous transfer. A
     223                 :            :          * frame descriptor describes the buffer position and length of the
     224                 :            :          * data to be transferred in the next scheduled (micro)frame of an
     225                 :            :          * isochronous transfer. It also holds status for that transaction.
     226                 :            :          * The frame index starts at 0.
     227                 :            :          */
     228                 :            :         uint16_t isoc_frame_index;
     229                 :            : 
     230                 :            :         /** Position of the ISOC split on full/low speed */
     231                 :            :         uint8_t isoc_split_pos;
     232                 :            : 
     233                 :            :         /** Position of the ISOC split in the buffer for the current frame */
     234                 :            :         uint16_t isoc_split_offset;
     235                 :            : 
     236                 :            :         /** URB for this transfer */
     237                 :            :         struct dwc_otg_hcd_urb *urb;
     238                 :            : 
     239                 :            :         struct dwc_otg_qh *qh;
     240                 :            : 
     241                 :            :         /** This list of QTDs */
     242                 :            :          DWC_CIRCLEQ_ENTRY(dwc_otg_qtd) qtd_list_entry;
     243                 :            : 
     244                 :            :         /** Indicates if this QTD is currently processed by HW. */
     245                 :            :         uint8_t in_process;
     246                 :            : 
     247                 :            :         /** Number of DMA descriptors for this QTD */
     248                 :            :         uint8_t n_desc;
     249                 :            : 
     250                 :            :         /**
     251                 :            :          * Last activated frame(packet) index.
     252                 :            :          * Used in Descriptor DMA mode only.
     253                 :            :          */
     254                 :            :         uint16_t isoc_frame_index_last;
     255                 :            : 
     256                 :            : } dwc_otg_qtd_t;
     257                 :            : 
     258                 :            : DWC_CIRCLEQ_HEAD(dwc_otg_qtd_list, dwc_otg_qtd);
     259                 :            : 
     260                 :            : /**
     261                 :            :  * A Queue Head (QH) holds the static characteristics of an endpoint and
     262                 :            :  * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
     263                 :            :  * be entered in either the non-periodic or periodic schedule.
     264                 :            :  */
     265                 :            : typedef struct dwc_otg_qh {
     266                 :            :         /**
     267                 :            :          * Endpoint type.
     268                 :            :          * One of the following values:
     269                 :            :          *      - UE_CONTROL
     270                 :            :          *      - UE_BULK
     271                 :            :          *      - UE_INTERRUPT
     272                 :            :          *      - UE_ISOCHRONOUS
     273                 :            :          */
     274                 :            :         uint8_t ep_type;
     275                 :            :         uint8_t ep_is_in;
     276                 :            : 
     277                 :            :         /** wMaxPacketSize Field of Endpoint Descriptor. */
     278                 :            :         uint16_t maxp;
     279                 :            : 
     280                 :            :         /**
     281                 :            :          * Device speed.
     282                 :            :          * One of the following values:
     283                 :            :          *      - DWC_OTG_EP_SPEED_LOW
     284                 :            :          *      - DWC_OTG_EP_SPEED_FULL
     285                 :            :          *      - DWC_OTG_EP_SPEED_HIGH
     286                 :            :          */
     287                 :            :         uint8_t dev_speed;
     288                 :            : 
     289                 :            :         /**
     290                 :            :          * Determines the PID of the next data packet for non-control
     291                 :            :          * transfers. Ignored for control transfers.<br>
     292                 :            :          * One of the following values:
     293                 :            :          *      - DWC_OTG_HC_PID_DATA0
     294                 :            :          *      - DWC_OTG_HC_PID_DATA1
     295                 :            :          */
     296                 :            :         uint8_t data_toggle;
     297                 :            : 
     298                 :            :         /** Ping state if 1. */
     299                 :            :         uint8_t ping_state;
     300                 :            : 
     301                 :            :         /**
     302                 :            :          * List of QTDs for this QH.
     303                 :            :          */
     304                 :            :         struct dwc_otg_qtd_list qtd_list;
     305                 :            : 
     306                 :            :         /** Host channel currently processing transfers for this QH. */
     307                 :            :         struct dwc_hc *channel;
     308                 :            : 
     309                 :            :         /** Full/low speed endpoint on high-speed hub requires split. */
     310                 :            :         uint8_t do_split;
     311                 :            : 
     312                 :            :         /** @name Periodic schedule information */
     313                 :            :         /** @{ */
     314                 :            : 
     315                 :            :         /** Bandwidth in microseconds per (micro)frame. */
     316                 :            :         uint16_t usecs;
     317                 :            : 
     318                 :            :         /** Interval between transfers in (micro)frames. */
     319                 :            :         uint16_t interval;
     320                 :            : 
     321                 :            :         /**
     322                 :            :          * (micro)frame to initialize a periodic transfer. The transfer
     323                 :            :          * executes in the following (micro)frame.
     324                 :            :          */
     325                 :            :         uint16_t sched_frame;
     326                 :            : 
     327                 :            :         /*
     328                 :            :         ** Frame a NAK was received on this queue head, used to minimise NAK retransmission
     329                 :            :         */
     330                 :            :         uint16_t nak_frame;
     331                 :            : 
     332                 :            :         /** (micro)frame at which last start split was initialized. */
     333                 :            :         uint16_t start_split_frame;
     334                 :            : 
     335                 :            :         /** @} */
     336                 :            : 
     337                 :            :         /**
     338                 :            :          * Used instead of original buffer if
     339                 :            :          * it(physical address) is not dword-aligned.
     340                 :            :          */
     341                 :            :         uint8_t *dw_align_buf;
     342                 :            :         dwc_dma_t dw_align_buf_dma;
     343                 :            : 
     344                 :            :         /** Entry for QH in either the periodic or non-periodic schedule. */
     345                 :            :         dwc_list_link_t qh_list_entry;
     346                 :            : 
     347                 :            :         /** @name Descriptor DMA support */
     348                 :            :         /** @{ */
     349                 :            : 
     350                 :            :         /** Descriptor List. */
     351                 :            :         dwc_otg_host_dma_desc_t *desc_list;
     352                 :            : 
     353                 :            :         /** Descriptor List physical address. */
     354                 :            :         dwc_dma_t desc_list_dma;
     355                 :            : 
     356                 :            :         /**
     357                 :            :          * Xfer Bytes array.
     358                 :            :          * Each element corresponds to a descriptor and indicates
     359                 :            :          * original XferSize size value for the descriptor.
     360                 :            :          */
     361                 :            :         uint32_t *n_bytes;
     362                 :            : 
     363                 :            :         /** Actual number of transfer descriptors in a list. */
     364                 :            :         uint16_t ntd;
     365                 :            : 
     366                 :            :         /** First activated isochronous transfer descriptor index. */
     367                 :            :         uint8_t td_first;
     368                 :            :         /** Last activated isochronous transfer descriptor index. */
     369                 :            :         uint8_t td_last;
     370                 :            : 
     371                 :            :         /** @} */
     372                 :            : 
     373                 :            : 
     374                 :            :         uint16_t speed;
     375                 :            :         uint16_t frame_usecs[8];
     376                 :            : 
     377                 :            :         uint32_t skip_count;
     378                 :            : } dwc_otg_qh_t;
     379                 :            : 
     380                 :            : DWC_CIRCLEQ_HEAD(hc_list, dwc_hc);
     381                 :            : 
     382                 :            : typedef struct urb_tq_entry {
     383                 :            :         struct urb *urb;
     384                 :            :         DWC_TAILQ_ENTRY(urb_tq_entry) urb_tq_entries;
     385                 :            : } urb_tq_entry_t;
     386                 :            : 
     387                 :            : DWC_TAILQ_HEAD(urb_list, urb_tq_entry);
     388                 :            : 
     389                 :            : /**
     390                 :            :  * This structure holds the state of the HCD, including the non-periodic and
     391                 :            :  * periodic schedules.
     392                 :            :  */
     393                 :            : struct dwc_otg_hcd {
     394                 :            :         /** The DWC otg device pointer */
     395                 :            :         struct dwc_otg_device *otg_dev;
     396                 :            :         /** DWC OTG Core Interface Layer */
     397                 :            :         dwc_otg_core_if_t *core_if;
     398                 :            : 
     399                 :            :         /** Function HCD driver callbacks */
     400                 :            :         struct dwc_otg_hcd_function_ops *fops;
     401                 :            : 
     402                 :            :         /** Internal DWC HCD Flags */
     403                 :            :         volatile union dwc_otg_hcd_internal_flags {
     404                 :            :                 uint32_t d32;
     405                 :            :                 struct {
     406                 :            :                         unsigned port_connect_status_change:1;
     407                 :            :                         unsigned port_connect_status:1;
     408                 :            :                         unsigned port_reset_change:1;
     409                 :            :                         unsigned port_enable_change:1;
     410                 :            :                         unsigned port_suspend_change:1;
     411                 :            :                         unsigned port_over_current_change:1;
     412                 :            :                         unsigned port_l1_change:1;
     413                 :            :                         unsigned port_speed:2;
     414                 :            :                         unsigned reserved:24;
     415                 :            :                 } b;
     416                 :            :         } flags;
     417                 :            : 
     418                 :            :         /**
     419                 :            :          * Inactive items in the non-periodic schedule. This is a list of
     420                 :            :          * Queue Heads. Transfers associated with these Queue Heads are not
     421                 :            :          * currently assigned to a host channel.
     422                 :            :          */
     423                 :            :         dwc_list_link_t non_periodic_sched_inactive;
     424                 :            : 
     425                 :            :         /**
     426                 :            :          * Active items in the non-periodic schedule. This is a list of
     427                 :            :          * Queue Heads. Transfers associated with these Queue Heads are
     428                 :            :          * currently assigned to a host channel.
     429                 :            :          */
     430                 :            :         dwc_list_link_t non_periodic_sched_active;
     431                 :            : 
     432                 :            :         /**
     433                 :            :          * Pointer to the next Queue Head to process in the active
     434                 :            :          * non-periodic schedule.
     435                 :            :          */
     436                 :            :         dwc_list_link_t *non_periodic_qh_ptr;
     437                 :            : 
     438                 :            :         /**
     439                 :            :          * Inactive items in the periodic schedule. This is a list of QHs for
     440                 :            :          * periodic transfers that are _not_ scheduled for the next frame.
     441                 :            :          * Each QH in the list has an interval counter that determines when it
     442                 :            :          * needs to be scheduled for execution. This scheduling mechanism
     443                 :            :          * allows only a simple calculation for periodic bandwidth used (i.e.
     444                 :            :          * must assume that all periodic transfers may need to execute in the
     445                 :            :          * same frame). However, it greatly simplifies scheduling and should
     446                 :            :          * be sufficient for the vast majority of OTG hosts, which need to
     447                 :            :          * connect to a small number of peripherals at one time.
     448                 :            :          *
     449                 :            :          * Items move from this list to periodic_sched_ready when the QH
     450                 :            :          * interval counter is 0 at SOF.
     451                 :            :          */
     452                 :            :         dwc_list_link_t periodic_sched_inactive;
     453                 :            : 
     454                 :            :         /**
     455                 :            :          * List of periodic QHs that are ready for execution in the next
     456                 :            :          * frame, but have not yet been assigned to host channels.
     457                 :            :          *
     458                 :            :          * Items move from this list to periodic_sched_assigned as host
     459                 :            :          * channels become available during the current frame.
     460                 :            :          */
     461                 :            :         dwc_list_link_t periodic_sched_ready;
     462                 :            : 
     463                 :            :         /**
     464                 :            :          * List of periodic QHs to be executed in the next frame that are
     465                 :            :          * assigned to host channels.
     466                 :            :          *
     467                 :            :          * Items move from this list to periodic_sched_queued as the
     468                 :            :          * transactions for the QH are queued to the DWC_otg controller.
     469                 :            :          */
     470                 :            :         dwc_list_link_t periodic_sched_assigned;
     471                 :            : 
     472                 :            :         /**
     473                 :            :          * List of periodic QHs that have been queued for execution.
     474                 :            :          *
     475                 :            :          * Items move from this list to either periodic_sched_inactive or
     476                 :            :          * periodic_sched_ready when the channel associated with the transfer
     477                 :            :          * is released. If the interval for the QH is 1, the item moves to
     478                 :            :          * periodic_sched_ready because it must be rescheduled for the next
     479                 :            :          * frame. Otherwise, the item moves to periodic_sched_inactive.
     480                 :            :          */
     481                 :            :         dwc_list_link_t periodic_sched_queued;
     482                 :            : 
     483                 :            :         /**
     484                 :            :          * Total bandwidth claimed so far for periodic transfers. This value
     485                 :            :          * is in microseconds per (micro)frame. The assumption is that all
     486                 :            :          * periodic transfers may occur in the same (micro)frame.
     487                 :            :          */
     488                 :            :         uint16_t periodic_usecs;
     489                 :            : 
     490                 :            :         /**
     491                 :            :          * Total bandwidth claimed so far for all periodic transfers
     492                 :            :          * in a frame.
     493                 :            :          * This will include a mixture of HS and FS transfers.
     494                 :            :          * Units are microseconds per (micro)frame.
     495                 :            :          * We have a budget per frame and have to schedule
     496                 :            :          * transactions accordingly.
     497                 :            :          * Watch out for the fact that things are actually scheduled for the
     498                 :            :          * "next frame".
     499                 :            :          */
     500                 :            :         uint16_t                frame_usecs[8];
     501                 :            : 
     502                 :            : 
     503                 :            :         /**
     504                 :            :          * Frame number read from the core at SOF. The value ranges from 0 to
     505                 :            :          * DWC_HFNUM_MAX_FRNUM.
     506                 :            :          */
     507                 :            :         uint16_t frame_number;
     508                 :            : 
     509                 :            :         /**
     510                 :            :          * Count of periodic QHs, if using several eps. For SOF enable/disable.
     511                 :            :          */
     512                 :            :         uint16_t periodic_qh_count;
     513                 :            : 
     514                 :            :         /**
     515                 :            :          * Free host channels in the controller. This is a list of
     516                 :            :          * dwc_hc_t items.
     517                 :            :          */
     518                 :            :         struct hc_list free_hc_list;
     519                 :            :         /**
     520                 :            :          * Number of host channels assigned to periodic transfers. Currently
     521                 :            :          * assuming that there is a dedicated host channel for each periodic
     522                 :            :          * transaction and at least one host channel available for
     523                 :            :          * non-periodic transactions.
     524                 :            :          */
     525                 :            :         int periodic_channels; /* microframe_schedule==0 */
     526                 :            : 
     527                 :            :         /**
     528                 :            :          * Number of host channels assigned to non-periodic transfers.
     529                 :            :          */
     530                 :            :         int non_periodic_channels; /* microframe_schedule==0 */
     531                 :            : 
     532                 :            :         /**
     533                 :            :          * Number of host channels assigned to non-periodic transfers.
     534                 :            :          */
     535                 :            :         int available_host_channels;
     536                 :            : 
     537                 :            :         /**
     538                 :            :          * Array of pointers to the host channel descriptors. Allows accessing
     539                 :            :          * a host channel descriptor given the host channel number. This is
     540                 :            :          * useful in interrupt handlers.
     541                 :            :          */
     542                 :            :         struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS];
     543                 :            : 
     544                 :            :         /**
     545                 :            :          * Buffer to use for any data received during the status phase of a
     546                 :            :          * control transfer. Normally no data is transferred during the status
     547                 :            :          * phase. This buffer is used as a bit bucket.
     548                 :            :          */
     549                 :            :         uint8_t *status_buf;
     550                 :            : 
     551                 :            :         /**
     552                 :            :          * DMA address for status_buf.
     553                 :            :          */
     554                 :            :         dma_addr_t status_buf_dma;
     555                 :            : #define DWC_OTG_HCD_STATUS_BUF_SIZE 64
     556                 :            : 
     557                 :            :         /**
     558                 :            :          * Connection timer. An OTG host must display a message if the device
     559                 :            :          * does not connect. Started when the VBus power is turned on via
     560                 :            :          * sysfs attribute "buspower".
     561                 :            :          */
     562                 :            :         dwc_timer_t *conn_timer;
     563                 :            : 
     564                 :            :         /* Tasket to do a reset */
     565                 :            :         dwc_tasklet_t *reset_tasklet;
     566                 :            : 
     567                 :            :         dwc_tasklet_t *completion_tasklet;
     568                 :            :         struct urb_list completed_urb_list;
     569                 :            : 
     570                 :            :         /*  */
     571                 :            :         dwc_spinlock_t *lock;
     572                 :            :         /**
     573                 :            :          * Private data that could be used by OS wrapper.
     574                 :            :          */
     575                 :            :         void *priv;
     576                 :            : 
     577                 :            :         uint8_t otg_port;
     578                 :            : 
     579                 :            :         /** Frame List */
     580                 :            :         uint32_t *frame_list;
     581                 :            : 
     582                 :            :         /** Hub - Port assignment */
     583                 :            :         int hub_port[128];
     584                 :            : #ifdef FIQ_DEBUG
     585                 :            :         int hub_port_alloc[2048];
     586                 :            : #endif
     587                 :            : 
     588                 :            :         /** Frame List DMA address */
     589                 :            :         dma_addr_t frame_list_dma;
     590                 :            : 
     591                 :            :         struct fiq_stack *fiq_stack;
     592                 :            :         struct fiq_state *fiq_state;
     593                 :            : 
     594                 :            :         /** Virtual address for split transaction DMA bounce buffers */
     595                 :            :         struct fiq_dma_blob *fiq_dmab;
     596                 :            : 
     597                 :            : #ifdef DEBUG
     598                 :            :         uint32_t frrem_samples;
     599                 :            :         uint64_t frrem_accum;
     600                 :            : 
     601                 :            :         uint32_t hfnum_7_samples_a;
     602                 :            :         uint64_t hfnum_7_frrem_accum_a;
     603                 :            :         uint32_t hfnum_0_samples_a;
     604                 :            :         uint64_t hfnum_0_frrem_accum_a;
     605                 :            :         uint32_t hfnum_other_samples_a;
     606                 :            :         uint64_t hfnum_other_frrem_accum_a;
     607                 :            : 
     608                 :            :         uint32_t hfnum_7_samples_b;
     609                 :            :         uint64_t hfnum_7_frrem_accum_b;
     610                 :            :         uint32_t hfnum_0_samples_b;
     611                 :            :         uint64_t hfnum_0_frrem_accum_b;
     612                 :            :         uint32_t hfnum_other_samples_b;
     613                 :            :         uint64_t hfnum_other_frrem_accum_b;
     614                 :            : #endif
     615                 :            : };
     616                 :            : 
     617                 :            : static inline struct device *dwc_otg_hcd_to_dev(struct dwc_otg_hcd *hcd)
     618                 :            : {
     619                 :    7078067 :         return &hcd->otg_dev->os_dep.platformdev->dev;
     620                 :            : }
     621                 :            : 
     622                 :            : /** @name Transaction Execution Functions */
     623                 :            : /** @{ */
     624                 :            : extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t
     625                 :            :                                                                   * hcd);
     626                 :            : extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd,
     627                 :            :                                            dwc_otg_transaction_type_e tr_type);
     628                 :            : 
     629                 :            : int dwc_otg_hcd_allocate_port(dwc_otg_hcd_t * hcd, dwc_otg_qh_t *qh);
     630                 :            : void dwc_otg_hcd_release_port(dwc_otg_hcd_t * dwc_otg_hcd, dwc_otg_qh_t *qh);
     631                 :            : 
     632                 :            : extern int fiq_fsm_queue_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
     633                 :            : extern int fiq_fsm_transaction_suitable(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh);
     634                 :            : extern void dwc_otg_cleanup_fiq_channel(dwc_otg_hcd_t *hcd, uint32_t num);
     635                 :            : 
     636                 :            : /** @} */
     637                 :            : 
     638                 :            : /** @name Interrupt Handler Functions */
     639                 :            : /** @{ */
     640                 :            : extern int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     641                 :            : extern int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     642                 :            : extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t *
     643                 :            :                                                          dwc_otg_hcd);
     644                 :            : extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t *
     645                 :            :                                                         dwc_otg_hcd);
     646                 :            : extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t *
     647                 :            :                                                            dwc_otg_hcd);
     648                 :            : extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *
     649                 :            :                                                            dwc_otg_hcd);
     650                 :            : extern int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     651                 :            : extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t *
     652                 :            :                                                              dwc_otg_hcd);
     653                 :            : extern int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     654                 :            : extern int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     655                 :            : extern int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd,
     656                 :            :                                             uint32_t num);
     657                 :            : extern int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t * dwc_otg_hcd);
     658                 :            : extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t *
     659                 :            :                                                        dwc_otg_hcd);
     660                 :            : /** @} */
     661                 :            : 
     662                 :            : /** @name Schedule Queue Functions */
     663                 :            : /** @{ */
     664                 :            : 
     665                 :            : /* Implemented in dwc_otg_hcd_queue.c */
     666                 :            : extern dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t * hcd,
     667                 :            :                                            dwc_otg_hcd_urb_t * urb, int atomic_alloc);
     668                 :            : extern void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     669                 :            : extern int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     670                 :            : extern void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     671                 :            : extern void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh,
     672                 :            :                                       int sched_csplit);
     673                 :            : 
     674                 :            : /** Remove and free a QH */
     675                 :          0 : static inline void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t * hcd,
     676                 :            :                                                   dwc_otg_qh_t * qh)
     677                 :            : {
     678                 :            :         dwc_irqflags_t flags;
     679                 :          0 :         DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
     680                 :          0 :         dwc_otg_hcd_qh_remove(hcd, qh);
     681                 :          0 :         DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
     682                 :          0 :         dwc_otg_hcd_qh_free(hcd, qh);
     683                 :          0 : }
     684                 :            : 
     685                 :            : /** Allocates memory for a QH structure.
     686                 :            :  * @return Returns the memory allocate or NULL on error. */
     687                 :       3105 : static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(int atomic_alloc)
     688                 :            : {
     689         [ +  - ]:       3105 :         if (atomic_alloc)
     690                 :       3105 :                 return (dwc_otg_qh_t *) DWC_ALLOC_ATOMIC(sizeof(dwc_otg_qh_t));
     691                 :            :         else
     692                 :          0 :                 return (dwc_otg_qh_t *) DWC_ALLOC(sizeof(dwc_otg_qh_t));
     693                 :            : }
     694                 :            : 
     695                 :            : extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb,
     696                 :            :                                              int atomic_alloc);
     697                 :            : extern void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb);
     698                 :            : extern int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, dwc_otg_hcd_t * dwc_otg_hcd,
     699                 :            :                                dwc_otg_qh_t ** qh, int atomic_alloc);
     700                 :            : 
     701                 :            : /** Allocates memory for a QTD structure.
     702                 :            :  * @return Returns the memory allocate or NULL on error. */
     703                 :     134750 : static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(int atomic_alloc)
     704                 :            : {
     705         [ +  - ]:     134750 :         if (atomic_alloc)
     706                 :     134750 :                 return (dwc_otg_qtd_t *) DWC_ALLOC_ATOMIC(sizeof(dwc_otg_qtd_t));
     707                 :            :         else
     708                 :          0 :                 return (dwc_otg_qtd_t *) DWC_ALLOC(sizeof(dwc_otg_qtd_t));
     709                 :            : }
     710                 :            : 
     711                 :            : /** Frees the memory for a QTD structure.  QTD should already be removed from
     712                 :            :  * list.
     713                 :            :  * @param qtd QTD to free.*/
     714                 :            : static inline void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t * qtd)
     715                 :            : {
     716                 :     126450 :         DWC_FREE(qtd);
     717                 :            : }
     718                 :            : 
     719                 :            : /** Removes a QTD from list.
     720                 :            :  * @param hcd HCD instance.
     721                 :            :  * @param qtd QTD to remove from list.
     722                 :            :  * @param qh QTD belongs to.
     723                 :            :  */
     724                 :            : static inline void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t * hcd,
     725                 :            :                                           dwc_otg_qtd_t * qtd,
     726                 :            :                                           dwc_otg_qh_t * qh)
     727                 :            : {
     728   [ +  +  +  - ]:     126450 :         DWC_CIRCLEQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry);
     729                 :            : }
     730                 :            : 
     731                 :            : /** Remove and free a QTD
     732                 :            :   * Need to disable IRQ and hold hcd lock while calling this function out of
     733                 :            :   * interrupt servicing chain */
     734                 :     126450 : static inline void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t * hcd,
     735                 :            :                                                    dwc_otg_qtd_t * qtd,
     736                 :            :                                                    dwc_otg_qh_t * qh)
     737                 :            : {
     738                 :            :         dwc_otg_hcd_qtd_remove(hcd, qtd, qh);
     739                 :            :         dwc_otg_hcd_qtd_free(qtd);
     740                 :     126450 : }
     741                 :            : 
     742                 :            : /** @} */
     743                 :            : 
     744                 :            : /** @name Descriptor DMA Supporting Functions */
     745                 :            : /** @{ */
     746                 :            : 
     747                 :            : extern void dwc_otg_hcd_start_xfer_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     748                 :            : extern void dwc_otg_hcd_complete_xfer_ddma(dwc_otg_hcd_t * hcd,
     749                 :            :                                            dwc_hc_t * hc,
     750                 :            :                                            dwc_otg_hc_regs_t * hc_regs,
     751                 :            :                                            dwc_otg_halt_status_e halt_status);
     752                 :            : 
     753                 :            : extern int dwc_otg_hcd_qh_init_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     754                 :            : extern void dwc_otg_hcd_qh_free_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh);
     755                 :            : 
     756                 :            : /** @} */
     757                 :            : 
     758                 :            : /** @name Internal Functions */
     759                 :            : /** @{ */
     760                 :            : dwc_otg_qh_t *dwc_urb_to_qh(dwc_otg_hcd_urb_t * urb);
     761                 :            : /** @} */
     762                 :            : 
     763                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
     764                 :            : extern int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd,
     765                 :            :                                            uint8_t devaddr);
     766                 :            : extern void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd);
     767                 :            : #endif
     768                 :            : 
     769                 :            : /** Gets the QH that contains the list_head */
     770                 :            : #define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry)
     771                 :            : 
     772                 :            : /** Gets the QTD that contains the list_head */
     773                 :            : #define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry)
     774                 :            : 
     775                 :            : /** Check if QH is non-periodic  */
     776                 :            : #define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == UE_BULK) || \
     777                 :            :                                      (_qh_ptr_->ep_type == UE_CONTROL))
     778                 :            : 
     779                 :            : /** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
     780                 :            : #define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
     781                 :            : 
     782                 :            : /** Packet size for any kind of endpoint descriptor */
     783                 :            : #define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
     784                 :            : 
     785                 :            : /**
     786                 :            :  * Returns true if _frame1 is less than or equal to _frame2. The comparison is
     787                 :            :  * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
     788                 :            :  * frame number when the max frame number is reached.
     789                 :            :  */
     790                 :            : static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2)
     791                 :            : {
     792                 :  290365906 :         return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <=
     793                 :            :             (DWC_HFNUM_MAX_FRNUM >> 1);
     794                 :            : }
     795                 :            : 
     796                 :            : /**
     797                 :            :  * Returns true if _frame1 is greater than _frame2. The comparison is done
     798                 :            :  * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
     799                 :            :  * number when the max frame number is reached.
     800                 :            :  */
     801                 :            : static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2)
     802                 :            : {
     803   [ #  #  #  # ]:          0 :         return (frame1 != frame2) &&
     804                 :          0 :             (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) <
     805                 :            :              (DWC_HFNUM_MAX_FRNUM >> 1));
     806                 :            : }
     807                 :            : 
     808                 :            : /**
     809                 :            :  * Increments _frame by the amount specified by _inc. The addition is done
     810                 :            :  * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
     811                 :            :  */
     812                 :            : static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc)
     813                 :            : {
     814                 :    6761328 :         return (frame + inc) & DWC_HFNUM_MAX_FRNUM;
     815                 :            : }
     816                 :            : 
     817                 :            : static inline uint16_t dwc_full_frame_num(uint16_t frame)
     818                 :            : {
     819                 :          0 :         return (frame & DWC_HFNUM_MAX_FRNUM) >> 3;
     820                 :            : }
     821                 :            : 
     822                 :            : static inline uint16_t dwc_micro_frame_num(uint16_t frame)
     823                 :            : {
     824                 :          0 :         return frame & 0x7;
     825                 :            : }
     826                 :            : 
     827                 :            : extern void init_hcd_usecs(dwc_otg_hcd_t *_hcd);
     828                 :            : 
     829                 :            : void dwc_otg_hcd_save_data_toggle(dwc_hc_t * hc,
     830                 :            :                                   dwc_otg_hc_regs_t * hc_regs,
     831                 :            :                                   dwc_otg_qtd_t * qtd);
     832                 :            : 
     833                 :            : #ifdef DEBUG
     834                 :            : /**
     835                 :            :  * Macro to sample the remaining PHY clocks left in the current frame. This
     836                 :            :  * may be used during debugging to determine the average time it takes to
     837                 :            :  * execute sections of code. There are two possible sample points, "a" and
     838                 :            :  * "b", so the _letter argument must be one of these values.
     839                 :            :  *
     840                 :            :  * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
     841                 :            :  * example, "cat /sys/devices/lm0/hcd_frrem".
     842                 :            :  */
     843                 :            : #define dwc_sample_frrem(_hcd, _qh, _letter) \
     844                 :            : { \
     845                 :            :         hfnum_data_t hfnum; \
     846                 :            :         dwc_otg_qtd_t *qtd; \
     847                 :            :         qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \
     848                 :            :         if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \
     849                 :            :                 hfnum.d32 = DWC_READ_REG32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
     850                 :            :                 switch (hfnum.b.frnum & 0x7) { \
     851                 :            :                 case 7: \
     852                 :            :                         _hcd->hfnum_7_samples_##_letter++; \
     853                 :            :                         _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
     854                 :            :                         break; \
     855                 :            :                 case 0: \
     856                 :            :                         _hcd->hfnum_0_samples_##_letter++; \
     857                 :            :                         _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
     858                 :            :                         break; \
     859                 :            :                 default: \
     860                 :            :                         _hcd->hfnum_other_samples_##_letter++; \
     861                 :            :                         _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \
     862                 :            :                         break; \
     863                 :            :                 } \
     864                 :            :         } \
     865                 :            : }
     866                 :            : #else
     867                 :            : #define dwc_sample_frrem(_hcd, _qh, _letter)
     868                 :            : #endif
     869                 :            : #endif
     870                 :            : #endif /* DWC_DEVICE_ONLY */

Generated by: LCOV version 1.14