xref: /linux/drivers/usb/c67x00/c67x00-hcd.h (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
1ca9e742bSNishad Kamdar /* SPDX-License-Identifier: GPL-2.0+ */
2e9b29ffcSPeter Korsgaard /*
3e9b29ffcSPeter Korsgaard  * c67x00-hcd.h: Cypress C67X00 USB HCD
4e9b29ffcSPeter Korsgaard  *
5e9b29ffcSPeter Korsgaard  * Copyright (C) 2006-2008 Barco N.V.
6e9b29ffcSPeter Korsgaard  *    Derived from the Cypress cy7c67200/300 ezusb linux driver and
7e9b29ffcSPeter Korsgaard  *    based on multiple host controller drivers inside the linux kernel.
8e9b29ffcSPeter Korsgaard  */
9e9b29ffcSPeter Korsgaard 
10e9b29ffcSPeter Korsgaard #ifndef _USB_C67X00_HCD_H
11e9b29ffcSPeter Korsgaard #define _USB_C67X00_HCD_H
12e9b29ffcSPeter Korsgaard 
13e9b29ffcSPeter Korsgaard #include <linux/kernel.h>
14e9b29ffcSPeter Korsgaard #include <linux/spinlock.h>
15e9b29ffcSPeter Korsgaard #include <linux/list.h>
16e9b29ffcSPeter Korsgaard #include <linux/usb.h>
1727729aadSEric Lescouet #include <linux/usb/hcd.h>
18e9b29ffcSPeter Korsgaard #include "c67x00.h"
19e9b29ffcSPeter Korsgaard 
20e9b29ffcSPeter Korsgaard /*
21e9b29ffcSPeter Korsgaard  * The following parameters depend on the CPU speed, bus speed, ...
22e9b29ffcSPeter Korsgaard  * These can be tuned for specific use cases, e.g. if isochronous transfers
2325985edcSLucas De Marchi  * are very important, bandwidth can be sacrificed to guarantee that the
24e9b29ffcSPeter Korsgaard  * 1ms deadline will be met.
25e9b29ffcSPeter Korsgaard  * If bulk transfers are important, the MAX_FRAME_BW can be increased,
26e9b29ffcSPeter Korsgaard  * but some (or many) isochronous deadlines might not be met.
27e9b29ffcSPeter Korsgaard  *
28e9b29ffcSPeter Korsgaard  * The values are specified in bittime.
29e9b29ffcSPeter Korsgaard  */
30e9b29ffcSPeter Korsgaard 
31e9b29ffcSPeter Korsgaard /*
32e9b29ffcSPeter Korsgaard  * The current implementation switches between _STD (default) and _ISO (when
33e9b29ffcSPeter Korsgaard  * isochronous transfers are scheduled), in order to optimize the throughput
34f3c1f515SRahul Bedarkar  * in normal circumstances, but also provide good isochronous behaviour.
35e9b29ffcSPeter Korsgaard  *
36e9b29ffcSPeter Korsgaard  * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms
37e9b29ffcSPeter Korsgaard  * frames; there are 12000 bit times per frame.
38e9b29ffcSPeter Korsgaard  */
39e9b29ffcSPeter Korsgaard 
40e9b29ffcSPeter Korsgaard #define TOTAL_FRAME_BW		12000
41e9b29ffcSPeter Korsgaard #define DEFAULT_EOT		2250
42e9b29ffcSPeter Korsgaard 
43e9b29ffcSPeter Korsgaard #define MAX_FRAME_BW_STD	(TOTAL_FRAME_BW - DEFAULT_EOT)
44e9b29ffcSPeter Korsgaard #define MAX_FRAME_BW_ISO	2400
45e9b29ffcSPeter Korsgaard 
46e9b29ffcSPeter Korsgaard /*
47e9b29ffcSPeter Korsgaard  * Periodic transfers may only use 90% of the full frame, but as
48e9b29ffcSPeter Korsgaard  * we currently don't even use 90% of the full frame, we may
49e9b29ffcSPeter Korsgaard  * use the full usable time for periodic transfers.
50e9b29ffcSPeter Korsgaard  */
51e9b29ffcSPeter Korsgaard #define MAX_PERIODIC_BW(full_bw)	full_bw
52e9b29ffcSPeter Korsgaard 
53e9b29ffcSPeter Korsgaard /* -------------------------------------------------------------------------- */
54e9b29ffcSPeter Korsgaard 
55e9b29ffcSPeter Korsgaard struct c67x00_hcd {
56e9b29ffcSPeter Korsgaard 	spinlock_t lock;
57e9b29ffcSPeter Korsgaard 	struct c67x00_sie *sie;
58e9b29ffcSPeter Korsgaard 	unsigned int low_speed_ports;	/* bitmask of low speed ports */
59e9b29ffcSPeter Korsgaard 	unsigned int urb_count;
60e9b29ffcSPeter Korsgaard 	unsigned int urb_iso_count;
61e9b29ffcSPeter Korsgaard 
62e9b29ffcSPeter Korsgaard 	struct list_head list[4];	/* iso, int, ctrl, bulk */
63e9b29ffcSPeter Korsgaard #if PIPE_BULK != 3
64e9b29ffcSPeter Korsgaard #error "Sanity check failed, this code presumes PIPE_... to range from 0 to 3"
65e9b29ffcSPeter Korsgaard #endif
66e9b29ffcSPeter Korsgaard 
67e9b29ffcSPeter Korsgaard 	/* USB bandwidth allocated to td_list */
68e9b29ffcSPeter Korsgaard 	int bandwidth_allocated;
69e9b29ffcSPeter Korsgaard 	/* USB bandwidth allocated for isoc/int transfer */
70e9b29ffcSPeter Korsgaard 	int periodic_bw_allocated;
71e9b29ffcSPeter Korsgaard 	struct list_head td_list;
72e9b29ffcSPeter Korsgaard 	int max_frame_bw;
73e9b29ffcSPeter Korsgaard 
74e9b29ffcSPeter Korsgaard 	u16 td_base_addr;
75e9b29ffcSPeter Korsgaard 	u16 buf_base_addr;
76e9b29ffcSPeter Korsgaard 	u16 next_td_addr;
77e9b29ffcSPeter Korsgaard 	u16 next_buf_addr;
78e9b29ffcSPeter Korsgaard 
79*60b4c9d5SDavidlohr Bueso 	struct work_struct work;
80e9b29ffcSPeter Korsgaard 
81e9b29ffcSPeter Korsgaard 	struct completion endpoint_disable;
82e9b29ffcSPeter Korsgaard 
83e9b29ffcSPeter Korsgaard 	u16 current_frame;
84e9b29ffcSPeter Korsgaard 	u16 last_frame;
85e9b29ffcSPeter Korsgaard };
86e9b29ffcSPeter Korsgaard 
87e9b29ffcSPeter Korsgaard static inline struct c67x00_hcd *hcd_to_c67x00_hcd(struct usb_hcd *hcd)
88e9b29ffcSPeter Korsgaard {
89e9b29ffcSPeter Korsgaard 	return (struct c67x00_hcd *)(hcd->hcd_priv);
90e9b29ffcSPeter Korsgaard }
91e9b29ffcSPeter Korsgaard 
92e9b29ffcSPeter Korsgaard static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00)
93e9b29ffcSPeter Korsgaard {
94e9b29ffcSPeter Korsgaard 	return container_of((void *)c67x00, struct usb_hcd, hcd_priv);
95e9b29ffcSPeter Korsgaard }
96e9b29ffcSPeter Korsgaard 
97e9b29ffcSPeter Korsgaard /* ---------------------------------------------------------------------
98e9b29ffcSPeter Korsgaard  * Functions used by c67x00-drv
99e9b29ffcSPeter Korsgaard  */
100e9b29ffcSPeter Korsgaard 
101e9b29ffcSPeter Korsgaard int c67x00_hcd_probe(struct c67x00_sie *sie);
102e9b29ffcSPeter Korsgaard void c67x00_hcd_remove(struct c67x00_sie *sie);
103e9b29ffcSPeter Korsgaard 
104e9b29ffcSPeter Korsgaard /* ---------------------------------------------------------------------
105e9b29ffcSPeter Korsgaard  * Transfer Descriptor scheduling functions
106e9b29ffcSPeter Korsgaard  */
107e9b29ffcSPeter Korsgaard int c67x00_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
108e9b29ffcSPeter Korsgaard int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
109e9b29ffcSPeter Korsgaard void c67x00_endpoint_disable(struct usb_hcd *hcd,
110e9b29ffcSPeter Korsgaard 			     struct usb_host_endpoint *ep);
111e9b29ffcSPeter Korsgaard 
112e9b29ffcSPeter Korsgaard void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg);
113e9b29ffcSPeter Korsgaard void c67x00_sched_kick(struct c67x00_hcd *c67x00);
114e9b29ffcSPeter Korsgaard int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00);
115e9b29ffcSPeter Korsgaard void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00);
116e9b29ffcSPeter Korsgaard 
117e9b29ffcSPeter Korsgaard #define c67x00_hcd_dev(x)	(c67x00_hcd_to_hcd(x)->self.controller)
118e9b29ffcSPeter Korsgaard 
119e9b29ffcSPeter Korsgaard #endif				/* _USB_C67X00_HCD_H */
120