1 /*
2  * Copyright (c) 2015 -2016, Freescale Semiconductor, Inc.
3  * Copyright 2016,2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __USB_HOST_KHCI_H__
10 #define __USB_HOST_KHCI_H__
11 
12 /*******************************************************************************
13  * KHCI driver private structures, enumerations, macros, functions
14  ******************************************************************************/
15 
16 /*******************************************************************************
17  * Definitions
18  ******************************************************************************/
19 #define USB_KHCI_MAX_SPEED_DETECTION_COUNT 3U
20 
21 /* usb khci atom transaction error results */
22 #define USB_KHCI_ATOM_TR_PID_ERROR (-1)
23 #define USB_KHCI_ATOM_TR_EOF_ERROR (-2)
24 #define USB_KHCI_ATOM_TR_CRC_ERROR (-4)
25 #define USB_KHCI_ATOM_TR_TO (-16)
26 #define USB_KHCI_ATOM_TR_DMA_ERROR (-32)
27 #define USB_KHCI_ATOM_TR_BTS_ERROR (-128)
28 #define USB_KHCI_ATOM_TR_NAK (-256)
29 #define USB_KHCI_ATOM_TR_DATA_ERROR (-512)
30 #define USB_KHCI_ATOM_TR_STALL (-1024)
31 #define USB_KHCI_ATOM_TR_RESET (-2048)
32 #define USB_KHCI_ATOM_TR_BUS_TIMEOUT (-4096)
33 #define USB_KHCI_ATOM_TR_INVALID (-8192)
34 
35 /* KHCI event bits */
36 #define USB_KHCI_EVENT_ATTACH 0x01U
37 #define USB_KHCI_EVENT_RESET 0x02U
38 #define USB_KHCI_EVENT_TOK_DONE 0x04U
39 #define USB_KHCI_EVENT_SOF_TOK 0x08U
40 #define USB_KHCI_EVENT_DETACH 0x10U
41 #define USB_KHCI_EVENT_MSG 0x20U
42 #define USB_KHCI_EVENT_ISO_MSG 0x40U
43 #define USB_KHCI_EVENT_RESUME 0x80U
44 #define USB_KHCI_EVENT_MASK 0xffU
45 
46 typedef enum _transfer_status
47 {
48     kTransfer_Idle = 0,
49     kTransfer_Setup0,
50     kTransfer_Setup1,
51     kTransfer_Setup2,
52     kTransfer_Setup3,
53 } transfer_status_t;
54 
55 typedef enum _khci_intr_type
56 {
57     kIntr_UsbRst = 0x01,
58     kIntr_Error  = 0x02,
59     kIntr_SofTok = 0x04,
60     kIntr_TokDne = 0x08,
61     kIntr_Sleep  = 0x10,
62     kIntr_Resume = 0x20,
63     kIntr_Attach = 0x40,
64     kIntr_Stall  = 0x80,
65 } khci_intr_type_t;
66 
67 typedef enum _tr_type
68 {
69     kTr_Ctrl = 0,
70     kTr_In,
71     kTr_Out,
72     kTr_OutHndsk,
73     kTr_InHndsk,
74     kTr_Unknown
75 } tr_type_t;
76 
77 /* Transaction type */
78 typedef enum _tr_request_type
79 {
80     kTr_MsgUnknown = 0, /*Unknown - not used */
81     kTr_MsgSetup,       /* Set up transaction */
82     kTr_MsgSend,        /* Send transaction */
83     kTr_MsgRecv         /* Receive transaction */
84 } tr_request_type_t;
85 
86 typedef enum tr_request_state
87 {
88     kTr_MsgIdle = 0, /*Normal transfer */
89     kTr_MsgNak,      /* NAK transfer */
90     kTr_BusTimeout,
91 } tr_request_state_t;
92 
93 typedef enum khci_tr_state
94 {
95     kKhci_TrGetMsg = 0,
96     kKhci_IsoTrGetMsg,
97     kKhci_TrStartTransmit,
98     kKhci_TrTransmiting,
99     kKhci_TrTransmitDone,
100     kKhci_TrNone
101 } khci_tr_state_t;
102 
103 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
104 typedef enum bus_suspend_request_state
105 {
106     kBus_Idle = 0,
107     kBus_StartSuspend,
108     kBus_Suspended,
109     kBus_StartResume,
110 } bus_suspend_request_state_t;
111 #endif
112 
113 /* Defines the USB KHCI time out value from USB specification */
114 #define USB_TIMEOUT_NODATA (5000)
115 #define USB_TIMEOUT_TOHOST (5000)
116 #define USB_TIMEOUT_TODEVICE (5000)
117 #define USB_TIMEOUT_OTHER (10000U)
118 #define USB_TIMEOUT_DEFAULT (500)
119 
120 #define NAK_RETRY_TIME (1U)
121 #define RETRY_TIME (3U)
122 
123 /* Define USB buffer descriptor operator MACRO definitions; This part is not included in header files  */
124 #define USB_KHCI_BDT_BASE ((&bdt[0]))
125 #define USB_KHCI_BD_PTR(ep, rxtx, odd) \
126     ((((uint32_t)USB_KHCI_BDT_BASE) & 0xfffffe00U) | (((ep)&0x0fu) << 5) | (((rxtx)&1u) << 4) | (((odd)&1u) << 3))
127 
128 #define USB_KHCI_BD_CTRL(ep, rxtx, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, rxtx, odd)))
129 #define USB_KHCI_BD_CTRL_RX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 0, odd)))
130 #define USB_KHCI_BD_CTRL_TX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 1, odd)))
131 
132 #define USB_KHCI_BD_ADDR(ep, rxtx, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, rxtx, odd) + 1))
133 #define USB_KHCI_BD_ADDR_RX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 0, odd) + 1))
134 #define USB_KHCI_BD_ADDR_TX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 1, odd) + 1))
135 
136 /* Define USB buffer descriptor definitions; This part is not included in header files  */
137 #define USB_KHCI_BD_BC(n) ((n & 0x3ffu) << 16)
138 #define USB_KHCI_BD_OWN 0x80u
139 #define USB_KHCI_BD_DATA01(n) ((n & 1u) << 6)
140 #define USB_KHCI_BD_DATA0 USB_KHCI_BD_DATA01(0u)
141 #define USB_KHCI_BD_DATA1 USB_KHCI_BD_DATA01(1u)
142 #define USB_KHCI_BD_KEEP 0x20u
143 #define USB_KHCI_BD_NINC 0x10u
144 #define USB_KHCI_BD_DTS 0x08u
145 #define USB_KHCI_BD_STALL 0x04u
146 #define USB_KHCI_BD_PID(n) ((n & 0x0fu) << 2)
147 
148 #define USB_HostKhciLock() (void)OSA_MutexLock(usbHostPointer->khciMutex, USB_OSA_WAIT_TIMEOUT)
149 #define USB_HostKhciUnlock() (void)OSA_MutexUnlock(usbHostPointer->khciMutex)
150 
151 typedef struct _khci_xfer_sts
152 {
153     uint32_t rxLen;
154     uint8_t *rxBuf;
155     uint8_t *rxBufOrig;
156     uint8_t isDmaAlign;
157 } khci_xfer_sts_t;
158 
159 /*******************************************************************************
160  * KHCI driver public structures, enumerations, macros, functions
161  ******************************************************************************/
162 
163 /*!
164  * @addtogroup usb_host_controller_khci
165  * @{
166  */
167 
168 /*! @brief  The value programmed into the threshold register must reserve enough time to ensure the worst case
169    transaction completes. In general, the worst case transaction is an IN token followed by a data packet from the
170    target followed by the response from the host. The actual time required is a function of the maximum packet size on
171    the bus. Set the KHCICFG_THSLD_DELAY to 0x65 to meet the worst case.*/
172 
173 #define KHCICFG_THSLD_DELAY 0x65U
174 
175 /*! @brief KHCI controller driver instance structure */
176 typedef struct _usb_khci_host_state_struct
177 {
178     volatile USB_Type *usbRegBase;              /*!< The base address of the register */
179     void *hostHandle;                           /*!< Related host handle*/
180     usb_host_pipe_t *pipeDescriptorBasePointer; /*!< Pipe descriptor bas pointer*/
181     osa_event_handle_t khciEventPointer;
182     uint32_t taskEventHandleBuffer[(OSA_EVENT_HANDLE_SIZE + 3) / 4]; /*!< KHCI task event handle buffer*/
183     osa_mutex_handle_t khciMutex;                                    /*!< KHCI mutex*/
184     uint32_t mutexBuffer[(OSA_MUTEX_HANDLE_SIZE + 3) / 4];           /*!< The mutex buffer. */
185     usb_host_transfer_t
186         *periodicListPointer; /*!< KHCI periodic list pointer, which link is an interrupt and an ISO transfer request*/
187     usb_host_transfer_t *asyncListPointer; /*!< KHCI async list pointer, which link controls and bulk transfer request*/
188     khci_xfer_sts_t sXferSts;              /*!< KHCI transfer status structure for the DAM ALIGN workaround */
189     uint8_t *khciSwapBufPointer;           /*!< KHCI swap buffer pointer for the DAM ALIGN workaround*/
190     volatile uint32_t trState;             /*!< KHCI transfer state*/
191 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
192     uint64_t matchTick;
193 #endif
194     uint8_t asyncListAvtive;    /*!< KHCI async list is active*/
195     uint8_t periodicListAvtive; /*!< KHCI periodic list is active*/
196     uint8_t rxBd;               /*!< RX buffer descriptor toggle bits*/
197     uint8_t txBd;               /*!< TX buffer descriptor toggle bits*/
198     uint8_t deviceSpeed;        /*!< Device speed*/
199 #if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U))
200     bus_suspend_request_state_t busSuspendStatus; /*!< Bus Suspend Status*/
201 #endif
202     int8_t deviceAttached; /*!< Device attach/detach state */
203 } usb_khci_host_state_struct_t, *ptr_usb_host_khci_state_struct_t;
204 
205 #ifdef __cplusplus
206 extern "C" {
207 #endif
208 /*!
209  * @name USB host KHCI APIs
210  * @{
211  */
212 
213 /*!
214  * @brief Creates the USB host KHCI instance.
215  *
216  * This function initializes the USB host KHCI controller driver.
217  *
218  * @param controllerId      The controller ID of the USB IP. See the enumeration usb_controller_index_t.
219  * @param hostHandle The host level handle.
220  * @param controllerHandle  Returns the controller instance handle.
221  *
222  * @retval kStatus_USB_Success              The host is initialized successfully.
223  * @retval kStatus_USB_AllocFail            Allocates memory failed.
224  * @retval kStatus_USB_Error                Host mutex create failed, KHCI mutex or KHCI event create failed.
225  *                                          Or, KHCI IP initialize failed.
226  */
227 extern usb_status_t USB_HostKhciCreate(uint8_t controllerId,
228                                        usb_host_handle hostHandle,
229                                        usb_host_controller_handle *controllerHandle);
230 
231 /*!
232  * @brief Destroys the USB host KHCI instance.
233  *
234  * This function deinitializes the USB host KHCI controller driver.
235  *
236  * @param controllerHandle  The controller handle.
237  *
238  * @retval kStatus_USB_Success              The host is initialized successfully.
239  */
240 extern usb_status_t USB_HostKhciDestory(usb_host_controller_handle controllerHandle);
241 
242 /*!
243  * @brief Opens the USB host pipe.
244  *
245  * This function opens a pipe according to the pipe_init_ptr parameter.
246  *
247  * @param controllerHandle    The controller handle.
248  * @param pipeHandlePointer   The pipe handle pointer used to return the pipe handle.
249  * @param pipeInitPointer     It is used to initialize the pipe.
250  *
251  * @retval kStatus_USB_Success              The host is initialized successfully.
252  * @retval kStatus_USB_Error                There is no idle pipe.
253  *
254  */
255 extern usb_status_t USB_HostKhciOpenPipe(usb_host_controller_handle controllerHandle,
256                                          usb_host_pipe_handle *pipeHandlePointer,
257                                          usb_host_pipe_init_t *pipeInitPointer);
258 
259 /*!
260  * @brief Closes the USB host pipe.
261  *
262  * This function closes a pipe and frees the related resources.
263  *
264  * @param controllerHandle The controller handle.
265  * @param pipeHandle       The closing pipe handle.
266  *
267  * @retval kStatus_USB_Success              The host is initialized successfully.
268  */
269 extern usb_status_t USB_HostKhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle);
270 
271 /*!
272  * @brief Sends data to the pipe.
273  *
274  * This function requests to send the transfer to the specified pipe.
275  *
276  * @param controllerHandle The controller handle.
277  * @param pipeHandle       The sending pipe handle.
278  * @param transfer          The transfer information.
279  *
280  * @retval kStatus_USB_Success                  Send successful.
281  * @retval kStatus_USB_LackSwapBuffer       There is no swap buffer for KHCI.
282  */
283 extern usb_status_t USB_HostKhciWritePipe(usb_host_controller_handle controllerHandle,
284                                           usb_host_pipe_handle pipeHandle,
285                                           usb_host_transfer_t *transfer);
286 
287 /*!
288  * @brief Receives data from the pipe.
289  *
290  * This function requests to receive the transfer from the specified pipe.
291  *
292  * @param controllerHandle The controller handle.
293  * @param pipeHandle       The receiving pipe handle.
294  * @param transfer          The transfer information.
295  *
296  * @retval kStatus_USB_Success                  Receive successful.
297  * @retval kStatus_USB_LackSwapBuffer       There is no swap buffer for KHCI.
298  */
299 extern usb_status_t USB_HostKhciReadpipe(usb_host_controller_handle controllerHandle,
300                                          usb_host_pipe_handle pipeHandle,
301                                          usb_host_transfer_t *transfer);
302 
303 /*!
304  * @brief Controls the KHCI.
305  *
306  * This function controls the KHCI.
307  *
308  * @param controllerHandle The controller handle.
309  * @param ioctlEvent       See the enumeration host_bus_control_t.
310  * @param ioctlParam       The control parameter.
311  *
312  * @retval kStatus_USB_Success                Cancel successful.
313  * @retval kStatus_USB_InvalidHandle        The controllerHandle is a NULL pointer.
314  */
315 extern usb_status_t USB_HostKciIoctl(usb_host_controller_handle controllerHandle,
316                                      uint32_t ioctlEvent,
317                                      void *ioctlParam);
318 
319 /*! @}*/
320 #ifdef __cplusplus
321 }
322 #endif
323 /*! @}*/
324 #endif /* __USB_HOST_KHCI_H__ */
325