1 /*******************************************************************************
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * PolarFire SoC MSS USB Driver Stack
7  *      USB Core Interface Layer (USB-CIFL)
8  *          USB-CIF driver
9  *
10  * USB-CIF driver public API.
11  *
12  */
13 
14 #ifndef __MSS_USB_COMMON_CIF_H_
15 #define __MSS_USB_COMMON_CIF_H_
16 
17 #include "mss_usb_config.h"
18 #include "mss_usb_core_regs.h"
19 
20 #define __INLINE        inline
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /*-------------------------------------------------------------------------*//**
27   Constant values internally used by the driver.
28  */
29 #define CEP_MAX_PKT_SIZE                                64u
30 #define SETUP_PKT_SIZE                                  8u
31 
32 #define DPB_DISABLE                                     0u
33 #define DPB_ENABLE                                      1u
34 
35 #ifdef MSS_USB_HOST_ENABLED
36 #define SUSPENDM_DISABLE                                0x0000u
37 #define SUSPENDM_ENABLE                                 0x0001u
38 #endif
39 
40 #define MSS_USB_WORD_BIT_0_MASK                         0x0001u
41 #define MSS_USB_BYTE_BIT_0_MASK                         0x01u
42 
43 #define MSS_USB_BOOLEAN_FALSE                           0x00u
44 #define MSS_USB_BOOLEAN_TRUE                            0x01u
45 
46 #define TX_EP_UNDER_RUN_ERROR                           0x01u
47 #define TX_EP_STALL_ERROR                               0x02u
48 
49 #define RX_EP_OVER_RUN_ERROR                            0x01u
50 #define RX_EP_STALL_ERROR                               0x02u
51 #define RX_EP_DATA_ERROR                                0x04u
52 #define RX_EP_PID_ERROR                                 0x06u
53 #define RX_EP_ISO_INCOMP_ERROR                          0x08u
54 
55 #define CTRL_EP_SETUP_END_ERROR                         0x01u
56 #define CTRL_EP_STALL_ERROR                             0x02u
57 
58 #define DMA_XFR_ERROR                                   0x40u
59 
60 #define MIN_EP_FIFO_SZ                                  0x0008u
61 #define EP_FIFO_ADDR_STEP                               0x0008u
62 
63 #define DMA_DISABLE                                     0u
64 #define DMA_ENABLE                                      1u
65 
66 #define NO_ZLP_TO_XFR                                   0u
67 #define ADD_ZLP_TO_XFR                                  1u
68 
69 /*-------------------------------------------------------------------------*//**
70   INTRUSBE register - USB interrupts masks
71  */
72 #define SUSPEND_IRQ_MASK                                0x01u
73 #define RESUME_IRQ_MASK                                 0x02u
74 #define RESET_IRQ_MASK                                  0x04u   /*Device mode*/
75 #define BABBLE_IRQ_MASK                                 0x04u   /*Host mode*/
76 #define SOF_IRQ_MASK                                    0x08u
77 #define CONNECT_IRQ_MASK                                0x10u
78 #define DISCONNECT_IRQ_MASK                             0x20u
79 #define SESSION_REQUEST_IRQ_MASK                        0x40u
80 #define VBUS_ERROR_IRQ_MASK                             0x80u
81 
82 /*-------------------------------------------------------------------------*//**
83   Types which can be used by LDL layer or the application.
84  */
85 
86 typedef enum {
87     MSS_USB_XFR_CONTROL,
88     MSS_USB_XFR_ISO,
89     MSS_USB_XFR_BULK,
90     MSS_USB_XFR_INTERRUPT,
91     MSS_USB_XFR_HB_INTERRUPT,
92     MSS_USB_XFR_HB_ISO
93 } mss_usb_xfr_type_t;
94 
95 typedef enum {
96     MSS_USB_DEVICE_HS,
97     MSS_USB_DEVICE_FS,
98     MSS_USB_DEVICE_LS
99 } mss_usb_device_speed_t;
100 
101 typedef enum {
102     MSS_USB_CEP = 0,
103     MSS_USB_TX_EP_1,
104     MSS_USB_TX_EP_2,
105     MSS_USB_TX_EP_3,
106     MSS_USB_TX_EP_4,
107 
108     MSS_USB_RX_EP_1 = 1,
109     MSS_USB_RX_EP_2,
110     MSS_USB_RX_EP_3,
111     MSS_USB_RX_EP_4
112 } mss_usb_ep_num_t;
113 
114 typedef enum {
115     MSS_USB_DMA_CHANNEL1,
116     MSS_USB_DMA_CHANNEL2,
117     MSS_USB_DMA_CHANNEL3,
118     MSS_USB_DMA_CHANNEL4,
119     MSS_USB_DMA_CHANNEL_NA
120 } mss_usb_dma_channel_t;
121 
122 /*-------------------------------------------------------------------------*//**
123   Types which are used internally by the driver.
124  */
125 
126 /* Device mode:  states of the device */
127 typedef enum {
128     MSS_USB_NOT_ATTACHED_STATE,
129     MSS_USB_ATTACHED_STATE,
130     MSS_USB_POWERED_STATE,
131     MSS_USB_DEFAULT_STATE,
132     MSS_USB_ADDRESS_STATE,
133     MSS_USB_CONFIGURED_STATE,
134     MSS_USB_SUSPENDED_STATE
135 } mss_usb_state_t;
136 
137 typedef enum {
138     MSS_USB_CORE_MODE_HOST,
139     MSS_USB_CORE_MODE_DEVICE
140 } mss_usb_core_mode_t;
141 
142 typedef enum {
143     MSS_USB_EP_VALID = 0u,
144     MSS_USB_EP_STALLED,
145     MSS_USB_EP_NAK,
146     MSS_USB_EP_NYET,
147     MSS_USB_CEP_IDLE,
148     MSS_USB_CEP_SETUP,
149     MSS_USB_CEP_TX,
150     MSS_USB_CEP_RX,
151 
152 #ifdef MSS_USB_HOST_ENABLED
153     MSS_USB_CEP_STATUS_AFTER_IN,
154     MSS_USB_CEP_STATUS_AFTER_OUT,
155     MSS_USB_EP_TXN_SUCCESS,
156     MSS_USB_EP_NAK_TOUT,
157     MSS_USB_EP_NO_RESPONSE,
158     MSS_USB_EP_STALL_RCVD,
159     MSS_USB_EP_XFR_SUCCESS,
160     MSS_USB_EP_ABORTED
161 #endif  /* MSS_USB_HOST_ENABLED */
162 
163 } mss_usb_ep_state_t;
164 
165 typedef enum mss_usb_pkt_type {
166     MSS_USB_SETUP_PKT,
167     MSS_USB_IN_DATA_PKT,
168     MSS_USB_OUT_DATA_PKT,
169     MSS_USB_STATUS_PKT_AFTER_IN,
170     MSS_USB_STATUS_PKT_AFTER_OUT
171 }mss_usb_pkt_type_t;
172 
173  /*
174   Type of device - Detected through DevCTL.D7 register bit depending
175   on the type of connector connected to on-board receptacle.
176   */
177 typedef enum mss_usb_device_role {
178     MSS_USB_DEVICE_ROLE_DEVICE_A,
179     MSS_USB_DEVICE_ROLE_DEVICE_B
180 } mss_usb_device_role_t;
181 
182 typedef enum {
183     MSS_USB_DMA_WRITE,
184     MSS_USB_DMA_READ
185 } mss_usb_dma_dir_t;
186 
187 typedef enum
188 {
189     MSS_USB_DMA_MODE0=0,
190     MSS_USB_DMA_MODE1=1
191 } mss_usb_dma_mode_t;
192 
193 typedef enum {
194     MSS_USB_DMA_BURST_MODE0 = 0,
195     MSS_USB_DMA_BURST_MODE1,
196     MSS_USB_DMA_BURST_MODE2,
197     MSS_USB_DMA_BURST_MODE3
198 } mss_usb_dma_burst_mode_t;
199 
200 typedef enum {
201     VBUS_BLOW_SESSIONEND,
202     VBUS_ABV_SESSIONEND_BLOW_AVALID,
203     VBUS_ABV_AVALID_BLOW_VB_VALID,
204     VBUS_ABV_VB_VALID
205 } mss_usb_vbus_level_t;
206 
207 #ifdef MSS_USB_DEVICE_ENABLED
208 typedef enum {
209     MSS_USB_CTRL_EP_IDLE,
210     MSS_USB_CTRL_EP_TX,
211     MSS_USB_CTRL_EP_RX
212 } mss_usbd_cep_state_t;
213 #endif  /* MSS_USB_DEVICE_ENABLED */
214 
215 /*-------------------------------------------------------------------------*//**
216   Data structures of USB-CIFL which are shared with USB-LL.
217  */
218 typedef struct {
219     /*EP configuration info*/
220     mss_usb_ep_num_t            num;
221 
222     uint8_t                     dpb_enable;         /*0 or 1*/
223     uint16_t                    fifo_size;          /*number of bytes*/
224     uint16_t                    fifo_addr;          /*number of bytes*/
225     uint8_t                     dma_enable;
226     mss_usb_dma_channel_t       dma_channel;
227     uint16_t                    max_pkt_size;       /*Maxpktsize register value*/
228 
229     uint8_t                     stall;
230     mss_usb_ep_state_t          state;
231 
232     /*EP data Transfer related info*/
233     mss_usb_xfr_type_t          xfr_type;
234     uint32_t                    add_zlp;
235 
236     /*
237      Number of pkts in one uFrame in case of Interrupt/ISO HB transfers. Number
238      of split packets in case of Bulk transfers.Should always be more than 0.
239      */
240     uint8_t                     num_usb_pkt;
241     uint8_t*                    buf_addr;
242 
243     /*
244      Transfer level info, used mainly for control transfer where the
245      total length of data transfer is prior know through setup transaction
246      In case of bulk transfer with Autospliting/amalgamation, this value is used
247      when length of transfer is bigger than one amalgamated packet.
248      */
249     uint32_t                    xfr_length;
250     uint32_t                    xfr_count;
251 
252     /*
253      Single packet Transaction level info
254      In case of bulk transfer with Autospliting/amalgamation, this value
255      represents the amalgamated packet.
256      */
257     uint32_t                    txn_length;
258     uint32_t                    txn_count;
259 
260 #ifdef MSS_USB_HOST_ENABLED
261     /*
262     Manual toggle enable is required only when dynamic switching of EP is supported.
263     We don't support it.
264     HubAddr and HubPortNum registers are needed for talking to LS/FS devices
265     connected through Hub - We don't support hub connected devices yet.
266     LS/FS device directly connected to SF2 is supported though.
267     */
268     uint8_t                     cep_data_dir;
269     uint8_t*                    cep_cmd_addr;
270     uint8_t                     disable_ping;       /*Depends on target speed*/
271     uint32_t                    req_pkt_n;          /*No of IN packets*/
272     /*
273      Interval Must be in terms of frame/uframe. Indicates NAKLIMIT0 register value
274      for EP0. TX/RXInterval register value for TX/RX EP.
275      */
276     uint32_t                    interval;
277     /*This index will be used to choose a particular connected device out of the
278       Multiple connected devices when Multiple devices are supported.
279       Currently we support only one device hence this will always evaluate to 0*/
280     uint8_t                     tdev_idx;
281 
282 #endif  /* MSS_USB_HOST_ENABLED */
283 
284 }mss_usb_ep_t;
285 
286 /*-------------------------------------------------------------------------*//**
287   Data structures which are used internally by the driver.
288  */
289 /*Device mode configuration information*/
290 typedef struct {
291     uint8_t                        device_addr;
292     uint8_t                        device_total_interfaces;
293     uint8_t                        device_total_ep;
294     mss_usb_state_t                device_state;
295     mss_usb_state_t                device_state_at_suspend;
296     uint8_t                        device_status;
297     mss_usb_device_speed_t         device_speed;    /*USB speed in Device mode*/
298     uint8_t                        active_config_num;      /*SetConfig command*/
299     uint8_t                        active_interface_num;/*SetInterface command*/
300     uint16_t                       config_feature_status;
301     uint8_t                        remote_wakeup;
302 } mss_usbd_dev_conf_t;
303 
304 /* Device mode call-back function called from CIF layer */
305 typedef struct {
306     void (*usbd_ep_rx)( mss_usb_ep_num_t num, uint8_t status );
307     void (*usbd_ep_tx_complete)( mss_usb_ep_num_t num, uint8_t status );
308 
309     void (*usbd_cep_setup)( uint8_t status );
310     void (*usbd_cep_rx)( uint8_t status );
311     void (*usbd_cep_tx_complete)( uint8_t status );
312 
313     void (*usbd_sof)( uint8_t status );
314     void (*usbd_reset)( void );
315     void (*usbd_suspend)( void );
316     void (*usbd_resume)( void );
317     void (*usbd_disconnect)( void );
318     void (*usbd_dma_handler)(mss_usb_ep_num_t ep_num, mss_usb_dma_dir_t dma_dir,
319                              uint8_t status, uint32_t dma_addr_val);
320 } mss_usbd_cb_t;
321 
322 /* MSS USB Hardware core information. This is read-only */
323 typedef struct {
324     uint8_t core_max_nbr_of_tx_ep;
325     uint8_t core_max_nbr_of_rx_ep;
326     uint8_t core_max_nbr_of_dma_chan;
327     uint8_t core_ram_bus_width;
328     uint8_t core_WTCON;
329     uint8_t core_WTID;
330     uint8_t core_VPLEN;
331     uint8_t core_HS_EOF1;
332     uint8_t core_FS_EOF1;
333     uint8_t core_LS_EOF1;
334     uint8_t core_configdata;
335 } mss_usb_core_info_t;
336 
337 /* Internal DMA Configuration data */
338 typedef struct {
339     uint8_t dma_channel;
340     uint8_t dma_dir;
341     uint8_t dma_assigned_ep;
342     uint8_t dma_mode;
343     uint8_t dma_burst_mode;
344     uint8_t dma_status;
345 } mss_usb_dma_t;
346 
347 
348 /*----------------------------------------------------------------------------*/
349 /*_------------------------USB-CIF Public APIs--------------------------------*/
350 /*----------------------------------------------------------------------------*/
351 
352 /*-------------------------------------------------------------------------*//**
353  */
MSS_USB_CIF_cep_flush_fifo(void)354 static __INLINE void MSS_USB_CIF_cep_flush_fifo(void)
355 {
356     USB->INDEXED_CSR.DEVICE_EP0.CSR0 |= CSR0H_DEV_FLUSH_FIFO_MASK;
357 }
358 
359 /*-------------------------------------------------------------------------*//**
360 */
MSS_USB_CIF_tx_ep_flush_fifo(mss_usb_ep_num_t ep_num)361 static __INLINE void MSS_USB_CIF_tx_ep_flush_fifo(mss_usb_ep_num_t ep_num)
362 {
363     USB->ENDPOINT[ep_num].TX_CSR |= TxCSRL_REG_EPN_FLUSH_FIFO_MASK;
364 }
365 
366 /*-------------------------------------------------------------------------*//**
367 */
MSS_USB_CIF_rx_ep_flush_fifo(mss_usb_ep_num_t ep_num)368 static __INLINE void MSS_USB_CIF_rx_ep_flush_fifo(mss_usb_ep_num_t ep_num)
369 {
370     USB->ENDPOINT[ep_num].RX_CSR |= RxCSRL_REG_EPN_FLUSH_FIFO_MASK;
371 }
372 
373 /*-------------------------------------------------------------------------*//**
374 */
MSS_USB_CIF_rx_ep_is_fifo_full(mss_usb_ep_num_t ep_num)375 static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_fifo_full(mss_usb_ep_num_t ep_num)
376 {
377     return(((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_RX_FIFO_FULL_MASK) ?
378                                     MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE));
379 }
380 
381 /*-------------------------------------------------------------------------*//**
382  * Enables USB interrupts.
383  */
MSS_USB_CIF_enable_usbirq(uint8_t irq_mask)384 static __INLINE void MSS_USB_CIF_enable_usbirq(uint8_t irq_mask)
385 {
386     USB->USB_ENABLE |= (irq_mask);
387 }
388 
389 /*-------------------------------------------------------------------------*//**
390   Disables USB interrupts.
391  */
MSS_USB_CIF_disable_usbirq(uint8_t irq_mask)392 static __INLINE void MSS_USB_CIF_disable_usbirq(uint8_t irq_mask)
393 {
394     USB->USB_ENABLE &= ~(irq_mask);
395 }
396 /*-------------------------------------------------------------------------*//**
397   Indicates that there is at least one byte available to be transmitted from
398   TX FIFO
399  */
MSS_USB_CIF_is_txepfifo_notempty(mss_usb_ep_num_t ep_num)400 static __INLINE uint8_t MSS_USB_CIF_is_txepfifo_notempty(mss_usb_ep_num_t ep_num)
401 {
402     return(((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_TX_FIFO_NE_MASK)
403             ? 1u : 0u));
404 }
405 
406 /*-------------------------------------------------------------------------*//**
407  */
408 static __INLINE void
MSS_USB_CIF_cep_enable_irq(void)409 MSS_USB_CIF_cep_enable_irq
410 (
411     void
412 )
413 {
414     USB->TX_IRQ_ENABLE |= (uint16_t)(TX_IRQ_ENABLE_REG_CEP_MASK);
415 }
416 
417 /*-------------------------------------------------------------------------*//**
418  */
419 static __INLINE void
MSS_USB_CIF_cep_disable_irq(void)420 MSS_USB_CIF_cep_disable_irq
421 (
422     void
423 )
424 {
425     USB->TX_IRQ_ENABLE &= (uint16_t)(~TX_IRQ_ENABLE_REG_CEP_MASK);
426 }
427 
428 /*-------------------------------------------------------------------------*//**
429   INDEX register related APIs
430  */
431 static __INLINE void
MSS_USB_CIF_set_index_reg(uint8_t index)432 MSS_USB_CIF_set_index_reg
433 (
434     uint8_t index
435 )
436 {
437     USB->INDEX = index;
438 }
439 
MSS_USB_CIF_start_testse0nak(void)440 static __INLINE void MSS_USB_CIF_start_testse0nak(void)
441 {
442     USB->TEST_MODE = TESTMODE_SE0NAK_MASK;
443 }
444 
MSS_USB_CIF_start_testj(void)445 static __INLINE void MSS_USB_CIF_start_testj(void)
446 {
447     USB->TEST_MODE = TESTMODE_TESTJ_MASK;
448 }
449 
MSS_USB_CIF_start_testk(void)450 static __INLINE void MSS_USB_CIF_start_testk(void)
451 {
452     USB->TEST_MODE = TESTMODE_TESTK_MASK;
453 }
454 
MSS_USB_CIF_start_testpacket_bit(void)455 static __INLINE void MSS_USB_CIF_start_testpacket_bit(void)
456 {
457     USB->TEST_MODE = TESTMODE_TESTPACKET_MASK;
458 }
459 
MSS_USB_CIF_start_forcehost_ena(void)460 static __INLINE void MSS_USB_CIF_start_forcehost_ena(void)
461 {
462     USB->TEST_MODE = TESTMODE_FORCEHOST_MASK | TESTMODE_FORCEHS_MASK;
463 }
464 
MSS_USB_CIF_end_testmode(void)465 static __INLINE void MSS_USB_CIF_end_testmode(void)
466 {
467     USB->TEST_MODE = 0x00U;
468 }
469 
470 /*-------------------------------------------------------------------------*//**
471  */
472 void
473 MSS_USB_CIF_configure_ep_dma
474 (
475     mss_usb_dma_channel_t channel,
476     mss_usb_dma_dir_t dir,
477     mss_usb_dma_mode_t dma_mode,
478     mss_usb_dma_burst_mode_t burst_mode,
479     mss_usb_ep_num_t ep_num,
480     uint32_t buf_addr
481 );
482 
483 /*-------------------------------------------------------------------------*//**
484  */
485 void
486 MSS_USB_CIF_tx_ep_configure
487 (
488     mss_usb_ep_t* core_ep
489 );
490 
491 /*-------------------------------------------------------------------------*//**
492  */
493 void
494 MSS_USB_CIF_rx_ep_configure
495 (
496     mss_usb_ep_t* core_ep
497 );
498 
499 /*-------------------------------------------------------------------------*//**
500   Prepares the RX EP for receiving data as per parameters provided by upper
501   layer
502  */
503 void
504 MSS_USB_CIF_rx_ep_read_prepare
505 (
506     mss_usb_ep_num_t ep_num,
507     uint8_t* buf_addr,
508     uint8_t dma_enable,
509     mss_usb_dma_channel_t dma_channel,
510     mss_usb_xfr_type_t xfr_type,
511     uint32_t xfr_length
512 );
513 
514 /*-------------------------------------------------------------------------*//**
515  */
516 void
517 MSS_USB_CIF_ep_write_pkt
518 (
519     mss_usb_ep_num_t ep_num,
520     uint8_t* buf_addr,
521     uint8_t dma_enable,
522     mss_usb_dma_channel_t dma_channel,
523     mss_usb_xfr_type_t xfr_type,
524     uint32_t xfr_length,
525     uint32_t txn_length
526 );
527 
528 
529 /*-------------------------------------------------------------------------*//**
530   USB2.0 test mode functions
531 */
532 void
533 MSS_USB_CIF_start_testpacket
534 (
535     void
536 );
537 
538 #ifdef __cplusplus
539 }
540 #endif
541 
542 #endif /*__MSS_USB_COMMON_CIF_H_*/
543