xref: /openbmc/linux/drivers/usb/cdns3/cdnsp-gadget.c (revision 3d82904559f4f5a2622db1b21de3edf2eded7664)
1*3d829045SPawel Laszczak // SPDX-License-Identifier: GPL-2.0
2*3d829045SPawel Laszczak /*
3*3d829045SPawel Laszczak  * Cadence CDNSP DRD Driver.
4*3d829045SPawel Laszczak  *
5*3d829045SPawel Laszczak  * Copyright (C) 2020 Cadence.
6*3d829045SPawel Laszczak  *
7*3d829045SPawel Laszczak  * Author: Pawel Laszczak <pawell@cadence.com>
8*3d829045SPawel Laszczak  *
9*3d829045SPawel Laszczak  */
10*3d829045SPawel Laszczak 
11*3d829045SPawel Laszczak #include <linux/moduleparam.h>
12*3d829045SPawel Laszczak #include <linux/dma-mapping.h>
13*3d829045SPawel Laszczak #include <linux/module.h>
14*3d829045SPawel Laszczak #include <linux/iopoll.h>
15*3d829045SPawel Laszczak #include <linux/delay.h>
16*3d829045SPawel Laszczak #include <linux/log2.h>
17*3d829045SPawel Laszczak #include <linux/slab.h>
18*3d829045SPawel Laszczak #include <linux/pci.h>
19*3d829045SPawel Laszczak #include <linux/irq.h>
20*3d829045SPawel Laszczak #include <linux/dmi.h>
21*3d829045SPawel Laszczak 
22*3d829045SPawel Laszczak #include "core.h"
23*3d829045SPawel Laszczak #include "gadget-export.h"
24*3d829045SPawel Laszczak #include "drd.h"
25*3d829045SPawel Laszczak #include "cdnsp-gadget.h"
26*3d829045SPawel Laszczak 
27*3d829045SPawel Laszczak unsigned int cdnsp_port_speed(unsigned int port_status)
28*3d829045SPawel Laszczak {
29*3d829045SPawel Laszczak 	/*Detect gadget speed based on PORTSC register*/
30*3d829045SPawel Laszczak 	if (DEV_SUPERSPEEDPLUS(port_status))
31*3d829045SPawel Laszczak 		return USB_SPEED_SUPER_PLUS;
32*3d829045SPawel Laszczak 	else if (DEV_SUPERSPEED(port_status))
33*3d829045SPawel Laszczak 		return USB_SPEED_SUPER;
34*3d829045SPawel Laszczak 	else if (DEV_HIGHSPEED(port_status))
35*3d829045SPawel Laszczak 		return USB_SPEED_HIGH;
36*3d829045SPawel Laszczak 	else if (DEV_FULLSPEED(port_status))
37*3d829045SPawel Laszczak 		return USB_SPEED_FULL;
38*3d829045SPawel Laszczak 
39*3d829045SPawel Laszczak 	/* If device is detached then speed will be USB_SPEED_UNKNOWN.*/
40*3d829045SPawel Laszczak 	return USB_SPEED_UNKNOWN;
41*3d829045SPawel Laszczak }
42*3d829045SPawel Laszczak 
43*3d829045SPawel Laszczak /*
44*3d829045SPawel Laszczak  * Given a port state, this function returns a value that would result in the
45*3d829045SPawel Laszczak  * port being in the same state, if the value was written to the port status
46*3d829045SPawel Laszczak  * control register.
47*3d829045SPawel Laszczak  * Save Read Only (RO) bits and save read/write bits where
48*3d829045SPawel Laszczak  * writing a 0 clears the bit and writing a 1 sets the bit (RWS).
49*3d829045SPawel Laszczak  * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect.
50*3d829045SPawel Laszczak  */
51*3d829045SPawel Laszczak u32 cdnsp_port_state_to_neutral(u32 state)
52*3d829045SPawel Laszczak {
53*3d829045SPawel Laszczak 	/* Save read-only status and port state. */
54*3d829045SPawel Laszczak 	return (state & CDNSP_PORT_RO) | (state & CDNSP_PORT_RWS);
55*3d829045SPawel Laszczak }
56*3d829045SPawel Laszczak 
57*3d829045SPawel Laszczak /**
58*3d829045SPawel Laszczak  * Find the offset of the extended capabilities with capability ID id.
59*3d829045SPawel Laszczak  * @base: PCI MMIO registers base address.
60*3d829045SPawel Laszczak  * @start: Address at which to start looking, (0 or HCC_PARAMS to start at
61*3d829045SPawel Laszczak  *         beginning of list)
62*3d829045SPawel Laszczak  * @id: Extended capability ID to search for.
63*3d829045SPawel Laszczak  *
64*3d829045SPawel Laszczak  * Returns the offset of the next matching extended capability structure.
65*3d829045SPawel Laszczak  * Some capabilities can occur several times,
66*3d829045SPawel Laszczak  * e.g., the EXT_CAPS_PROTOCOL, and this provides a way to find them all.
67*3d829045SPawel Laszczak  */
68*3d829045SPawel Laszczak int cdnsp_find_next_ext_cap(void __iomem *base, u32 start, int id)
69*3d829045SPawel Laszczak {
70*3d829045SPawel Laszczak 	u32 offset = start;
71*3d829045SPawel Laszczak 	u32 next;
72*3d829045SPawel Laszczak 	u32 val;
73*3d829045SPawel Laszczak 
74*3d829045SPawel Laszczak 	if (!start || start == HCC_PARAMS_OFFSET) {
75*3d829045SPawel Laszczak 		val = readl(base + HCC_PARAMS_OFFSET);
76*3d829045SPawel Laszczak 		if (val == ~0)
77*3d829045SPawel Laszczak 			return 0;
78*3d829045SPawel Laszczak 
79*3d829045SPawel Laszczak 		offset = HCC_EXT_CAPS(val) << 2;
80*3d829045SPawel Laszczak 		if (!offset)
81*3d829045SPawel Laszczak 			return 0;
82*3d829045SPawel Laszczak 	};
83*3d829045SPawel Laszczak 
84*3d829045SPawel Laszczak 	do {
85*3d829045SPawel Laszczak 		val = readl(base + offset);
86*3d829045SPawel Laszczak 		if (val == ~0)
87*3d829045SPawel Laszczak 			return 0;
88*3d829045SPawel Laszczak 
89*3d829045SPawel Laszczak 		if (EXT_CAPS_ID(val) == id && offset != start)
90*3d829045SPawel Laszczak 			return offset;
91*3d829045SPawel Laszczak 
92*3d829045SPawel Laszczak 		next = EXT_CAPS_NEXT(val);
93*3d829045SPawel Laszczak 		offset += next << 2;
94*3d829045SPawel Laszczak 	} while (next);
95*3d829045SPawel Laszczak 
96*3d829045SPawel Laszczak 	return 0;
97*3d829045SPawel Laszczak }
98*3d829045SPawel Laszczak 
99*3d829045SPawel Laszczak void cdnsp_set_link_state(struct cdnsp_device *pdev,
100*3d829045SPawel Laszczak 			  __le32 __iomem *port_regs,
101*3d829045SPawel Laszczak 			  u32 link_state)
102*3d829045SPawel Laszczak {
103*3d829045SPawel Laszczak 	u32 temp;
104*3d829045SPawel Laszczak 
105*3d829045SPawel Laszczak 	temp = readl(port_regs);
106*3d829045SPawel Laszczak 	temp = cdnsp_port_state_to_neutral(temp);
107*3d829045SPawel Laszczak 	temp |= PORT_WKCONN_E | PORT_WKDISC_E;
108*3d829045SPawel Laszczak 	writel(temp, port_regs);
109*3d829045SPawel Laszczak 
110*3d829045SPawel Laszczak 	temp &= ~PORT_PLS_MASK;
111*3d829045SPawel Laszczak 	temp |= PORT_LINK_STROBE | link_state;
112*3d829045SPawel Laszczak 
113*3d829045SPawel Laszczak 	writel(temp, port_regs);
114*3d829045SPawel Laszczak }
115*3d829045SPawel Laszczak 
116*3d829045SPawel Laszczak static void cdnsp_disable_port(struct cdnsp_device *pdev,
117*3d829045SPawel Laszczak 			       __le32 __iomem *port_regs)
118*3d829045SPawel Laszczak {
119*3d829045SPawel Laszczak 	u32 temp = cdnsp_port_state_to_neutral(readl(port_regs));
120*3d829045SPawel Laszczak 
121*3d829045SPawel Laszczak 	writel(temp | PORT_PED, port_regs);
122*3d829045SPawel Laszczak }
123*3d829045SPawel Laszczak 
124*3d829045SPawel Laszczak static void cdnsp_clear_port_change_bit(struct cdnsp_device *pdev,
125*3d829045SPawel Laszczak 					__le32 __iomem *port_regs)
126*3d829045SPawel Laszczak {
127*3d829045SPawel Laszczak 	u32 portsc = readl(port_regs);
128*3d829045SPawel Laszczak 
129*3d829045SPawel Laszczak 	writel(cdnsp_port_state_to_neutral(portsc) |
130*3d829045SPawel Laszczak 	       (portsc & PORT_CHANGE_BITS), port_regs);
131*3d829045SPawel Laszczak }
132*3d829045SPawel Laszczak 
133*3d829045SPawel Laszczak static void cdnsp_set_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)
134*3d829045SPawel Laszczak {
135*3d829045SPawel Laszczak 	__le32 __iomem *reg;
136*3d829045SPawel Laszczak 	void __iomem *base;
137*3d829045SPawel Laszczak 	u32 offset = 0;
138*3d829045SPawel Laszczak 
139*3d829045SPawel Laszczak 	base = &pdev->cap_regs->hc_capbase;
140*3d829045SPawel Laszczak 	offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
141*3d829045SPawel Laszczak 	reg = base + offset + REG_CHICKEN_BITS_2_OFFSET;
142*3d829045SPawel Laszczak 
143*3d829045SPawel Laszczak 	bit = readl(reg) | bit;
144*3d829045SPawel Laszczak 	writel(bit, reg);
145*3d829045SPawel Laszczak }
146*3d829045SPawel Laszczak 
147*3d829045SPawel Laszczak static void cdnsp_clear_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)
148*3d829045SPawel Laszczak {
149*3d829045SPawel Laszczak 	__le32 __iomem *reg;
150*3d829045SPawel Laszczak 	void __iomem *base;
151*3d829045SPawel Laszczak 	u32 offset = 0;
152*3d829045SPawel Laszczak 
153*3d829045SPawel Laszczak 	base = &pdev->cap_regs->hc_capbase;
154*3d829045SPawel Laszczak 	offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
155*3d829045SPawel Laszczak 	reg = base + offset + REG_CHICKEN_BITS_2_OFFSET;
156*3d829045SPawel Laszczak 
157*3d829045SPawel Laszczak 	bit = readl(reg) & ~bit;
158*3d829045SPawel Laszczak 	writel(bit, reg);
159*3d829045SPawel Laszczak }
160*3d829045SPawel Laszczak 
161*3d829045SPawel Laszczak /*
162*3d829045SPawel Laszczak  * Disable interrupts and begin the controller halting process.
163*3d829045SPawel Laszczak  */
164*3d829045SPawel Laszczak static void cdnsp_quiesce(struct cdnsp_device *pdev)
165*3d829045SPawel Laszczak {
166*3d829045SPawel Laszczak 	u32 halted;
167*3d829045SPawel Laszczak 	u32 mask;
168*3d829045SPawel Laszczak 	u32 cmd;
169*3d829045SPawel Laszczak 
170*3d829045SPawel Laszczak 	mask = ~(u32)(CDNSP_IRQS);
171*3d829045SPawel Laszczak 
172*3d829045SPawel Laszczak 	halted = readl(&pdev->op_regs->status) & STS_HALT;
173*3d829045SPawel Laszczak 	if (!halted)
174*3d829045SPawel Laszczak 		mask &= ~(CMD_R_S | CMD_DEVEN);
175*3d829045SPawel Laszczak 
176*3d829045SPawel Laszczak 	cmd = readl(&pdev->op_regs->command);
177*3d829045SPawel Laszczak 	cmd &= mask;
178*3d829045SPawel Laszczak 	writel(cmd, &pdev->op_regs->command);
179*3d829045SPawel Laszczak }
180*3d829045SPawel Laszczak 
181*3d829045SPawel Laszczak /*
182*3d829045SPawel Laszczak  * Force controller into halt state.
183*3d829045SPawel Laszczak  *
184*3d829045SPawel Laszczak  * Disable any IRQs and clear the run/stop bit.
185*3d829045SPawel Laszczak  * Controller will complete any current and actively pipelined transactions, and
186*3d829045SPawel Laszczak  * should halt within 16 ms of the run/stop bit being cleared.
187*3d829045SPawel Laszczak  * Read controller Halted bit in the status register to see when the
188*3d829045SPawel Laszczak  * controller is finished.
189*3d829045SPawel Laszczak  */
190*3d829045SPawel Laszczak int cdnsp_halt(struct cdnsp_device *pdev)
191*3d829045SPawel Laszczak {
192*3d829045SPawel Laszczak 	int ret;
193*3d829045SPawel Laszczak 	u32 val;
194*3d829045SPawel Laszczak 
195*3d829045SPawel Laszczak 	cdnsp_quiesce(pdev);
196*3d829045SPawel Laszczak 
197*3d829045SPawel Laszczak 	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, val,
198*3d829045SPawel Laszczak 					val & STS_HALT, 1,
199*3d829045SPawel Laszczak 					CDNSP_MAX_HALT_USEC);
200*3d829045SPawel Laszczak 	if (ret) {
201*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERROR: Device halt failed\n");
202*3d829045SPawel Laszczak 		return ret;
203*3d829045SPawel Laszczak 	}
204*3d829045SPawel Laszczak 
205*3d829045SPawel Laszczak 	pdev->cdnsp_state |= CDNSP_STATE_HALTED;
206*3d829045SPawel Laszczak 
207*3d829045SPawel Laszczak 	return 0;
208*3d829045SPawel Laszczak }
209*3d829045SPawel Laszczak 
210*3d829045SPawel Laszczak /*
211*3d829045SPawel Laszczak  * device controller died, register read returns 0xffffffff, or command never
212*3d829045SPawel Laszczak  * ends.
213*3d829045SPawel Laszczak  */
214*3d829045SPawel Laszczak void cdnsp_died(struct cdnsp_device *pdev)
215*3d829045SPawel Laszczak {
216*3d829045SPawel Laszczak 	dev_err(pdev->dev, "ERROR: CDNSP controller not responding\n");
217*3d829045SPawel Laszczak 	pdev->cdnsp_state |= CDNSP_STATE_DYING;
218*3d829045SPawel Laszczak 	cdnsp_halt(pdev);
219*3d829045SPawel Laszczak }
220*3d829045SPawel Laszczak 
221*3d829045SPawel Laszczak /*
222*3d829045SPawel Laszczak  * Set the run bit and wait for the device to be running.
223*3d829045SPawel Laszczak  */
224*3d829045SPawel Laszczak static int cdnsp_start(struct cdnsp_device *pdev)
225*3d829045SPawel Laszczak {
226*3d829045SPawel Laszczak 	u32 temp;
227*3d829045SPawel Laszczak 	int ret;
228*3d829045SPawel Laszczak 
229*3d829045SPawel Laszczak 	temp = readl(&pdev->op_regs->command);
230*3d829045SPawel Laszczak 	temp |= (CMD_R_S | CMD_DEVEN);
231*3d829045SPawel Laszczak 	writel(temp, &pdev->op_regs->command);
232*3d829045SPawel Laszczak 
233*3d829045SPawel Laszczak 	pdev->cdnsp_state = 0;
234*3d829045SPawel Laszczak 
235*3d829045SPawel Laszczak 	/*
236*3d829045SPawel Laszczak 	 * Wait for the STS_HALT Status bit to be 0 to indicate the device is
237*3d829045SPawel Laszczak 	 * running.
238*3d829045SPawel Laszczak 	 */
239*3d829045SPawel Laszczak 	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, temp,
240*3d829045SPawel Laszczak 					!(temp & STS_HALT), 1,
241*3d829045SPawel Laszczak 					CDNSP_MAX_HALT_USEC);
242*3d829045SPawel Laszczak 	if (ret) {
243*3d829045SPawel Laszczak 		pdev->cdnsp_state = CDNSP_STATE_DYING;
244*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERROR: Controller run failed\n");
245*3d829045SPawel Laszczak 	}
246*3d829045SPawel Laszczak 
247*3d829045SPawel Laszczak 	return ret;
248*3d829045SPawel Laszczak }
249*3d829045SPawel Laszczak 
250*3d829045SPawel Laszczak /*
251*3d829045SPawel Laszczak  * Reset a halted controller.
252*3d829045SPawel Laszczak  *
253*3d829045SPawel Laszczak  * This resets pipelines, timers, counters, state machines, etc.
254*3d829045SPawel Laszczak  * Transactions will be terminated immediately, and operational registers
255*3d829045SPawel Laszczak  * will be set to their defaults.
256*3d829045SPawel Laszczak  */
257*3d829045SPawel Laszczak int cdnsp_reset(struct cdnsp_device *pdev)
258*3d829045SPawel Laszczak {
259*3d829045SPawel Laszczak 	u32 command;
260*3d829045SPawel Laszczak 	u32 temp;
261*3d829045SPawel Laszczak 	int ret;
262*3d829045SPawel Laszczak 
263*3d829045SPawel Laszczak 	temp = readl(&pdev->op_regs->status);
264*3d829045SPawel Laszczak 
265*3d829045SPawel Laszczak 	if (temp == ~(u32)0) {
266*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Device not accessible, reset failed.\n");
267*3d829045SPawel Laszczak 		return -ENODEV;
268*3d829045SPawel Laszczak 	}
269*3d829045SPawel Laszczak 
270*3d829045SPawel Laszczak 	if ((temp & STS_HALT) == 0) {
271*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Controller not halted, aborting reset.\n");
272*3d829045SPawel Laszczak 		return -EINVAL;
273*3d829045SPawel Laszczak 	}
274*3d829045SPawel Laszczak 
275*3d829045SPawel Laszczak 	command = readl(&pdev->op_regs->command);
276*3d829045SPawel Laszczak 	command |= CMD_RESET;
277*3d829045SPawel Laszczak 	writel(command, &pdev->op_regs->command);
278*3d829045SPawel Laszczak 
279*3d829045SPawel Laszczak 	ret = readl_poll_timeout_atomic(&pdev->op_regs->command, temp,
280*3d829045SPawel Laszczak 					!(temp & CMD_RESET), 1,
281*3d829045SPawel Laszczak 					10 * 1000);
282*3d829045SPawel Laszczak 	if (ret) {
283*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERROR: Controller reset failed\n");
284*3d829045SPawel Laszczak 		return ret;
285*3d829045SPawel Laszczak 	}
286*3d829045SPawel Laszczak 
287*3d829045SPawel Laszczak 	/*
288*3d829045SPawel Laszczak 	 * CDNSP cannot write any doorbells or operational registers other
289*3d829045SPawel Laszczak 	 * than status until the "Controller Not Ready" flag is cleared.
290*3d829045SPawel Laszczak 	 */
291*3d829045SPawel Laszczak 	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, temp,
292*3d829045SPawel Laszczak 					!(temp & STS_CNR), 1,
293*3d829045SPawel Laszczak 					10 * 1000);
294*3d829045SPawel Laszczak 
295*3d829045SPawel Laszczak 	if (ret) {
296*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERROR: Controller not ready to work\n");
297*3d829045SPawel Laszczak 		return ret;
298*3d829045SPawel Laszczak 	}
299*3d829045SPawel Laszczak 
300*3d829045SPawel Laszczak 	dev_dbg(pdev->dev, "Controller ready to work");
301*3d829045SPawel Laszczak 
302*3d829045SPawel Laszczak 	return ret;
303*3d829045SPawel Laszczak }
304*3d829045SPawel Laszczak 
305*3d829045SPawel Laszczak /*
306*3d829045SPawel Laszczak  * cdnsp_get_endpoint_index - Find the index for an endpoint given its
307*3d829045SPawel Laszczak  * descriptor.Use the return value to right shift 1 for the bitmask.
308*3d829045SPawel Laszczak  *
309*3d829045SPawel Laszczak  * Index = (epnum * 2) + direction - 1,
310*3d829045SPawel Laszczak  * where direction = 0 for OUT, 1 for IN.
311*3d829045SPawel Laszczak  * For control endpoints, the IN index is used (OUT index is unused), so
312*3d829045SPawel Laszczak  * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
313*3d829045SPawel Laszczak  */
314*3d829045SPawel Laszczak static unsigned int
315*3d829045SPawel Laszczak 	cdnsp_get_endpoint_index(const struct usb_endpoint_descriptor *desc)
316*3d829045SPawel Laszczak {
317*3d829045SPawel Laszczak 	unsigned int index = (unsigned int)usb_endpoint_num(desc);
318*3d829045SPawel Laszczak 
319*3d829045SPawel Laszczak 	if (usb_endpoint_xfer_control(desc))
320*3d829045SPawel Laszczak 		return index * 2;
321*3d829045SPawel Laszczak 
322*3d829045SPawel Laszczak 	return (index * 2) + (usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
323*3d829045SPawel Laszczak }
324*3d829045SPawel Laszczak 
325*3d829045SPawel Laszczak /*
326*3d829045SPawel Laszczak  * Find the flag for this endpoint (for use in the control context). Use the
327*3d829045SPawel Laszczak  * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
328*3d829045SPawel Laszczak  * bit 1, etc.
329*3d829045SPawel Laszczak  */
330*3d829045SPawel Laszczak static unsigned int
331*3d829045SPawel Laszczak 	cdnsp_get_endpoint_flag(const struct usb_endpoint_descriptor *desc)
332*3d829045SPawel Laszczak {
333*3d829045SPawel Laszczak 	return 1 << (cdnsp_get_endpoint_index(desc) + 1);
334*3d829045SPawel Laszczak }
335*3d829045SPawel Laszczak 
336*3d829045SPawel Laszczak int cdnsp_ep_enqueue(struct cdnsp_ep *pep, struct cdnsp_request *preq)
337*3d829045SPawel Laszczak {
338*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
339*3d829045SPawel Laszczak 	struct usb_request *request;
340*3d829045SPawel Laszczak 	int ret;
341*3d829045SPawel Laszczak 
342*3d829045SPawel Laszczak 	if (preq->epnum == 0 && !list_empty(&pep->pending_list))
343*3d829045SPawel Laszczak 		return -EBUSY;
344*3d829045SPawel Laszczak 
345*3d829045SPawel Laszczak 	request = &preq->request;
346*3d829045SPawel Laszczak 	request->actual = 0;
347*3d829045SPawel Laszczak 	request->status = -EINPROGRESS;
348*3d829045SPawel Laszczak 	preq->direction = pep->direction;
349*3d829045SPawel Laszczak 	preq->epnum = pep->number;
350*3d829045SPawel Laszczak 	preq->td.drbl = 0;
351*3d829045SPawel Laszczak 
352*3d829045SPawel Laszczak 	ret = usb_gadget_map_request_by_dev(pdev->dev, request, pep->direction);
353*3d829045SPawel Laszczak 	if (ret)
354*3d829045SPawel Laszczak 		return ret;
355*3d829045SPawel Laszczak 
356*3d829045SPawel Laszczak 	list_add_tail(&preq->list, &pep->pending_list);
357*3d829045SPawel Laszczak 
358*3d829045SPawel Laszczak 	switch (usb_endpoint_type(pep->endpoint.desc)) {
359*3d829045SPawel Laszczak 	case USB_ENDPOINT_XFER_CONTROL:
360*3d829045SPawel Laszczak 		ret = cdnsp_queue_ctrl_tx(pdev, preq);
361*3d829045SPawel Laszczak 		break;
362*3d829045SPawel Laszczak 	case USB_ENDPOINT_XFER_BULK:
363*3d829045SPawel Laszczak 	case USB_ENDPOINT_XFER_INT:
364*3d829045SPawel Laszczak 		ret = cdnsp_queue_bulk_tx(pdev, preq);
365*3d829045SPawel Laszczak 		break;
366*3d829045SPawel Laszczak 	case USB_ENDPOINT_XFER_ISOC:
367*3d829045SPawel Laszczak 		ret = cdnsp_queue_isoc_tx_prepare(pdev, preq);
368*3d829045SPawel Laszczak 	}
369*3d829045SPawel Laszczak 
370*3d829045SPawel Laszczak 	if (ret)
371*3d829045SPawel Laszczak 		goto unmap;
372*3d829045SPawel Laszczak 
373*3d829045SPawel Laszczak 	return 0;
374*3d829045SPawel Laszczak 
375*3d829045SPawel Laszczak unmap:
376*3d829045SPawel Laszczak 	usb_gadget_unmap_request_by_dev(pdev->dev, &preq->request,
377*3d829045SPawel Laszczak 					pep->direction);
378*3d829045SPawel Laszczak 	list_del(&preq->list);
379*3d829045SPawel Laszczak 
380*3d829045SPawel Laszczak 	return ret;
381*3d829045SPawel Laszczak }
382*3d829045SPawel Laszczak 
383*3d829045SPawel Laszczak /*
384*3d829045SPawel Laszczak  * Remove the request's TD from the endpoint ring. This may cause the
385*3d829045SPawel Laszczak  * controller to stop USB transfers, potentially stopping in the middle of a
386*3d829045SPawel Laszczak  * TRB buffer. The controller should pick up where it left off in the TD,
387*3d829045SPawel Laszczak  * unless a Set Transfer Ring Dequeue Pointer is issued.
388*3d829045SPawel Laszczak  *
389*3d829045SPawel Laszczak  * The TRBs that make up the buffers for the canceled request will be "removed"
390*3d829045SPawel Laszczak  * from the ring. Since the ring is a contiguous structure, they can't be
391*3d829045SPawel Laszczak  * physically removed. Instead, there are two options:
392*3d829045SPawel Laszczak  *
393*3d829045SPawel Laszczak  *  1) If the controller is in the middle of processing the request to be
394*3d829045SPawel Laszczak  *     canceled, we simply move the ring's dequeue pointer past those TRBs
395*3d829045SPawel Laszczak  *     using the Set Transfer Ring Dequeue Pointer command. This will be
396*3d829045SPawel Laszczak  *     the common case, when drivers timeout on the last submitted request
397*3d829045SPawel Laszczak  *     and attempt to cancel.
398*3d829045SPawel Laszczak  *
399*3d829045SPawel Laszczak  *  2) If the controller is in the middle of a different TD, we turn the TRBs
400*3d829045SPawel Laszczak  *     into a series of 1-TRB transfer no-op TDs. No-ops shouldn't be chained.
401*3d829045SPawel Laszczak  *     The controller will need to invalidate the any TRBs it has cached after
402*3d829045SPawel Laszczak  *     the stop endpoint command.
403*3d829045SPawel Laszczak  *
404*3d829045SPawel Laszczak  *  3) The TD may have completed by the time the Stop Endpoint Command
405*3d829045SPawel Laszczak  *     completes, so software needs to handle that case too.
406*3d829045SPawel Laszczak  *
407*3d829045SPawel Laszczak  */
408*3d829045SPawel Laszczak int cdnsp_ep_dequeue(struct cdnsp_ep *pep, struct cdnsp_request *preq)
409*3d829045SPawel Laszczak {
410*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
411*3d829045SPawel Laszczak 	int ret;
412*3d829045SPawel Laszczak 
413*3d829045SPawel Laszczak 	if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_RUNNING) {
414*3d829045SPawel Laszczak 		ret = cdnsp_cmd_stop_ep(pdev, pep);
415*3d829045SPawel Laszczak 		if (ret)
416*3d829045SPawel Laszczak 			return ret;
417*3d829045SPawel Laszczak 	}
418*3d829045SPawel Laszczak 
419*3d829045SPawel Laszczak 	return cdnsp_remove_request(pdev, preq, pep);
420*3d829045SPawel Laszczak }
421*3d829045SPawel Laszczak 
422*3d829045SPawel Laszczak static void cdnsp_zero_in_ctx(struct cdnsp_device *pdev)
423*3d829045SPawel Laszczak {
424*3d829045SPawel Laszczak 	struct cdnsp_input_control_ctx *ctrl_ctx;
425*3d829045SPawel Laszczak 	struct cdnsp_slot_ctx *slot_ctx;
426*3d829045SPawel Laszczak 	struct cdnsp_ep_ctx *ep_ctx;
427*3d829045SPawel Laszczak 	int i;
428*3d829045SPawel Laszczak 
429*3d829045SPawel Laszczak 	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
430*3d829045SPawel Laszczak 
431*3d829045SPawel Laszczak 	/*
432*3d829045SPawel Laszczak 	 * When a device's add flag and drop flag are zero, any subsequent
433*3d829045SPawel Laszczak 	 * configure endpoint command will leave that endpoint's state
434*3d829045SPawel Laszczak 	 * untouched. Make sure we don't leave any old state in the input
435*3d829045SPawel Laszczak 	 * endpoint contexts.
436*3d829045SPawel Laszczak 	 */
437*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags = 0;
438*3d829045SPawel Laszczak 	ctrl_ctx->add_flags = 0;
439*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
440*3d829045SPawel Laszczak 	slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
441*3d829045SPawel Laszczak 
442*3d829045SPawel Laszczak 	/* Endpoint 0 is always valid */
443*3d829045SPawel Laszczak 	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
444*3d829045SPawel Laszczak 	for (i = 1; i < CDNSP_ENDPOINTS_NUM; ++i) {
445*3d829045SPawel Laszczak 		ep_ctx = cdnsp_get_ep_ctx(&pdev->in_ctx, i);
446*3d829045SPawel Laszczak 		ep_ctx->ep_info = 0;
447*3d829045SPawel Laszczak 		ep_ctx->ep_info2 = 0;
448*3d829045SPawel Laszczak 		ep_ctx->deq = 0;
449*3d829045SPawel Laszczak 		ep_ctx->tx_info = 0;
450*3d829045SPawel Laszczak 	}
451*3d829045SPawel Laszczak }
452*3d829045SPawel Laszczak 
453*3d829045SPawel Laszczak /* Issue a configure endpoint command and wait for it to finish. */
454*3d829045SPawel Laszczak static int cdnsp_configure_endpoint(struct cdnsp_device *pdev)
455*3d829045SPawel Laszczak {
456*3d829045SPawel Laszczak 	int ret;
457*3d829045SPawel Laszczak 
458*3d829045SPawel Laszczak 	cdnsp_queue_configure_endpoint(pdev, pdev->cmd.in_ctx->dma);
459*3d829045SPawel Laszczak 	cdnsp_ring_cmd_db(pdev);
460*3d829045SPawel Laszczak 	ret = cdnsp_wait_for_cmd_compl(pdev);
461*3d829045SPawel Laszczak 	if (ret) {
462*3d829045SPawel Laszczak 		dev_err(pdev->dev,
463*3d829045SPawel Laszczak 			"ERR: unexpected command completion code 0x%x.\n", ret);
464*3d829045SPawel Laszczak 		return -EINVAL;
465*3d829045SPawel Laszczak 	}
466*3d829045SPawel Laszczak 
467*3d829045SPawel Laszczak 	return ret;
468*3d829045SPawel Laszczak }
469*3d829045SPawel Laszczak 
470*3d829045SPawel Laszczak static void cdnsp_invalidate_ep_events(struct cdnsp_device *pdev,
471*3d829045SPawel Laszczak 				       struct cdnsp_ep *pep)
472*3d829045SPawel Laszczak {
473*3d829045SPawel Laszczak 	struct cdnsp_segment *segment;
474*3d829045SPawel Laszczak 	union cdnsp_trb *event;
475*3d829045SPawel Laszczak 	u32 cycle_state;
476*3d829045SPawel Laszczak 	__le32  data;
477*3d829045SPawel Laszczak 
478*3d829045SPawel Laszczak 	event = pdev->event_ring->dequeue;
479*3d829045SPawel Laszczak 	segment = pdev->event_ring->deq_seg;
480*3d829045SPawel Laszczak 	cycle_state = pdev->event_ring->cycle_state;
481*3d829045SPawel Laszczak 
482*3d829045SPawel Laszczak 	while (1) {
483*3d829045SPawel Laszczak 		data = le32_to_cpu(event->trans_event.flags);
484*3d829045SPawel Laszczak 
485*3d829045SPawel Laszczak 		/* Check the owner of the TRB. */
486*3d829045SPawel Laszczak 		if ((data & TRB_CYCLE) != cycle_state)
487*3d829045SPawel Laszczak 			break;
488*3d829045SPawel Laszczak 
489*3d829045SPawel Laszczak 		if (TRB_FIELD_TO_TYPE(data) == TRB_TRANSFER &&
490*3d829045SPawel Laszczak 		    TRB_TO_EP_ID(data) == (pep->idx + 1)) {
491*3d829045SPawel Laszczak 			data |= TRB_EVENT_INVALIDATE;
492*3d829045SPawel Laszczak 			event->trans_event.flags = cpu_to_le32(data);
493*3d829045SPawel Laszczak 		}
494*3d829045SPawel Laszczak 
495*3d829045SPawel Laszczak 		if (cdnsp_last_trb_on_seg(segment, event)) {
496*3d829045SPawel Laszczak 			cycle_state ^= 1;
497*3d829045SPawel Laszczak 			segment = pdev->event_ring->deq_seg->next;
498*3d829045SPawel Laszczak 			event = segment->trbs;
499*3d829045SPawel Laszczak 		} else {
500*3d829045SPawel Laszczak 			event++;
501*3d829045SPawel Laszczak 		}
502*3d829045SPawel Laszczak 	}
503*3d829045SPawel Laszczak }
504*3d829045SPawel Laszczak 
505*3d829045SPawel Laszczak int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)
506*3d829045SPawel Laszczak {
507*3d829045SPawel Laszczak 	struct cdnsp_segment *event_deq_seg;
508*3d829045SPawel Laszczak 	union cdnsp_trb *cmd_trb;
509*3d829045SPawel Laszczak 	dma_addr_t cmd_deq_dma;
510*3d829045SPawel Laszczak 	union cdnsp_trb *event;
511*3d829045SPawel Laszczak 	u32 cycle_state;
512*3d829045SPawel Laszczak 	__le32  flags;
513*3d829045SPawel Laszczak 	int ret, val;
514*3d829045SPawel Laszczak 	u64 cmd_dma;
515*3d829045SPawel Laszczak 
516*3d829045SPawel Laszczak 	cmd_trb = pdev->cmd.command_trb;
517*3d829045SPawel Laszczak 	pdev->cmd.status = 0;
518*3d829045SPawel Laszczak 
519*3d829045SPawel Laszczak 	ret = readl_poll_timeout_atomic(&pdev->op_regs->cmd_ring, val,
520*3d829045SPawel Laszczak 					!CMD_RING_BUSY(val), 1,
521*3d829045SPawel Laszczak 					CDNSP_CMD_TIMEOUT);
522*3d829045SPawel Laszczak 	if (ret) {
523*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERR: Timeout while waiting for command\n");
524*3d829045SPawel Laszczak 		pdev->cdnsp_state = CDNSP_STATE_DYING;
525*3d829045SPawel Laszczak 		return -ETIMEDOUT;
526*3d829045SPawel Laszczak 	}
527*3d829045SPawel Laszczak 
528*3d829045SPawel Laszczak 	event = pdev->event_ring->dequeue;
529*3d829045SPawel Laszczak 	event_deq_seg = pdev->event_ring->deq_seg;
530*3d829045SPawel Laszczak 	cycle_state = pdev->event_ring->cycle_state;
531*3d829045SPawel Laszczak 
532*3d829045SPawel Laszczak 	cmd_deq_dma = cdnsp_trb_virt_to_dma(pdev->cmd_ring->deq_seg, cmd_trb);
533*3d829045SPawel Laszczak 	if (!cmd_deq_dma)
534*3d829045SPawel Laszczak 		return -EINVAL;
535*3d829045SPawel Laszczak 
536*3d829045SPawel Laszczak 	while (1) {
537*3d829045SPawel Laszczak 		flags = le32_to_cpu(event->event_cmd.flags);
538*3d829045SPawel Laszczak 
539*3d829045SPawel Laszczak 		/* Check the owner of the TRB. */
540*3d829045SPawel Laszczak 		if ((flags & TRB_CYCLE) != cycle_state)
541*3d829045SPawel Laszczak 			return -EINVAL;
542*3d829045SPawel Laszczak 
543*3d829045SPawel Laszczak 		cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb);
544*3d829045SPawel Laszczak 
545*3d829045SPawel Laszczak 		/*
546*3d829045SPawel Laszczak 		 * Check whether the completion event is for last queued
547*3d829045SPawel Laszczak 		 * command.
548*3d829045SPawel Laszczak 		 */
549*3d829045SPawel Laszczak 		if (TRB_FIELD_TO_TYPE(flags) != TRB_COMPLETION ||
550*3d829045SPawel Laszczak 		    cmd_dma != (u64)cmd_deq_dma) {
551*3d829045SPawel Laszczak 			if (!cdnsp_last_trb_on_seg(event_deq_seg, event)) {
552*3d829045SPawel Laszczak 				event++;
553*3d829045SPawel Laszczak 				continue;
554*3d829045SPawel Laszczak 			}
555*3d829045SPawel Laszczak 
556*3d829045SPawel Laszczak 			if (cdnsp_last_trb_on_ring(pdev->event_ring,
557*3d829045SPawel Laszczak 						   event_deq_seg, event))
558*3d829045SPawel Laszczak 				cycle_state ^= 1;
559*3d829045SPawel Laszczak 
560*3d829045SPawel Laszczak 			event_deq_seg = event_deq_seg->next;
561*3d829045SPawel Laszczak 			event = event_deq_seg->trbs;
562*3d829045SPawel Laszczak 			continue;
563*3d829045SPawel Laszczak 		}
564*3d829045SPawel Laszczak 
565*3d829045SPawel Laszczak 		pdev->cmd.status = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status));
566*3d829045SPawel Laszczak 		if (pdev->cmd.status == COMP_SUCCESS)
567*3d829045SPawel Laszczak 			return 0;
568*3d829045SPawel Laszczak 
569*3d829045SPawel Laszczak 		return -pdev->cmd.status;
570*3d829045SPawel Laszczak 	}
571*3d829045SPawel Laszczak }
572*3d829045SPawel Laszczak 
573*3d829045SPawel Laszczak int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
574*3d829045SPawel Laszczak 			struct cdnsp_ep *pep,
575*3d829045SPawel Laszczak 			int value)
576*3d829045SPawel Laszczak {
577*3d829045SPawel Laszczak 	int ret;
578*3d829045SPawel Laszczak 
579*3d829045SPawel Laszczak 	if (value) {
580*3d829045SPawel Laszczak 		ret = cdnsp_cmd_stop_ep(pdev, pep);
581*3d829045SPawel Laszczak 		if (ret)
582*3d829045SPawel Laszczak 			return ret;
583*3d829045SPawel Laszczak 
584*3d829045SPawel Laszczak 		if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
585*3d829045SPawel Laszczak 			cdnsp_queue_halt_endpoint(pdev, pep->idx);
586*3d829045SPawel Laszczak 			cdnsp_ring_cmd_db(pdev);
587*3d829045SPawel Laszczak 			ret = cdnsp_wait_for_cmd_compl(pdev);
588*3d829045SPawel Laszczak 		}
589*3d829045SPawel Laszczak 
590*3d829045SPawel Laszczak 		pep->ep_state |= EP_HALTED;
591*3d829045SPawel Laszczak 	} else {
592*3d829045SPawel Laszczak 		/*
593*3d829045SPawel Laszczak 		 * In device mode driver can call reset endpoint command
594*3d829045SPawel Laszczak 		 * from any endpoint state.
595*3d829045SPawel Laszczak 		 */
596*3d829045SPawel Laszczak 		cdnsp_queue_reset_ep(pdev, pep->idx);
597*3d829045SPawel Laszczak 		cdnsp_ring_cmd_db(pdev);
598*3d829045SPawel Laszczak 		ret = cdnsp_wait_for_cmd_compl(pdev);
599*3d829045SPawel Laszczak 		if (ret)
600*3d829045SPawel Laszczak 			return ret;
601*3d829045SPawel Laszczak 
602*3d829045SPawel Laszczak 		pep->ep_state &= ~EP_HALTED;
603*3d829045SPawel Laszczak 
604*3d829045SPawel Laszczak 		if (pep->idx != 0 && !(pep->ep_state & EP_WEDGE))
605*3d829045SPawel Laszczak 			cdnsp_ring_doorbell_for_active_rings(pdev, pep);
606*3d829045SPawel Laszczak 
607*3d829045SPawel Laszczak 		pep->ep_state &= ~EP_WEDGE;
608*3d829045SPawel Laszczak 	}
609*3d829045SPawel Laszczak 
610*3d829045SPawel Laszczak 	return 0;
611*3d829045SPawel Laszczak }
612*3d829045SPawel Laszczak 
613*3d829045SPawel Laszczak static int cdnsp_update_eps_configuration(struct cdnsp_device *pdev,
614*3d829045SPawel Laszczak 					  struct cdnsp_ep *pep)
615*3d829045SPawel Laszczak {
616*3d829045SPawel Laszczak 	struct cdnsp_input_control_ctx *ctrl_ctx;
617*3d829045SPawel Laszczak 	struct cdnsp_slot_ctx *slot_ctx;
618*3d829045SPawel Laszczak 	int ret = 0;
619*3d829045SPawel Laszczak 	u32 ep_sts;
620*3d829045SPawel Laszczak 	int i;
621*3d829045SPawel Laszczak 
622*3d829045SPawel Laszczak 	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
623*3d829045SPawel Laszczak 
624*3d829045SPawel Laszczak 	/* Don't issue the command if there's no endpoints to update. */
625*3d829045SPawel Laszczak 	if (ctrl_ctx->add_flags == 0 && ctrl_ctx->drop_flags == 0)
626*3d829045SPawel Laszczak 		return 0;
627*3d829045SPawel Laszczak 
628*3d829045SPawel Laszczak 	ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
629*3d829045SPawel Laszczak 	ctrl_ctx->add_flags &= cpu_to_le32(~EP0_FLAG);
630*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags &= cpu_to_le32(~(SLOT_FLAG | EP0_FLAG));
631*3d829045SPawel Laszczak 
632*3d829045SPawel Laszczak 	/* Fix up Context Entries field. Minimum value is EP0 == BIT(1). */
633*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
634*3d829045SPawel Laszczak 	for (i = CDNSP_ENDPOINTS_NUM; i >= 1; i--) {
635*3d829045SPawel Laszczak 		__le32 le32 = cpu_to_le32(BIT(i));
636*3d829045SPawel Laszczak 
637*3d829045SPawel Laszczak 		if ((pdev->eps[i - 1].ring && !(ctrl_ctx->drop_flags & le32)) ||
638*3d829045SPawel Laszczak 		    (ctrl_ctx->add_flags & le32) || i == 1) {
639*3d829045SPawel Laszczak 			slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
640*3d829045SPawel Laszczak 			slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(i));
641*3d829045SPawel Laszczak 			break;
642*3d829045SPawel Laszczak 		}
643*3d829045SPawel Laszczak 	}
644*3d829045SPawel Laszczak 
645*3d829045SPawel Laszczak 	ep_sts = GET_EP_CTX_STATE(pep->out_ctx);
646*3d829045SPawel Laszczak 
647*3d829045SPawel Laszczak 	if ((ctrl_ctx->add_flags != cpu_to_le32(SLOT_FLAG) &&
648*3d829045SPawel Laszczak 	     ep_sts == EP_STATE_DISABLED) ||
649*3d829045SPawel Laszczak 	    (ep_sts != EP_STATE_DISABLED && ctrl_ctx->drop_flags))
650*3d829045SPawel Laszczak 		ret = cdnsp_configure_endpoint(pdev);
651*3d829045SPawel Laszczak 
652*3d829045SPawel Laszczak 	cdnsp_zero_in_ctx(pdev);
653*3d829045SPawel Laszczak 
654*3d829045SPawel Laszczak 	return ret;
655*3d829045SPawel Laszczak }
656*3d829045SPawel Laszczak 
657*3d829045SPawel Laszczak /*
658*3d829045SPawel Laszczak  * This submits a Reset Device Command, which will set the device state to 0,
659*3d829045SPawel Laszczak  * set the device address to 0, and disable all the endpoints except the default
660*3d829045SPawel Laszczak  * control endpoint. The USB core should come back and call
661*3d829045SPawel Laszczak  * cdnsp_setup_device(), and then re-set up the configuration.
662*3d829045SPawel Laszczak  */
663*3d829045SPawel Laszczak int cdnsp_reset_device(struct cdnsp_device *pdev)
664*3d829045SPawel Laszczak {
665*3d829045SPawel Laszczak 	struct cdnsp_slot_ctx *slot_ctx;
666*3d829045SPawel Laszczak 	int slot_state;
667*3d829045SPawel Laszczak 	int ret, i;
668*3d829045SPawel Laszczak 
669*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
670*3d829045SPawel Laszczak 	slot_ctx->dev_info = 0;
671*3d829045SPawel Laszczak 	pdev->device_address = 0;
672*3d829045SPawel Laszczak 
673*3d829045SPawel Laszczak 	/* If device is not setup, there is no point in resetting it. */
674*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
675*3d829045SPawel Laszczak 	slot_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));
676*3d829045SPawel Laszczak 
677*3d829045SPawel Laszczak 	if (slot_state <= SLOT_STATE_DEFAULT &&
678*3d829045SPawel Laszczak 	    pdev->eps[0].ep_state & EP_HALTED) {
679*3d829045SPawel Laszczak 		cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0);
680*3d829045SPawel Laszczak 	}
681*3d829045SPawel Laszczak 
682*3d829045SPawel Laszczak 	/*
683*3d829045SPawel Laszczak 	 * During Reset Device command controller shall transition the
684*3d829045SPawel Laszczak 	 * endpoint ep0 to the Running State.
685*3d829045SPawel Laszczak 	 */
686*3d829045SPawel Laszczak 	pdev->eps[0].ep_state &= ~(EP_STOPPED | EP_HALTED);
687*3d829045SPawel Laszczak 	pdev->eps[0].ep_state |= EP_ENABLED;
688*3d829045SPawel Laszczak 
689*3d829045SPawel Laszczak 	if (slot_state <= SLOT_STATE_DEFAULT)
690*3d829045SPawel Laszczak 		return 0;
691*3d829045SPawel Laszczak 
692*3d829045SPawel Laszczak 	cdnsp_queue_reset_device(pdev);
693*3d829045SPawel Laszczak 	cdnsp_ring_cmd_db(pdev);
694*3d829045SPawel Laszczak 	ret = cdnsp_wait_for_cmd_compl(pdev);
695*3d829045SPawel Laszczak 
696*3d829045SPawel Laszczak 	/*
697*3d829045SPawel Laszczak 	 * After Reset Device command all not default endpoints
698*3d829045SPawel Laszczak 	 * are in Disabled state.
699*3d829045SPawel Laszczak 	 */
700*3d829045SPawel Laszczak 	for (i = 1; i < CDNSP_ENDPOINTS_NUM; ++i)
701*3d829045SPawel Laszczak 		pdev->eps[i].ep_state |= EP_STOPPED;
702*3d829045SPawel Laszczak 
703*3d829045SPawel Laszczak 	if (ret)
704*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Reset device failed with error code %d",
705*3d829045SPawel Laszczak 			ret);
706*3d829045SPawel Laszczak 
707*3d829045SPawel Laszczak 	return ret;
708*3d829045SPawel Laszczak }
709*3d829045SPawel Laszczak 
710*3d829045SPawel Laszczak /*
711*3d829045SPawel Laszczak  * Sets the MaxPStreams field and the Linear Stream Array field.
712*3d829045SPawel Laszczak  * Sets the dequeue pointer to the stream context array.
713*3d829045SPawel Laszczak  */
714*3d829045SPawel Laszczak static void cdnsp_setup_streams_ep_input_ctx(struct cdnsp_device *pdev,
715*3d829045SPawel Laszczak 					     struct cdnsp_ep_ctx *ep_ctx,
716*3d829045SPawel Laszczak 					     struct cdnsp_stream_info *stream_info)
717*3d829045SPawel Laszczak {
718*3d829045SPawel Laszczak 	u32 max_primary_streams;
719*3d829045SPawel Laszczak 
720*3d829045SPawel Laszczak 	/* MaxPStreams is the number of stream context array entries, not the
721*3d829045SPawel Laszczak 	 * number we're actually using. Must be in 2^(MaxPstreams + 1) format.
722*3d829045SPawel Laszczak 	 * fls(0) = 0, fls(0x1) = 1, fls(0x10) = 2, fls(0x100) = 3, etc.
723*3d829045SPawel Laszczak 	 */
724*3d829045SPawel Laszczak 	max_primary_streams = fls(stream_info->num_stream_ctxs) - 2;
725*3d829045SPawel Laszczak 	ep_ctx->ep_info &= cpu_to_le32(~EP_MAXPSTREAMS_MASK);
726*3d829045SPawel Laszczak 	ep_ctx->ep_info |= cpu_to_le32(EP_MAXPSTREAMS(max_primary_streams)
727*3d829045SPawel Laszczak 				       | EP_HAS_LSA);
728*3d829045SPawel Laszczak 	ep_ctx->deq  = cpu_to_le64(stream_info->ctx_array_dma);
729*3d829045SPawel Laszczak }
730*3d829045SPawel Laszczak 
731*3d829045SPawel Laszczak /*
732*3d829045SPawel Laszczak  * The drivers use this function to prepare a bulk endpoints to use streams.
733*3d829045SPawel Laszczak  *
734*3d829045SPawel Laszczak  * Don't allow the call to succeed if endpoint only supports one stream
735*3d829045SPawel Laszczak  * (which means it doesn't support streams at all).
736*3d829045SPawel Laszczak  */
737*3d829045SPawel Laszczak int cdnsp_alloc_streams(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
738*3d829045SPawel Laszczak {
739*3d829045SPawel Laszczak 	unsigned int num_streams = usb_ss_max_streams(pep->endpoint.comp_desc);
740*3d829045SPawel Laszczak 	unsigned int num_stream_ctxs;
741*3d829045SPawel Laszczak 	int ret;
742*3d829045SPawel Laszczak 
743*3d829045SPawel Laszczak 	if (num_streams ==  0)
744*3d829045SPawel Laszczak 		return 0;
745*3d829045SPawel Laszczak 
746*3d829045SPawel Laszczak 	if (num_streams > STREAM_NUM_STREAMS)
747*3d829045SPawel Laszczak 		return -EINVAL;
748*3d829045SPawel Laszczak 
749*3d829045SPawel Laszczak 	/*
750*3d829045SPawel Laszczak 	 * Add two to the number of streams requested to account for
751*3d829045SPawel Laszczak 	 * stream 0 that is reserved for controller usage and one additional
752*3d829045SPawel Laszczak 	 * for TASK SET FULL response.
753*3d829045SPawel Laszczak 	 */
754*3d829045SPawel Laszczak 	num_streams += 2;
755*3d829045SPawel Laszczak 
756*3d829045SPawel Laszczak 	/* The stream context array size must be a power of two */
757*3d829045SPawel Laszczak 	num_stream_ctxs = roundup_pow_of_two(num_streams);
758*3d829045SPawel Laszczak 
759*3d829045SPawel Laszczak 	ret = cdnsp_alloc_stream_info(pdev, pep, num_stream_ctxs, num_streams);
760*3d829045SPawel Laszczak 	if (ret)
761*3d829045SPawel Laszczak 		return ret;
762*3d829045SPawel Laszczak 
763*3d829045SPawel Laszczak 	cdnsp_setup_streams_ep_input_ctx(pdev, pep->in_ctx, &pep->stream_info);
764*3d829045SPawel Laszczak 
765*3d829045SPawel Laszczak 	pep->ep_state |= EP_HAS_STREAMS;
766*3d829045SPawel Laszczak 	pep->stream_info.td_count = 0;
767*3d829045SPawel Laszczak 	pep->stream_info.first_prime_det = 0;
768*3d829045SPawel Laszczak 
769*3d829045SPawel Laszczak 	/* Subtract 1 for stream 0, which drivers can't use. */
770*3d829045SPawel Laszczak 	return num_streams - 1;
771*3d829045SPawel Laszczak }
772*3d829045SPawel Laszczak 
773*3d829045SPawel Laszczak int cdnsp_disable_slot(struct cdnsp_device *pdev)
774*3d829045SPawel Laszczak {
775*3d829045SPawel Laszczak 	int ret;
776*3d829045SPawel Laszczak 
777*3d829045SPawel Laszczak 	cdnsp_queue_slot_control(pdev, TRB_DISABLE_SLOT);
778*3d829045SPawel Laszczak 	cdnsp_ring_cmd_db(pdev);
779*3d829045SPawel Laszczak 	ret = cdnsp_wait_for_cmd_compl(pdev);
780*3d829045SPawel Laszczak 
781*3d829045SPawel Laszczak 	pdev->slot_id = 0;
782*3d829045SPawel Laszczak 	pdev->active_port = NULL;
783*3d829045SPawel Laszczak 
784*3d829045SPawel Laszczak 	memset(pdev->in_ctx.bytes, 0, CDNSP_CTX_SIZE);
785*3d829045SPawel Laszczak 	memset(pdev->out_ctx.bytes, 0, CDNSP_CTX_SIZE);
786*3d829045SPawel Laszczak 
787*3d829045SPawel Laszczak 	return ret;
788*3d829045SPawel Laszczak }
789*3d829045SPawel Laszczak 
790*3d829045SPawel Laszczak int cdnsp_enable_slot(struct cdnsp_device *pdev)
791*3d829045SPawel Laszczak {
792*3d829045SPawel Laszczak 	struct cdnsp_slot_ctx *slot_ctx;
793*3d829045SPawel Laszczak 	int slot_state;
794*3d829045SPawel Laszczak 	int ret;
795*3d829045SPawel Laszczak 
796*3d829045SPawel Laszczak 	/* If device is not setup, there is no point in resetting it */
797*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
798*3d829045SPawel Laszczak 	slot_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));
799*3d829045SPawel Laszczak 
800*3d829045SPawel Laszczak 	if (slot_state != SLOT_STATE_DISABLED)
801*3d829045SPawel Laszczak 		return 0;
802*3d829045SPawel Laszczak 
803*3d829045SPawel Laszczak 	cdnsp_queue_slot_control(pdev, TRB_ENABLE_SLOT);
804*3d829045SPawel Laszczak 	cdnsp_ring_cmd_db(pdev);
805*3d829045SPawel Laszczak 	ret = cdnsp_wait_for_cmd_compl(pdev);
806*3d829045SPawel Laszczak 	if (ret)
807*3d829045SPawel Laszczak 		return ret;
808*3d829045SPawel Laszczak 
809*3d829045SPawel Laszczak 	pdev->slot_id = 1;
810*3d829045SPawel Laszczak 
811*3d829045SPawel Laszczak 	return 0;
812*3d829045SPawel Laszczak }
813*3d829045SPawel Laszczak 
814*3d829045SPawel Laszczak /*
815*3d829045SPawel Laszczak  * Issue an Address Device command with BSR=0 if setup is SETUP_CONTEXT_ONLY
816*3d829045SPawel Laszczak  * or with BSR = 1 if set_address is SETUP_CONTEXT_ADDRESS.
817*3d829045SPawel Laszczak  */
818*3d829045SPawel Laszczak int cdnsp_setup_device(struct cdnsp_device *pdev, enum cdnsp_setup_dev setup)
819*3d829045SPawel Laszczak {
820*3d829045SPawel Laszczak 	struct cdnsp_input_control_ctx *ctrl_ctx;
821*3d829045SPawel Laszczak 	struct cdnsp_slot_ctx *slot_ctx;
822*3d829045SPawel Laszczak 	int dev_state = 0;
823*3d829045SPawel Laszczak 	int ret;
824*3d829045SPawel Laszczak 
825*3d829045SPawel Laszczak 	if (!pdev->slot_id)
826*3d829045SPawel Laszczak 		return -EINVAL;
827*3d829045SPawel Laszczak 
828*3d829045SPawel Laszczak 	if (!pdev->active_port->port_num)
829*3d829045SPawel Laszczak 		return -EINVAL;
830*3d829045SPawel Laszczak 
831*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
832*3d829045SPawel Laszczak 	dev_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));
833*3d829045SPawel Laszczak 
834*3d829045SPawel Laszczak 	if (setup == SETUP_CONTEXT_ONLY && dev_state == SLOT_STATE_DEFAULT)
835*3d829045SPawel Laszczak 		return 0;
836*3d829045SPawel Laszczak 
837*3d829045SPawel Laszczak 	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
838*3d829045SPawel Laszczak 	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
839*3d829045SPawel Laszczak 
840*3d829045SPawel Laszczak 	if (!slot_ctx->dev_info || dev_state == SLOT_STATE_DEFAULT) {
841*3d829045SPawel Laszczak 		ret = cdnsp_setup_addressable_priv_dev(pdev);
842*3d829045SPawel Laszczak 		if (ret)
843*3d829045SPawel Laszczak 			return ret;
844*3d829045SPawel Laszczak 	}
845*3d829045SPawel Laszczak 
846*3d829045SPawel Laszczak 	cdnsp_copy_ep0_dequeue_into_input_ctx(pdev);
847*3d829045SPawel Laszczak 
848*3d829045SPawel Laszczak 	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
849*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags = 0;
850*3d829045SPawel Laszczak 
851*3d829045SPawel Laszczak 	cdnsp_queue_address_device(pdev, pdev->in_ctx.dma, setup);
852*3d829045SPawel Laszczak 	cdnsp_ring_cmd_db(pdev);
853*3d829045SPawel Laszczak 	ret = cdnsp_wait_for_cmd_compl(pdev);
854*3d829045SPawel Laszczak 
855*3d829045SPawel Laszczak 	/* Zero the input context control for later use. */
856*3d829045SPawel Laszczak 	ctrl_ctx->add_flags = 0;
857*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags = 0;
858*3d829045SPawel Laszczak 
859*3d829045SPawel Laszczak 	return ret;
860*3d829045SPawel Laszczak }
861*3d829045SPawel Laszczak 
862*3d829045SPawel Laszczak void cdnsp_set_usb2_hardware_lpm(struct cdnsp_device *pdev,
863*3d829045SPawel Laszczak 				 struct usb_request *req,
864*3d829045SPawel Laszczak 				 int enable)
865*3d829045SPawel Laszczak {
866*3d829045SPawel Laszczak 	if (pdev->active_port != &pdev->usb2_port || !pdev->gadget.lpm_capable)
867*3d829045SPawel Laszczak 		return;
868*3d829045SPawel Laszczak 
869*3d829045SPawel Laszczak 	if (enable)
870*3d829045SPawel Laszczak 		writel(PORT_BESL(CDNSP_DEFAULT_BESL) | PORT_L1S_NYET | PORT_HLE,
871*3d829045SPawel Laszczak 		       &pdev->active_port->regs->portpmsc);
872*3d829045SPawel Laszczak 	else
873*3d829045SPawel Laszczak 		writel(PORT_L1S_NYET, &pdev->active_port->regs->portpmsc);
874*3d829045SPawel Laszczak }
875*3d829045SPawel Laszczak 
876*3d829045SPawel Laszczak static int cdnsp_get_frame(struct cdnsp_device *pdev)
877*3d829045SPawel Laszczak {
878*3d829045SPawel Laszczak 	return readl(&pdev->run_regs->microframe_index) >> 3;
879*3d829045SPawel Laszczak }
880*3d829045SPawel Laszczak 
881*3d829045SPawel Laszczak static int cdnsp_gadget_ep_enable(struct usb_ep *ep,
882*3d829045SPawel Laszczak 				  const struct usb_endpoint_descriptor *desc)
883*3d829045SPawel Laszczak {
884*3d829045SPawel Laszczak 	struct cdnsp_input_control_ctx *ctrl_ctx;
885*3d829045SPawel Laszczak 	struct cdnsp_device *pdev;
886*3d829045SPawel Laszczak 	struct cdnsp_ep *pep;
887*3d829045SPawel Laszczak 	unsigned long flags;
888*3d829045SPawel Laszczak 	u32 added_ctxs;
889*3d829045SPawel Laszczak 	int ret;
890*3d829045SPawel Laszczak 
891*3d829045SPawel Laszczak 	if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT ||
892*3d829045SPawel Laszczak 	    !desc->wMaxPacketSize)
893*3d829045SPawel Laszczak 		return -EINVAL;
894*3d829045SPawel Laszczak 
895*3d829045SPawel Laszczak 	pep = to_cdnsp_ep(ep);
896*3d829045SPawel Laszczak 	pdev = pep->pdev;
897*3d829045SPawel Laszczak 
898*3d829045SPawel Laszczak 	if (dev_WARN_ONCE(pdev->dev, pep->ep_state & EP_ENABLED,
899*3d829045SPawel Laszczak 			  "%s is already enabled\n", pep->name))
900*3d829045SPawel Laszczak 		return 0;
901*3d829045SPawel Laszczak 
902*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
903*3d829045SPawel Laszczak 
904*3d829045SPawel Laszczak 	added_ctxs = cdnsp_get_endpoint_flag(desc);
905*3d829045SPawel Laszczak 	if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
906*3d829045SPawel Laszczak 		dev_err(pdev->dev, "ERROR: Bad endpoint number\n");
907*3d829045SPawel Laszczak 		ret = -EINVAL;
908*3d829045SPawel Laszczak 		goto unlock;
909*3d829045SPawel Laszczak 	}
910*3d829045SPawel Laszczak 
911*3d829045SPawel Laszczak 	pep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0;
912*3d829045SPawel Laszczak 
913*3d829045SPawel Laszczak 	if (pdev->gadget.speed == USB_SPEED_FULL) {
914*3d829045SPawel Laszczak 		if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT)
915*3d829045SPawel Laszczak 			pep->interval = desc->bInterval << 3;
916*3d829045SPawel Laszczak 		if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_ISOC)
917*3d829045SPawel Laszczak 			pep->interval = BIT(desc->bInterval - 1) << 3;
918*3d829045SPawel Laszczak 	}
919*3d829045SPawel Laszczak 
920*3d829045SPawel Laszczak 	if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_ISOC) {
921*3d829045SPawel Laszczak 		if (pep->interval > BIT(12)) {
922*3d829045SPawel Laszczak 			dev_err(pdev->dev, "bInterval %d not supported\n",
923*3d829045SPawel Laszczak 				desc->bInterval);
924*3d829045SPawel Laszczak 			ret = -EINVAL;
925*3d829045SPawel Laszczak 			goto unlock;
926*3d829045SPawel Laszczak 		}
927*3d829045SPawel Laszczak 		cdnsp_set_chicken_bits_2(pdev, CHICKEN_XDMA_2_TP_CACHE_DIS);
928*3d829045SPawel Laszczak 	}
929*3d829045SPawel Laszczak 
930*3d829045SPawel Laszczak 	ret = cdnsp_endpoint_init(pdev, pep, GFP_ATOMIC);
931*3d829045SPawel Laszczak 	if (ret)
932*3d829045SPawel Laszczak 		goto unlock;
933*3d829045SPawel Laszczak 
934*3d829045SPawel Laszczak 	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
935*3d829045SPawel Laszczak 	ctrl_ctx->add_flags = cpu_to_le32(added_ctxs);
936*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags = 0;
937*3d829045SPawel Laszczak 
938*3d829045SPawel Laszczak 	ret = cdnsp_update_eps_configuration(pdev, pep);
939*3d829045SPawel Laszczak 	if (ret) {
940*3d829045SPawel Laszczak 		cdnsp_free_endpoint_rings(pdev, pep);
941*3d829045SPawel Laszczak 		goto unlock;
942*3d829045SPawel Laszczak 	}
943*3d829045SPawel Laszczak 
944*3d829045SPawel Laszczak 	pep->ep_state |= EP_ENABLED;
945*3d829045SPawel Laszczak 	pep->ep_state &= ~EP_STOPPED;
946*3d829045SPawel Laszczak 
947*3d829045SPawel Laszczak unlock:
948*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
949*3d829045SPawel Laszczak 
950*3d829045SPawel Laszczak 	return ret;
951*3d829045SPawel Laszczak }
952*3d829045SPawel Laszczak 
953*3d829045SPawel Laszczak static int cdnsp_gadget_ep_disable(struct usb_ep *ep)
954*3d829045SPawel Laszczak {
955*3d829045SPawel Laszczak 	struct cdnsp_input_control_ctx *ctrl_ctx;
956*3d829045SPawel Laszczak 	struct cdnsp_request *preq;
957*3d829045SPawel Laszczak 	struct cdnsp_device *pdev;
958*3d829045SPawel Laszczak 	struct cdnsp_ep *pep;
959*3d829045SPawel Laszczak 	unsigned long flags;
960*3d829045SPawel Laszczak 	u32 drop_flag;
961*3d829045SPawel Laszczak 	int ret = 0;
962*3d829045SPawel Laszczak 
963*3d829045SPawel Laszczak 	if (!ep)
964*3d829045SPawel Laszczak 		return -EINVAL;
965*3d829045SPawel Laszczak 
966*3d829045SPawel Laszczak 	pep = to_cdnsp_ep(ep);
967*3d829045SPawel Laszczak 	pdev = pep->pdev;
968*3d829045SPawel Laszczak 
969*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
970*3d829045SPawel Laszczak 
971*3d829045SPawel Laszczak 	if (!(pep->ep_state & EP_ENABLED)) {
972*3d829045SPawel Laszczak 		dev_err(pdev->dev, "%s is already disabled\n", pep->name);
973*3d829045SPawel Laszczak 		ret = -EINVAL;
974*3d829045SPawel Laszczak 		goto finish;
975*3d829045SPawel Laszczak 	}
976*3d829045SPawel Laszczak 
977*3d829045SPawel Laszczak 	cdnsp_cmd_stop_ep(pdev, pep);
978*3d829045SPawel Laszczak 	pep->ep_state |= EP_DIS_IN_RROGRESS;
979*3d829045SPawel Laszczak 	cdnsp_cmd_flush_ep(pdev, pep);
980*3d829045SPawel Laszczak 
981*3d829045SPawel Laszczak 	/* Remove all queued USB requests. */
982*3d829045SPawel Laszczak 	while (!list_empty(&pep->pending_list)) {
983*3d829045SPawel Laszczak 		preq = next_request(&pep->pending_list);
984*3d829045SPawel Laszczak 		cdnsp_ep_dequeue(pep, preq);
985*3d829045SPawel Laszczak 	}
986*3d829045SPawel Laszczak 
987*3d829045SPawel Laszczak 	cdnsp_invalidate_ep_events(pdev, pep);
988*3d829045SPawel Laszczak 
989*3d829045SPawel Laszczak 	pep->ep_state &= ~EP_DIS_IN_RROGRESS;
990*3d829045SPawel Laszczak 	drop_flag = cdnsp_get_endpoint_flag(pep->endpoint.desc);
991*3d829045SPawel Laszczak 	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
992*3d829045SPawel Laszczak 	ctrl_ctx->drop_flags = cpu_to_le32(drop_flag);
993*3d829045SPawel Laszczak 	ctrl_ctx->add_flags = 0;
994*3d829045SPawel Laszczak 
995*3d829045SPawel Laszczak 	cdnsp_endpoint_zero(pdev, pep);
996*3d829045SPawel Laszczak 
997*3d829045SPawel Laszczak 	ret = cdnsp_update_eps_configuration(pdev, pep);
998*3d829045SPawel Laszczak 	cdnsp_free_endpoint_rings(pdev, pep);
999*3d829045SPawel Laszczak 
1000*3d829045SPawel Laszczak 	pep->ep_state &= ~EP_ENABLED;
1001*3d829045SPawel Laszczak 	pep->ep_state |= EP_STOPPED;
1002*3d829045SPawel Laszczak 
1003*3d829045SPawel Laszczak finish:
1004*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1005*3d829045SPawel Laszczak 
1006*3d829045SPawel Laszczak 	return ret;
1007*3d829045SPawel Laszczak }
1008*3d829045SPawel Laszczak 
1009*3d829045SPawel Laszczak static struct usb_request *cdnsp_gadget_ep_alloc_request(struct usb_ep *ep,
1010*3d829045SPawel Laszczak 							 gfp_t gfp_flags)
1011*3d829045SPawel Laszczak {
1012*3d829045SPawel Laszczak 	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
1013*3d829045SPawel Laszczak 	struct cdnsp_request *preq;
1014*3d829045SPawel Laszczak 
1015*3d829045SPawel Laszczak 	preq = kzalloc(sizeof(*preq), gfp_flags);
1016*3d829045SPawel Laszczak 	if (!preq)
1017*3d829045SPawel Laszczak 		return NULL;
1018*3d829045SPawel Laszczak 
1019*3d829045SPawel Laszczak 	preq->epnum = pep->number;
1020*3d829045SPawel Laszczak 	preq->pep = pep;
1021*3d829045SPawel Laszczak 
1022*3d829045SPawel Laszczak 	return &preq->request;
1023*3d829045SPawel Laszczak }
1024*3d829045SPawel Laszczak 
1025*3d829045SPawel Laszczak static void cdnsp_gadget_ep_free_request(struct usb_ep *ep,
1026*3d829045SPawel Laszczak 					 struct usb_request *request)
1027*3d829045SPawel Laszczak {
1028*3d829045SPawel Laszczak 	struct cdnsp_request *preq = to_cdnsp_request(request);
1029*3d829045SPawel Laszczak 
1030*3d829045SPawel Laszczak 	kfree(preq);
1031*3d829045SPawel Laszczak }
1032*3d829045SPawel Laszczak 
1033*3d829045SPawel Laszczak static int cdnsp_gadget_ep_queue(struct usb_ep *ep,
1034*3d829045SPawel Laszczak 				 struct usb_request *request,
1035*3d829045SPawel Laszczak 				 gfp_t gfp_flags)
1036*3d829045SPawel Laszczak {
1037*3d829045SPawel Laszczak 	struct cdnsp_request *preq;
1038*3d829045SPawel Laszczak 	struct cdnsp_device *pdev;
1039*3d829045SPawel Laszczak 	struct cdnsp_ep *pep;
1040*3d829045SPawel Laszczak 	unsigned long flags;
1041*3d829045SPawel Laszczak 	int ret;
1042*3d829045SPawel Laszczak 
1043*3d829045SPawel Laszczak 	if (!request || !ep)
1044*3d829045SPawel Laszczak 		return -EINVAL;
1045*3d829045SPawel Laszczak 
1046*3d829045SPawel Laszczak 	pep = to_cdnsp_ep(ep);
1047*3d829045SPawel Laszczak 	pdev = pep->pdev;
1048*3d829045SPawel Laszczak 
1049*3d829045SPawel Laszczak 	if (!(pep->ep_state & EP_ENABLED)) {
1050*3d829045SPawel Laszczak 		dev_err(pdev->dev, "%s: can't queue to disabled endpoint\n",
1051*3d829045SPawel Laszczak 			pep->name);
1052*3d829045SPawel Laszczak 		return -EINVAL;
1053*3d829045SPawel Laszczak 	}
1054*3d829045SPawel Laszczak 
1055*3d829045SPawel Laszczak 	preq = to_cdnsp_request(request);
1056*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1057*3d829045SPawel Laszczak 	ret = cdnsp_ep_enqueue(pep, preq);
1058*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1059*3d829045SPawel Laszczak 
1060*3d829045SPawel Laszczak 	return ret;
1061*3d829045SPawel Laszczak }
1062*3d829045SPawel Laszczak 
1063*3d829045SPawel Laszczak static int cdnsp_gadget_ep_dequeue(struct usb_ep *ep,
1064*3d829045SPawel Laszczak 				   struct usb_request *request)
1065*3d829045SPawel Laszczak {
1066*3d829045SPawel Laszczak 	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
1067*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
1068*3d829045SPawel Laszczak 	unsigned long flags;
1069*3d829045SPawel Laszczak 	int ret;
1070*3d829045SPawel Laszczak 
1071*3d829045SPawel Laszczak 	if (!pep->endpoint.desc) {
1072*3d829045SPawel Laszczak 		dev_err(pdev->dev,
1073*3d829045SPawel Laszczak 			"%s: can't dequeue to disabled endpoint\n",
1074*3d829045SPawel Laszczak 			pep->name);
1075*3d829045SPawel Laszczak 		return -ESHUTDOWN;
1076*3d829045SPawel Laszczak 	}
1077*3d829045SPawel Laszczak 
1078*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1079*3d829045SPawel Laszczak 	ret = cdnsp_ep_dequeue(pep, to_cdnsp_request(request));
1080*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1081*3d829045SPawel Laszczak 
1082*3d829045SPawel Laszczak 	return ret;
1083*3d829045SPawel Laszczak }
1084*3d829045SPawel Laszczak 
1085*3d829045SPawel Laszczak static int cdnsp_gadget_ep_set_halt(struct usb_ep *ep, int value)
1086*3d829045SPawel Laszczak {
1087*3d829045SPawel Laszczak 	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
1088*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
1089*3d829045SPawel Laszczak 	struct cdnsp_request *preq;
1090*3d829045SPawel Laszczak 	unsigned long flags = 0;
1091*3d829045SPawel Laszczak 	int ret;
1092*3d829045SPawel Laszczak 
1093*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1094*3d829045SPawel Laszczak 
1095*3d829045SPawel Laszczak 	preq = next_request(&pep->pending_list);
1096*3d829045SPawel Laszczak 	if (value) {
1097*3d829045SPawel Laszczak 		if (preq) {
1098*3d829045SPawel Laszczak 			ret = -EAGAIN;
1099*3d829045SPawel Laszczak 			goto done;
1100*3d829045SPawel Laszczak 		}
1101*3d829045SPawel Laszczak 	}
1102*3d829045SPawel Laszczak 
1103*3d829045SPawel Laszczak 	ret = cdnsp_halt_endpoint(pdev, pep, value);
1104*3d829045SPawel Laszczak 
1105*3d829045SPawel Laszczak done:
1106*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1107*3d829045SPawel Laszczak 	return ret;
1108*3d829045SPawel Laszczak }
1109*3d829045SPawel Laszczak 
1110*3d829045SPawel Laszczak static int cdnsp_gadget_ep_set_wedge(struct usb_ep *ep)
1111*3d829045SPawel Laszczak {
1112*3d829045SPawel Laszczak 	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
1113*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
1114*3d829045SPawel Laszczak 	unsigned long flags = 0;
1115*3d829045SPawel Laszczak 	int ret;
1116*3d829045SPawel Laszczak 
1117*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1118*3d829045SPawel Laszczak 	pep->ep_state |= EP_WEDGE;
1119*3d829045SPawel Laszczak 	ret = cdnsp_halt_endpoint(pdev, pep, 1);
1120*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1121*3d829045SPawel Laszczak 
1122*3d829045SPawel Laszczak 	return ret;
1123*3d829045SPawel Laszczak }
1124*3d829045SPawel Laszczak 
1125*3d829045SPawel Laszczak static const struct usb_ep_ops cdnsp_gadget_ep0_ops = {
1126*3d829045SPawel Laszczak 	.enable		= cdnsp_gadget_ep_enable,
1127*3d829045SPawel Laszczak 	.disable	= cdnsp_gadget_ep_disable,
1128*3d829045SPawel Laszczak 	.alloc_request	= cdnsp_gadget_ep_alloc_request,
1129*3d829045SPawel Laszczak 	.free_request	= cdnsp_gadget_ep_free_request,
1130*3d829045SPawel Laszczak 	.queue		= cdnsp_gadget_ep_queue,
1131*3d829045SPawel Laszczak 	.dequeue	= cdnsp_gadget_ep_dequeue,
1132*3d829045SPawel Laszczak 	.set_halt	= cdnsp_gadget_ep_set_halt,
1133*3d829045SPawel Laszczak 	.set_wedge	= cdnsp_gadget_ep_set_wedge,
1134*3d829045SPawel Laszczak };
1135*3d829045SPawel Laszczak 
1136*3d829045SPawel Laszczak static const struct usb_ep_ops cdnsp_gadget_ep_ops = {
1137*3d829045SPawel Laszczak 	.enable		= cdnsp_gadget_ep_enable,
1138*3d829045SPawel Laszczak 	.disable	= cdnsp_gadget_ep_disable,
1139*3d829045SPawel Laszczak 	.alloc_request	= cdnsp_gadget_ep_alloc_request,
1140*3d829045SPawel Laszczak 	.free_request	= cdnsp_gadget_ep_free_request,
1141*3d829045SPawel Laszczak 	.queue		= cdnsp_gadget_ep_queue,
1142*3d829045SPawel Laszczak 	.dequeue	= cdnsp_gadget_ep_dequeue,
1143*3d829045SPawel Laszczak 	.set_halt	= cdnsp_gadget_ep_set_halt,
1144*3d829045SPawel Laszczak 	.set_wedge	= cdnsp_gadget_ep_set_wedge,
1145*3d829045SPawel Laszczak };
1146*3d829045SPawel Laszczak 
1147*3d829045SPawel Laszczak void cdnsp_gadget_giveback(struct cdnsp_ep *pep,
1148*3d829045SPawel Laszczak 			   struct cdnsp_request *preq,
1149*3d829045SPawel Laszczak 			   int status)
1150*3d829045SPawel Laszczak {
1151*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = pep->pdev;
1152*3d829045SPawel Laszczak 
1153*3d829045SPawel Laszczak 	list_del(&preq->list);
1154*3d829045SPawel Laszczak 
1155*3d829045SPawel Laszczak 	if (preq->request.status == -EINPROGRESS)
1156*3d829045SPawel Laszczak 		preq->request.status = status;
1157*3d829045SPawel Laszczak 
1158*3d829045SPawel Laszczak 	usb_gadget_unmap_request_by_dev(pdev->dev, &preq->request,
1159*3d829045SPawel Laszczak 					preq->direction);
1160*3d829045SPawel Laszczak 
1161*3d829045SPawel Laszczak 	if (preq != &pdev->ep0_preq) {
1162*3d829045SPawel Laszczak 		spin_unlock(&pdev->lock);
1163*3d829045SPawel Laszczak 		usb_gadget_giveback_request(&pep->endpoint, &preq->request);
1164*3d829045SPawel Laszczak 		spin_lock(&pdev->lock);
1165*3d829045SPawel Laszczak 	}
1166*3d829045SPawel Laszczak }
1167*3d829045SPawel Laszczak 
1168*3d829045SPawel Laszczak static struct usb_endpoint_descriptor cdnsp_gadget_ep0_desc = {
1169*3d829045SPawel Laszczak 	.bLength =		USB_DT_ENDPOINT_SIZE,
1170*3d829045SPawel Laszczak 	.bDescriptorType =	USB_DT_ENDPOINT,
1171*3d829045SPawel Laszczak 	.bmAttributes =		USB_ENDPOINT_XFER_CONTROL,
1172*3d829045SPawel Laszczak };
1173*3d829045SPawel Laszczak 
1174*3d829045SPawel Laszczak static int cdnsp_run(struct cdnsp_device *pdev,
1175*3d829045SPawel Laszczak 		     enum usb_device_speed speed)
1176*3d829045SPawel Laszczak {
1177*3d829045SPawel Laszczak 	u32 fs_speed = 0;
1178*3d829045SPawel Laszczak 	u64 temp_64;
1179*3d829045SPawel Laszczak 	u32 temp;
1180*3d829045SPawel Laszczak 	int ret;
1181*3d829045SPawel Laszczak 
1182*3d829045SPawel Laszczak 	temp_64 = cdnsp_read_64(&pdev->ir_set->erst_dequeue);
1183*3d829045SPawel Laszczak 	temp_64 &= ~ERST_PTR_MASK;
1184*3d829045SPawel Laszczak 	temp = readl(&pdev->ir_set->irq_control);
1185*3d829045SPawel Laszczak 	temp &= ~IMOD_INTERVAL_MASK;
1186*3d829045SPawel Laszczak 	temp |= ((IMOD_DEFAULT_INTERVAL / 250) & IMOD_INTERVAL_MASK);
1187*3d829045SPawel Laszczak 	writel(temp, &pdev->ir_set->irq_control);
1188*3d829045SPawel Laszczak 
1189*3d829045SPawel Laszczak 	temp = readl(&pdev->port3x_regs->mode_addr);
1190*3d829045SPawel Laszczak 
1191*3d829045SPawel Laszczak 	switch (speed) {
1192*3d829045SPawel Laszczak 	case USB_SPEED_SUPER_PLUS:
1193*3d829045SPawel Laszczak 		temp |= CFG_3XPORT_SSP_SUPPORT;
1194*3d829045SPawel Laszczak 		break;
1195*3d829045SPawel Laszczak 	case USB_SPEED_SUPER:
1196*3d829045SPawel Laszczak 		temp &= ~CFG_3XPORT_SSP_SUPPORT;
1197*3d829045SPawel Laszczak 		break;
1198*3d829045SPawel Laszczak 	case USB_SPEED_HIGH:
1199*3d829045SPawel Laszczak 		break;
1200*3d829045SPawel Laszczak 	case USB_SPEED_FULL:
1201*3d829045SPawel Laszczak 		fs_speed = PORT_REG6_FORCE_FS;
1202*3d829045SPawel Laszczak 		break;
1203*3d829045SPawel Laszczak 	default:
1204*3d829045SPawel Laszczak 		dev_err(pdev->dev, "invalid maximum_speed parameter %d\n",
1205*3d829045SPawel Laszczak 			speed);
1206*3d829045SPawel Laszczak 		fallthrough;
1207*3d829045SPawel Laszczak 	case USB_SPEED_UNKNOWN:
1208*3d829045SPawel Laszczak 		/* Default to superspeed. */
1209*3d829045SPawel Laszczak 		speed = USB_SPEED_SUPER;
1210*3d829045SPawel Laszczak 		break;
1211*3d829045SPawel Laszczak 	}
1212*3d829045SPawel Laszczak 
1213*3d829045SPawel Laszczak 	if (speed >= USB_SPEED_SUPER) {
1214*3d829045SPawel Laszczak 		writel(temp, &pdev->port3x_regs->mode_addr);
1215*3d829045SPawel Laszczak 		cdnsp_set_link_state(pdev, &pdev->usb3_port.regs->portsc,
1216*3d829045SPawel Laszczak 				     XDEV_RXDETECT);
1217*3d829045SPawel Laszczak 	} else {
1218*3d829045SPawel Laszczak 		cdnsp_disable_port(pdev, &pdev->usb3_port.regs->portsc);
1219*3d829045SPawel Laszczak 	}
1220*3d829045SPawel Laszczak 
1221*3d829045SPawel Laszczak 	cdnsp_set_link_state(pdev, &pdev->usb2_port.regs->portsc,
1222*3d829045SPawel Laszczak 			     XDEV_RXDETECT);
1223*3d829045SPawel Laszczak 
1224*3d829045SPawel Laszczak 	cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
1225*3d829045SPawel Laszczak 
1226*3d829045SPawel Laszczak 	writel(PORT_REG6_L1_L0_HW_EN | fs_speed, &pdev->port20_regs->port_reg6);
1227*3d829045SPawel Laszczak 
1228*3d829045SPawel Laszczak 	ret = cdnsp_start(pdev);
1229*3d829045SPawel Laszczak 	if (ret) {
1230*3d829045SPawel Laszczak 		ret = -ENODEV;
1231*3d829045SPawel Laszczak 		goto err;
1232*3d829045SPawel Laszczak 	}
1233*3d829045SPawel Laszczak 
1234*3d829045SPawel Laszczak 	temp = readl(&pdev->op_regs->command);
1235*3d829045SPawel Laszczak 	temp |= (CMD_INTE);
1236*3d829045SPawel Laszczak 	writel(temp, &pdev->op_regs->command);
1237*3d829045SPawel Laszczak 
1238*3d829045SPawel Laszczak 	temp = readl(&pdev->ir_set->irq_pending);
1239*3d829045SPawel Laszczak 	writel(IMAN_IE_SET(temp), &pdev->ir_set->irq_pending);
1240*3d829045SPawel Laszczak 
1241*3d829045SPawel Laszczak 	return 0;
1242*3d829045SPawel Laszczak err:
1243*3d829045SPawel Laszczak 	cdnsp_halt(pdev);
1244*3d829045SPawel Laszczak 	return ret;
1245*3d829045SPawel Laszczak }
1246*3d829045SPawel Laszczak 
1247*3d829045SPawel Laszczak static int cdnsp_gadget_udc_start(struct usb_gadget *g,
1248*3d829045SPawel Laszczak 				  struct usb_gadget_driver *driver)
1249*3d829045SPawel Laszczak {
1250*3d829045SPawel Laszczak 	enum usb_device_speed max_speed = driver->max_speed;
1251*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
1252*3d829045SPawel Laszczak 	unsigned long flags;
1253*3d829045SPawel Laszczak 	int ret;
1254*3d829045SPawel Laszczak 
1255*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1256*3d829045SPawel Laszczak 	pdev->gadget_driver = driver;
1257*3d829045SPawel Laszczak 
1258*3d829045SPawel Laszczak 	/* limit speed if necessary */
1259*3d829045SPawel Laszczak 	max_speed = min(driver->max_speed, g->max_speed);
1260*3d829045SPawel Laszczak 	ret = cdnsp_run(pdev, max_speed);
1261*3d829045SPawel Laszczak 
1262*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1263*3d829045SPawel Laszczak 
1264*3d829045SPawel Laszczak 	return ret;
1265*3d829045SPawel Laszczak }
1266*3d829045SPawel Laszczak 
1267*3d829045SPawel Laszczak /*
1268*3d829045SPawel Laszczak  * Update Event Ring Dequeue Pointer:
1269*3d829045SPawel Laszczak  * - When all events have finished
1270*3d829045SPawel Laszczak  * - To avoid "Event Ring Full Error" condition
1271*3d829045SPawel Laszczak  */
1272*3d829045SPawel Laszczak void cdnsp_update_erst_dequeue(struct cdnsp_device *pdev,
1273*3d829045SPawel Laszczak 			       union cdnsp_trb *event_ring_deq,
1274*3d829045SPawel Laszczak 			       u8 clear_ehb)
1275*3d829045SPawel Laszczak {
1276*3d829045SPawel Laszczak 	u64 temp_64;
1277*3d829045SPawel Laszczak 	dma_addr_t deq;
1278*3d829045SPawel Laszczak 
1279*3d829045SPawel Laszczak 	temp_64 = cdnsp_read_64(&pdev->ir_set->erst_dequeue);
1280*3d829045SPawel Laszczak 
1281*3d829045SPawel Laszczak 	/* If necessary, update the HW's version of the event ring deq ptr. */
1282*3d829045SPawel Laszczak 	if (event_ring_deq != pdev->event_ring->dequeue) {
1283*3d829045SPawel Laszczak 		deq = cdnsp_trb_virt_to_dma(pdev->event_ring->deq_seg,
1284*3d829045SPawel Laszczak 					    pdev->event_ring->dequeue);
1285*3d829045SPawel Laszczak 		temp_64 &= ERST_PTR_MASK;
1286*3d829045SPawel Laszczak 		temp_64 |= ((u64)deq & (u64)~ERST_PTR_MASK);
1287*3d829045SPawel Laszczak 	}
1288*3d829045SPawel Laszczak 
1289*3d829045SPawel Laszczak 	/* Clear the event handler busy flag (RW1C). */
1290*3d829045SPawel Laszczak 	if (clear_ehb)
1291*3d829045SPawel Laszczak 		temp_64 |= ERST_EHB;
1292*3d829045SPawel Laszczak 	else
1293*3d829045SPawel Laszczak 		temp_64 &= ~ERST_EHB;
1294*3d829045SPawel Laszczak 
1295*3d829045SPawel Laszczak 	cdnsp_write_64(temp_64, &pdev->ir_set->erst_dequeue);
1296*3d829045SPawel Laszczak }
1297*3d829045SPawel Laszczak 
1298*3d829045SPawel Laszczak static void cdnsp_clear_cmd_ring(struct cdnsp_device *pdev)
1299*3d829045SPawel Laszczak {
1300*3d829045SPawel Laszczak 	struct cdnsp_segment *seg;
1301*3d829045SPawel Laszczak 	u64 val_64;
1302*3d829045SPawel Laszczak 	int i;
1303*3d829045SPawel Laszczak 
1304*3d829045SPawel Laszczak 	cdnsp_initialize_ring_info(pdev->cmd_ring);
1305*3d829045SPawel Laszczak 
1306*3d829045SPawel Laszczak 	seg = pdev->cmd_ring->first_seg;
1307*3d829045SPawel Laszczak 	for (i = 0; i < pdev->cmd_ring->num_segs; i++) {
1308*3d829045SPawel Laszczak 		memset(seg->trbs, 0,
1309*3d829045SPawel Laszczak 		       sizeof(union cdnsp_trb) * (TRBS_PER_SEGMENT - 1));
1310*3d829045SPawel Laszczak 		seg = seg->next;
1311*3d829045SPawel Laszczak 	}
1312*3d829045SPawel Laszczak 
1313*3d829045SPawel Laszczak 	/* Set the address in the Command Ring Control register. */
1314*3d829045SPawel Laszczak 	val_64 = cdnsp_read_64(&pdev->op_regs->cmd_ring);
1315*3d829045SPawel Laszczak 	val_64 = (val_64 & (u64)CMD_RING_RSVD_BITS) |
1316*3d829045SPawel Laszczak 		 (pdev->cmd_ring->first_seg->dma & (u64)~CMD_RING_RSVD_BITS) |
1317*3d829045SPawel Laszczak 		 pdev->cmd_ring->cycle_state;
1318*3d829045SPawel Laszczak 	cdnsp_write_64(val_64, &pdev->op_regs->cmd_ring);
1319*3d829045SPawel Laszczak }
1320*3d829045SPawel Laszczak 
1321*3d829045SPawel Laszczak static void cdnsp_consume_all_events(struct cdnsp_device *pdev)
1322*3d829045SPawel Laszczak {
1323*3d829045SPawel Laszczak 	struct cdnsp_segment *event_deq_seg;
1324*3d829045SPawel Laszczak 	union cdnsp_trb *event_ring_deq;
1325*3d829045SPawel Laszczak 	union cdnsp_trb *event;
1326*3d829045SPawel Laszczak 	u32 cycle_bit;
1327*3d829045SPawel Laszczak 
1328*3d829045SPawel Laszczak 	event_ring_deq = pdev->event_ring->dequeue;
1329*3d829045SPawel Laszczak 	event_deq_seg = pdev->event_ring->deq_seg;
1330*3d829045SPawel Laszczak 	event = pdev->event_ring->dequeue;
1331*3d829045SPawel Laszczak 
1332*3d829045SPawel Laszczak 	/* Update ring dequeue pointer. */
1333*3d829045SPawel Laszczak 	while (1) {
1334*3d829045SPawel Laszczak 		cycle_bit = (le32_to_cpu(event->event_cmd.flags) & TRB_CYCLE);
1335*3d829045SPawel Laszczak 
1336*3d829045SPawel Laszczak 		/* Does the controller or driver own the TRB? */
1337*3d829045SPawel Laszczak 		if (cycle_bit != pdev->event_ring->cycle_state)
1338*3d829045SPawel Laszczak 			break;
1339*3d829045SPawel Laszczak 
1340*3d829045SPawel Laszczak 		cdnsp_inc_deq(pdev, pdev->event_ring);
1341*3d829045SPawel Laszczak 
1342*3d829045SPawel Laszczak 		if (!cdnsp_last_trb_on_seg(event_deq_seg, event)) {
1343*3d829045SPawel Laszczak 			event++;
1344*3d829045SPawel Laszczak 			continue;
1345*3d829045SPawel Laszczak 		}
1346*3d829045SPawel Laszczak 
1347*3d829045SPawel Laszczak 		if (cdnsp_last_trb_on_ring(pdev->event_ring, event_deq_seg,
1348*3d829045SPawel Laszczak 					   event))
1349*3d829045SPawel Laszczak 			cycle_bit ^= 1;
1350*3d829045SPawel Laszczak 
1351*3d829045SPawel Laszczak 		event_deq_seg = event_deq_seg->next;
1352*3d829045SPawel Laszczak 		event = event_deq_seg->trbs;
1353*3d829045SPawel Laszczak 	}
1354*3d829045SPawel Laszczak 
1355*3d829045SPawel Laszczak 	cdnsp_update_erst_dequeue(pdev,  event_ring_deq, 1);
1356*3d829045SPawel Laszczak }
1357*3d829045SPawel Laszczak 
1358*3d829045SPawel Laszczak static void cdnsp_stop(struct cdnsp_device *pdev)
1359*3d829045SPawel Laszczak {
1360*3d829045SPawel Laszczak 	u32 temp;
1361*3d829045SPawel Laszczak 
1362*3d829045SPawel Laszczak 	cdnsp_cmd_flush_ep(pdev, &pdev->eps[0]);
1363*3d829045SPawel Laszczak 
1364*3d829045SPawel Laszczak 	/* Remove internally queued request for ep0. */
1365*3d829045SPawel Laszczak 	if (!list_empty(&pdev->eps[0].pending_list)) {
1366*3d829045SPawel Laszczak 		struct cdnsp_request *req;
1367*3d829045SPawel Laszczak 
1368*3d829045SPawel Laszczak 		req = next_request(&pdev->eps[0].pending_list);
1369*3d829045SPawel Laszczak 		if (req == &pdev->ep0_preq)
1370*3d829045SPawel Laszczak 			cdnsp_ep_dequeue(&pdev->eps[0], req);
1371*3d829045SPawel Laszczak 	}
1372*3d829045SPawel Laszczak 
1373*3d829045SPawel Laszczak 	cdnsp_disable_port(pdev, &pdev->usb2_port.regs->portsc);
1374*3d829045SPawel Laszczak 	cdnsp_disable_port(pdev, &pdev->usb3_port.regs->portsc);
1375*3d829045SPawel Laszczak 	cdnsp_disable_slot(pdev);
1376*3d829045SPawel Laszczak 	cdnsp_halt(pdev);
1377*3d829045SPawel Laszczak 
1378*3d829045SPawel Laszczak 	temp = readl(&pdev->op_regs->status);
1379*3d829045SPawel Laszczak 	writel((temp & ~0x1fff) | STS_EINT, &pdev->op_regs->status);
1380*3d829045SPawel Laszczak 	temp = readl(&pdev->ir_set->irq_pending);
1381*3d829045SPawel Laszczak 	writel(IMAN_IE_CLEAR(temp), &pdev->ir_set->irq_pending);
1382*3d829045SPawel Laszczak 
1383*3d829045SPawel Laszczak 	cdnsp_clear_port_change_bit(pdev, &pdev->usb2_port.regs->portsc);
1384*3d829045SPawel Laszczak 	cdnsp_clear_port_change_bit(pdev, &pdev->usb3_port.regs->portsc);
1385*3d829045SPawel Laszczak 
1386*3d829045SPawel Laszczak 	/* Clear interrupt line */
1387*3d829045SPawel Laszczak 	temp = readl(&pdev->ir_set->irq_pending);
1388*3d829045SPawel Laszczak 	temp |= IMAN_IP;
1389*3d829045SPawel Laszczak 	writel(temp, &pdev->ir_set->irq_pending);
1390*3d829045SPawel Laszczak 
1391*3d829045SPawel Laszczak 	cdnsp_consume_all_events(pdev);
1392*3d829045SPawel Laszczak 	cdnsp_clear_cmd_ring(pdev);
1393*3d829045SPawel Laszczak }
1394*3d829045SPawel Laszczak 
1395*3d829045SPawel Laszczak /*
1396*3d829045SPawel Laszczak  * Stop controller.
1397*3d829045SPawel Laszczak  * This function is called by the gadget core when the driver is removed.
1398*3d829045SPawel Laszczak  * Disable slot, disable IRQs, and quiesce the controller.
1399*3d829045SPawel Laszczak  */
1400*3d829045SPawel Laszczak static int cdnsp_gadget_udc_stop(struct usb_gadget *g)
1401*3d829045SPawel Laszczak {
1402*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
1403*3d829045SPawel Laszczak 	unsigned long flags;
1404*3d829045SPawel Laszczak 
1405*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1406*3d829045SPawel Laszczak 	cdnsp_stop(pdev);
1407*3d829045SPawel Laszczak 	pdev->gadget_driver = NULL;
1408*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1409*3d829045SPawel Laszczak 
1410*3d829045SPawel Laszczak 	return 0;
1411*3d829045SPawel Laszczak }
1412*3d829045SPawel Laszczak 
1413*3d829045SPawel Laszczak static int cdnsp_gadget_get_frame(struct usb_gadget *g)
1414*3d829045SPawel Laszczak {
1415*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
1416*3d829045SPawel Laszczak 
1417*3d829045SPawel Laszczak 	return cdnsp_get_frame(pdev);
1418*3d829045SPawel Laszczak }
1419*3d829045SPawel Laszczak 
1420*3d829045SPawel Laszczak static void __cdnsp_gadget_wakeup(struct cdnsp_device *pdev)
1421*3d829045SPawel Laszczak {
1422*3d829045SPawel Laszczak 	struct cdnsp_port_regs __iomem *port_regs;
1423*3d829045SPawel Laszczak 	u32 portpm, portsc;
1424*3d829045SPawel Laszczak 
1425*3d829045SPawel Laszczak 	port_regs = pdev->active_port->regs;
1426*3d829045SPawel Laszczak 	portsc = readl(&port_regs->portsc) & PORT_PLS_MASK;
1427*3d829045SPawel Laszczak 
1428*3d829045SPawel Laszczak 	/* Remote wakeup feature is not enabled by host. */
1429*3d829045SPawel Laszczak 	if (pdev->gadget.speed < USB_SPEED_SUPER && portsc == XDEV_U2) {
1430*3d829045SPawel Laszczak 		portpm = readl(&port_regs->portpmsc);
1431*3d829045SPawel Laszczak 
1432*3d829045SPawel Laszczak 		if (!(portpm & PORT_RWE))
1433*3d829045SPawel Laszczak 			return;
1434*3d829045SPawel Laszczak 	}
1435*3d829045SPawel Laszczak 
1436*3d829045SPawel Laszczak 	if (portsc == XDEV_U3 && !pdev->may_wakeup)
1437*3d829045SPawel Laszczak 		return;
1438*3d829045SPawel Laszczak 
1439*3d829045SPawel Laszczak 	cdnsp_set_link_state(pdev, &port_regs->portsc, XDEV_U0);
1440*3d829045SPawel Laszczak 
1441*3d829045SPawel Laszczak 	pdev->cdnsp_state |= CDNSP_WAKEUP_PENDING;
1442*3d829045SPawel Laszczak }
1443*3d829045SPawel Laszczak 
1444*3d829045SPawel Laszczak static int cdnsp_gadget_wakeup(struct usb_gadget *g)
1445*3d829045SPawel Laszczak {
1446*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
1447*3d829045SPawel Laszczak 	unsigned long flags;
1448*3d829045SPawel Laszczak 
1449*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1450*3d829045SPawel Laszczak 	__cdnsp_gadget_wakeup(pdev);
1451*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1452*3d829045SPawel Laszczak 
1453*3d829045SPawel Laszczak 	return 0;
1454*3d829045SPawel Laszczak }
1455*3d829045SPawel Laszczak 
1456*3d829045SPawel Laszczak static int cdnsp_gadget_set_selfpowered(struct usb_gadget *g,
1457*3d829045SPawel Laszczak 					int is_selfpowered)
1458*3d829045SPawel Laszczak {
1459*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
1460*3d829045SPawel Laszczak 	unsigned long flags;
1461*3d829045SPawel Laszczak 
1462*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1463*3d829045SPawel Laszczak 	g->is_selfpowered = !!is_selfpowered;
1464*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1465*3d829045SPawel Laszczak 
1466*3d829045SPawel Laszczak 	return 0;
1467*3d829045SPawel Laszczak }
1468*3d829045SPawel Laszczak 
1469*3d829045SPawel Laszczak static int cdnsp_gadget_pullup(struct usb_gadget *gadget, int is_on)
1470*3d829045SPawel Laszczak {
1471*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = gadget_to_cdnsp(gadget);
1472*3d829045SPawel Laszczak 	struct cdns *cdns = dev_get_drvdata(pdev->dev);
1473*3d829045SPawel Laszczak 
1474*3d829045SPawel Laszczak 	if (!is_on) {
1475*3d829045SPawel Laszczak 		cdnsp_reset_device(pdev);
1476*3d829045SPawel Laszczak 		cdns_clear_vbus(cdns);
1477*3d829045SPawel Laszczak 	} else {
1478*3d829045SPawel Laszczak 		cdns_set_vbus(cdns);
1479*3d829045SPawel Laszczak 	}
1480*3d829045SPawel Laszczak 	return 0;
1481*3d829045SPawel Laszczak }
1482*3d829045SPawel Laszczak 
1483*3d829045SPawel Laszczak const struct usb_gadget_ops cdnsp_gadget_ops = {
1484*3d829045SPawel Laszczak 	.get_frame		= cdnsp_gadget_get_frame,
1485*3d829045SPawel Laszczak 	.wakeup			= cdnsp_gadget_wakeup,
1486*3d829045SPawel Laszczak 	.set_selfpowered	= cdnsp_gadget_set_selfpowered,
1487*3d829045SPawel Laszczak 	.pullup			= cdnsp_gadget_pullup,
1488*3d829045SPawel Laszczak 	.udc_start		= cdnsp_gadget_udc_start,
1489*3d829045SPawel Laszczak 	.udc_stop		= cdnsp_gadget_udc_stop,
1490*3d829045SPawel Laszczak };
1491*3d829045SPawel Laszczak 
1492*3d829045SPawel Laszczak static void cdnsp_get_ep_buffering(struct cdnsp_device *pdev,
1493*3d829045SPawel Laszczak 				   struct cdnsp_ep *pep)
1494*3d829045SPawel Laszczak {
1495*3d829045SPawel Laszczak 	void __iomem *reg = &pdev->cap_regs->hc_capbase;
1496*3d829045SPawel Laszczak 	int endpoints;
1497*3d829045SPawel Laszczak 
1498*3d829045SPawel Laszczak 	reg += cdnsp_find_next_ext_cap(reg, 0, XBUF_CAP_ID);
1499*3d829045SPawel Laszczak 
1500*3d829045SPawel Laszczak 	if (!pep->direction) {
1501*3d829045SPawel Laszczak 		pep->buffering = readl(reg + XBUF_RX_TAG_MASK_0_OFFSET);
1502*3d829045SPawel Laszczak 		pep->buffering_period = readl(reg + XBUF_RX_TAG_MASK_1_OFFSET);
1503*3d829045SPawel Laszczak 		pep->buffering = (pep->buffering + 1) / 2;
1504*3d829045SPawel Laszczak 		pep->buffering_period = (pep->buffering_period + 1) / 2;
1505*3d829045SPawel Laszczak 		return;
1506*3d829045SPawel Laszczak 	}
1507*3d829045SPawel Laszczak 
1508*3d829045SPawel Laszczak 	endpoints = HCS_ENDPOINTS(readl(&pdev->hcs_params1)) / 2;
1509*3d829045SPawel Laszczak 
1510*3d829045SPawel Laszczak 	/* Set to XBUF_TX_TAG_MASK_0 register. */
1511*3d829045SPawel Laszczak 	reg += XBUF_TX_CMD_OFFSET + (endpoints * 2 + 2) * sizeof(u32);
1512*3d829045SPawel Laszczak 	/* Set reg to XBUF_TX_TAG_MASK_N related with this endpoint. */
1513*3d829045SPawel Laszczak 	reg += pep->number * sizeof(u32) * 2;
1514*3d829045SPawel Laszczak 
1515*3d829045SPawel Laszczak 	pep->buffering = (readl(reg) + 1) / 2;
1516*3d829045SPawel Laszczak 	pep->buffering_period = pep->buffering;
1517*3d829045SPawel Laszczak }
1518*3d829045SPawel Laszczak 
1519*3d829045SPawel Laszczak static int cdnsp_gadget_init_endpoints(struct cdnsp_device *pdev)
1520*3d829045SPawel Laszczak {
1521*3d829045SPawel Laszczak 	int max_streams = HCC_MAX_PSA(pdev->hcc_params);
1522*3d829045SPawel Laszczak 	struct cdnsp_ep *pep;
1523*3d829045SPawel Laszczak 	int i;
1524*3d829045SPawel Laszczak 
1525*3d829045SPawel Laszczak 	INIT_LIST_HEAD(&pdev->gadget.ep_list);
1526*3d829045SPawel Laszczak 
1527*3d829045SPawel Laszczak 	if (max_streams < STREAM_LOG_STREAMS) {
1528*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Stream size %d not supported\n",
1529*3d829045SPawel Laszczak 			max_streams);
1530*3d829045SPawel Laszczak 		return -EINVAL;
1531*3d829045SPawel Laszczak 	}
1532*3d829045SPawel Laszczak 
1533*3d829045SPawel Laszczak 	max_streams = STREAM_LOG_STREAMS;
1534*3d829045SPawel Laszczak 
1535*3d829045SPawel Laszczak 	for (i = 0; i < CDNSP_ENDPOINTS_NUM; i++) {
1536*3d829045SPawel Laszczak 		bool direction = !(i & 1); /* Start from OUT endpoint. */
1537*3d829045SPawel Laszczak 		u8 epnum = ((i + 1) >> 1);
1538*3d829045SPawel Laszczak 
1539*3d829045SPawel Laszczak 		if (!CDNSP_IF_EP_EXIST(pdev, epnum, direction))
1540*3d829045SPawel Laszczak 			continue;
1541*3d829045SPawel Laszczak 
1542*3d829045SPawel Laszczak 		pep = &pdev->eps[i];
1543*3d829045SPawel Laszczak 		pep->pdev = pdev;
1544*3d829045SPawel Laszczak 		pep->number = epnum;
1545*3d829045SPawel Laszczak 		pep->direction = direction; /* 0 for OUT, 1 for IN. */
1546*3d829045SPawel Laszczak 
1547*3d829045SPawel Laszczak 		/*
1548*3d829045SPawel Laszczak 		 * Ep0 is bidirectional, so ep0in and ep0out are represented by
1549*3d829045SPawel Laszczak 		 * pdev->eps[0]
1550*3d829045SPawel Laszczak 		 */
1551*3d829045SPawel Laszczak 		if (epnum == 0) {
1552*3d829045SPawel Laszczak 			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
1553*3d829045SPawel Laszczak 				 epnum, "BiDir");
1554*3d829045SPawel Laszczak 
1555*3d829045SPawel Laszczak 			pep->idx = 0;
1556*3d829045SPawel Laszczak 			usb_ep_set_maxpacket_limit(&pep->endpoint, 512);
1557*3d829045SPawel Laszczak 			pep->endpoint.maxburst = 1;
1558*3d829045SPawel Laszczak 			pep->endpoint.ops = &cdnsp_gadget_ep0_ops;
1559*3d829045SPawel Laszczak 			pep->endpoint.desc = &cdnsp_gadget_ep0_desc;
1560*3d829045SPawel Laszczak 			pep->endpoint.comp_desc = NULL;
1561*3d829045SPawel Laszczak 			pep->endpoint.caps.type_control = true;
1562*3d829045SPawel Laszczak 			pep->endpoint.caps.dir_in = true;
1563*3d829045SPawel Laszczak 			pep->endpoint.caps.dir_out = true;
1564*3d829045SPawel Laszczak 
1565*3d829045SPawel Laszczak 			pdev->ep0_preq.epnum = pep->number;
1566*3d829045SPawel Laszczak 			pdev->ep0_preq.pep = pep;
1567*3d829045SPawel Laszczak 			pdev->gadget.ep0 = &pep->endpoint;
1568*3d829045SPawel Laszczak 		} else {
1569*3d829045SPawel Laszczak 			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
1570*3d829045SPawel Laszczak 				 epnum, (pep->direction) ? "in" : "out");
1571*3d829045SPawel Laszczak 
1572*3d829045SPawel Laszczak 			pep->idx =  (epnum * 2 + (direction ? 1 : 0)) - 1;
1573*3d829045SPawel Laszczak 			usb_ep_set_maxpacket_limit(&pep->endpoint, 1024);
1574*3d829045SPawel Laszczak 
1575*3d829045SPawel Laszczak 			pep->endpoint.max_streams = max_streams;
1576*3d829045SPawel Laszczak 			pep->endpoint.ops = &cdnsp_gadget_ep_ops;
1577*3d829045SPawel Laszczak 			list_add_tail(&pep->endpoint.ep_list,
1578*3d829045SPawel Laszczak 				      &pdev->gadget.ep_list);
1579*3d829045SPawel Laszczak 
1580*3d829045SPawel Laszczak 			pep->endpoint.caps.type_iso = true;
1581*3d829045SPawel Laszczak 			pep->endpoint.caps.type_bulk = true;
1582*3d829045SPawel Laszczak 			pep->endpoint.caps.type_int = true;
1583*3d829045SPawel Laszczak 
1584*3d829045SPawel Laszczak 			pep->endpoint.caps.dir_in = direction;
1585*3d829045SPawel Laszczak 			pep->endpoint.caps.dir_out = !direction;
1586*3d829045SPawel Laszczak 		}
1587*3d829045SPawel Laszczak 
1588*3d829045SPawel Laszczak 		pep->endpoint.name = pep->name;
1589*3d829045SPawel Laszczak 		pep->in_ctx = cdnsp_get_ep_ctx(&pdev->in_ctx, pep->idx);
1590*3d829045SPawel Laszczak 		pep->out_ctx = cdnsp_get_ep_ctx(&pdev->out_ctx, pep->idx);
1591*3d829045SPawel Laszczak 		cdnsp_get_ep_buffering(pdev, pep);
1592*3d829045SPawel Laszczak 
1593*3d829045SPawel Laszczak 		dev_dbg(pdev->dev, "Init %s, MPS: %04x SupType: "
1594*3d829045SPawel Laszczak 			"CTRL: %s, INT: %s, BULK: %s, ISOC %s, "
1595*3d829045SPawel Laszczak 			"SupDir IN: %s, OUT: %s\n",
1596*3d829045SPawel Laszczak 			pep->name, 1024,
1597*3d829045SPawel Laszczak 			(pep->endpoint.caps.type_control) ? "yes" : "no",
1598*3d829045SPawel Laszczak 			(pep->endpoint.caps.type_int) ? "yes" : "no",
1599*3d829045SPawel Laszczak 			(pep->endpoint.caps.type_bulk) ? "yes" : "no",
1600*3d829045SPawel Laszczak 			(pep->endpoint.caps.type_iso) ? "yes" : "no",
1601*3d829045SPawel Laszczak 			(pep->endpoint.caps.dir_in) ? "yes" : "no",
1602*3d829045SPawel Laszczak 			(pep->endpoint.caps.dir_out) ? "yes" : "no");
1603*3d829045SPawel Laszczak 
1604*3d829045SPawel Laszczak 		INIT_LIST_HEAD(&pep->pending_list);
1605*3d829045SPawel Laszczak 	}
1606*3d829045SPawel Laszczak 
1607*3d829045SPawel Laszczak 	return 0;
1608*3d829045SPawel Laszczak }
1609*3d829045SPawel Laszczak 
1610*3d829045SPawel Laszczak static void cdnsp_gadget_free_endpoints(struct cdnsp_device *pdev)
1611*3d829045SPawel Laszczak {
1612*3d829045SPawel Laszczak 	struct cdnsp_ep *pep;
1613*3d829045SPawel Laszczak 	int i;
1614*3d829045SPawel Laszczak 
1615*3d829045SPawel Laszczak 	for (i = 0; i < CDNSP_ENDPOINTS_NUM; i++) {
1616*3d829045SPawel Laszczak 		pep = &pdev->eps[i];
1617*3d829045SPawel Laszczak 		if (pep->number != 0 && pep->out_ctx)
1618*3d829045SPawel Laszczak 			list_del(&pep->endpoint.ep_list);
1619*3d829045SPawel Laszczak 	}
1620*3d829045SPawel Laszczak }
1621*3d829045SPawel Laszczak 
1622*3d829045SPawel Laszczak void cdnsp_disconnect_gadget(struct cdnsp_device *pdev)
1623*3d829045SPawel Laszczak {
1624*3d829045SPawel Laszczak 	pdev->cdnsp_state |= CDNSP_STATE_DISCONNECT_PENDING;
1625*3d829045SPawel Laszczak 
1626*3d829045SPawel Laszczak 	if (pdev->gadget_driver && pdev->gadget_driver->disconnect) {
1627*3d829045SPawel Laszczak 		spin_unlock(&pdev->lock);
1628*3d829045SPawel Laszczak 		pdev->gadget_driver->disconnect(&pdev->gadget);
1629*3d829045SPawel Laszczak 		spin_lock(&pdev->lock);
1630*3d829045SPawel Laszczak 	}
1631*3d829045SPawel Laszczak 
1632*3d829045SPawel Laszczak 	pdev->gadget.speed = USB_SPEED_UNKNOWN;
1633*3d829045SPawel Laszczak 	usb_gadget_set_state(&pdev->gadget, USB_STATE_NOTATTACHED);
1634*3d829045SPawel Laszczak 
1635*3d829045SPawel Laszczak 	pdev->cdnsp_state &= ~CDNSP_STATE_DISCONNECT_PENDING;
1636*3d829045SPawel Laszczak }
1637*3d829045SPawel Laszczak 
1638*3d829045SPawel Laszczak void cdnsp_suspend_gadget(struct cdnsp_device *pdev)
1639*3d829045SPawel Laszczak {
1640*3d829045SPawel Laszczak 	if (pdev->gadget_driver && pdev->gadget_driver->suspend) {
1641*3d829045SPawel Laszczak 		spin_unlock(&pdev->lock);
1642*3d829045SPawel Laszczak 		pdev->gadget_driver->suspend(&pdev->gadget);
1643*3d829045SPawel Laszczak 		spin_lock(&pdev->lock);
1644*3d829045SPawel Laszczak 	}
1645*3d829045SPawel Laszczak }
1646*3d829045SPawel Laszczak 
1647*3d829045SPawel Laszczak void cdnsp_resume_gadget(struct cdnsp_device *pdev)
1648*3d829045SPawel Laszczak {
1649*3d829045SPawel Laszczak 	if (pdev->gadget_driver && pdev->gadget_driver->resume) {
1650*3d829045SPawel Laszczak 		spin_unlock(&pdev->lock);
1651*3d829045SPawel Laszczak 		pdev->gadget_driver->resume(&pdev->gadget);
1652*3d829045SPawel Laszczak 		spin_lock(&pdev->lock);
1653*3d829045SPawel Laszczak 	}
1654*3d829045SPawel Laszczak }
1655*3d829045SPawel Laszczak 
1656*3d829045SPawel Laszczak void cdnsp_irq_reset(struct cdnsp_device *pdev)
1657*3d829045SPawel Laszczak {
1658*3d829045SPawel Laszczak 	struct cdnsp_port_regs __iomem *port_regs;
1659*3d829045SPawel Laszczak 
1660*3d829045SPawel Laszczak 	cdnsp_reset_device(pdev);
1661*3d829045SPawel Laszczak 
1662*3d829045SPawel Laszczak 	port_regs = pdev->active_port->regs;
1663*3d829045SPawel Laszczak 	pdev->gadget.speed = cdnsp_port_speed(readl(port_regs));
1664*3d829045SPawel Laszczak 
1665*3d829045SPawel Laszczak 	spin_unlock(&pdev->lock);
1666*3d829045SPawel Laszczak 	usb_gadget_udc_reset(&pdev->gadget, pdev->gadget_driver);
1667*3d829045SPawel Laszczak 	spin_lock(&pdev->lock);
1668*3d829045SPawel Laszczak 
1669*3d829045SPawel Laszczak 	switch (pdev->gadget.speed) {
1670*3d829045SPawel Laszczak 	case USB_SPEED_SUPER_PLUS:
1671*3d829045SPawel Laszczak 	case USB_SPEED_SUPER:
1672*3d829045SPawel Laszczak 		cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
1673*3d829045SPawel Laszczak 		pdev->gadget.ep0->maxpacket = 512;
1674*3d829045SPawel Laszczak 		break;
1675*3d829045SPawel Laszczak 	case USB_SPEED_HIGH:
1676*3d829045SPawel Laszczak 	case USB_SPEED_FULL:
1677*3d829045SPawel Laszczak 		cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
1678*3d829045SPawel Laszczak 		pdev->gadget.ep0->maxpacket = 64;
1679*3d829045SPawel Laszczak 		break;
1680*3d829045SPawel Laszczak 	default:
1681*3d829045SPawel Laszczak 		/* Low speed is not supported. */
1682*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Unknown device speed\n");
1683*3d829045SPawel Laszczak 		break;
1684*3d829045SPawel Laszczak 	}
1685*3d829045SPawel Laszczak 
1686*3d829045SPawel Laszczak 	cdnsp_clear_chicken_bits_2(pdev, CHICKEN_XDMA_2_TP_CACHE_DIS);
1687*3d829045SPawel Laszczak 	cdnsp_setup_device(pdev, SETUP_CONTEXT_ONLY);
1688*3d829045SPawel Laszczak 	usb_gadget_set_state(&pdev->gadget, USB_STATE_DEFAULT);
1689*3d829045SPawel Laszczak }
1690*3d829045SPawel Laszczak 
1691*3d829045SPawel Laszczak static void cdnsp_get_rev_cap(struct cdnsp_device *pdev)
1692*3d829045SPawel Laszczak {
1693*3d829045SPawel Laszczak 	void __iomem *reg = &pdev->cap_regs->hc_capbase;
1694*3d829045SPawel Laszczak 	struct cdnsp_rev_cap *rev_cap;
1695*3d829045SPawel Laszczak 
1696*3d829045SPawel Laszczak 	reg += cdnsp_find_next_ext_cap(reg, 0, RTL_REV_CAP);
1697*3d829045SPawel Laszczak 	rev_cap = reg;
1698*3d829045SPawel Laszczak 
1699*3d829045SPawel Laszczak 	pdev->rev_cap.ctrl_revision = readl(&rev_cap->ctrl_revision);
1700*3d829045SPawel Laszczak 	pdev->rev_cap.rtl_revision = readl(&rev_cap->rtl_revision);
1701*3d829045SPawel Laszczak 	pdev->rev_cap.ep_supported = readl(&rev_cap->ep_supported);
1702*3d829045SPawel Laszczak 	pdev->rev_cap.ext_cap = readl(&rev_cap->ext_cap);
1703*3d829045SPawel Laszczak 	pdev->rev_cap.rx_buff_size = readl(&rev_cap->rx_buff_size);
1704*3d829045SPawel Laszczak 	pdev->rev_cap.tx_buff_size = readl(&rev_cap->tx_buff_size);
1705*3d829045SPawel Laszczak 
1706*3d829045SPawel Laszczak 	dev_info(pdev->dev, "Rev: %08x/%08x, eps: %08x, buff: %08x/%08x\n",
1707*3d829045SPawel Laszczak 		 pdev->rev_cap.ctrl_revision, pdev->rev_cap.rtl_revision,
1708*3d829045SPawel Laszczak 		 pdev->rev_cap.ep_supported, pdev->rev_cap.rx_buff_size,
1709*3d829045SPawel Laszczak 		 pdev->rev_cap.tx_buff_size);
1710*3d829045SPawel Laszczak }
1711*3d829045SPawel Laszczak 
1712*3d829045SPawel Laszczak static int cdnsp_gen_setup(struct cdnsp_device *pdev)
1713*3d829045SPawel Laszczak {
1714*3d829045SPawel Laszczak 	int ret;
1715*3d829045SPawel Laszczak 	u32 reg;
1716*3d829045SPawel Laszczak 
1717*3d829045SPawel Laszczak 	pdev->cap_regs = pdev->regs;
1718*3d829045SPawel Laszczak 	pdev->op_regs = pdev->regs +
1719*3d829045SPawel Laszczak 		HC_LENGTH(readl(&pdev->cap_regs->hc_capbase));
1720*3d829045SPawel Laszczak 	pdev->run_regs = pdev->regs +
1721*3d829045SPawel Laszczak 		(readl(&pdev->cap_regs->run_regs_off) & RTSOFF_MASK);
1722*3d829045SPawel Laszczak 
1723*3d829045SPawel Laszczak 	/* Cache read-only capability registers */
1724*3d829045SPawel Laszczak 	pdev->hcs_params1 = readl(&pdev->cap_regs->hcs_params1);
1725*3d829045SPawel Laszczak 	pdev->hcc_params = readl(&pdev->cap_regs->hc_capbase);
1726*3d829045SPawel Laszczak 	pdev->hci_version = HC_VERSION(pdev->hcc_params);
1727*3d829045SPawel Laszczak 	pdev->hcc_params = readl(&pdev->cap_regs->hcc_params);
1728*3d829045SPawel Laszczak 
1729*3d829045SPawel Laszczak 	cdnsp_get_rev_cap(pdev);
1730*3d829045SPawel Laszczak 
1731*3d829045SPawel Laszczak 	/* Make sure the Device Controller is halted. */
1732*3d829045SPawel Laszczak 	ret = cdnsp_halt(pdev);
1733*3d829045SPawel Laszczak 	if (ret)
1734*3d829045SPawel Laszczak 		return ret;
1735*3d829045SPawel Laszczak 
1736*3d829045SPawel Laszczak 	/* Reset the internal controller memory state and registers. */
1737*3d829045SPawel Laszczak 	ret = cdnsp_reset(pdev);
1738*3d829045SPawel Laszczak 	if (ret)
1739*3d829045SPawel Laszczak 		return ret;
1740*3d829045SPawel Laszczak 
1741*3d829045SPawel Laszczak 	/*
1742*3d829045SPawel Laszczak 	 * Set dma_mask and coherent_dma_mask to 64-bits,
1743*3d829045SPawel Laszczak 	 * if controller supports 64-bit addressing.
1744*3d829045SPawel Laszczak 	 */
1745*3d829045SPawel Laszczak 	if (HCC_64BIT_ADDR(pdev->hcc_params) &&
1746*3d829045SPawel Laszczak 	    !dma_set_mask(pdev->dev, DMA_BIT_MASK(64))) {
1747*3d829045SPawel Laszczak 		dev_dbg(pdev->dev, "Enabling 64-bit DMA addresses.\n");
1748*3d829045SPawel Laszczak 		dma_set_coherent_mask(pdev->dev, DMA_BIT_MASK(64));
1749*3d829045SPawel Laszczak 	} else {
1750*3d829045SPawel Laszczak 		/*
1751*3d829045SPawel Laszczak 		 * This is to avoid error in cases where a 32-bit USB
1752*3d829045SPawel Laszczak 		 * controller is used on a 64-bit capable system.
1753*3d829045SPawel Laszczak 		 */
1754*3d829045SPawel Laszczak 		ret = dma_set_mask(pdev->dev, DMA_BIT_MASK(32));
1755*3d829045SPawel Laszczak 		if (ret)
1756*3d829045SPawel Laszczak 			return ret;
1757*3d829045SPawel Laszczak 
1758*3d829045SPawel Laszczak 		dev_dbg(pdev->dev, "Enabling 32-bit DMA addresses.\n");
1759*3d829045SPawel Laszczak 		dma_set_coherent_mask(pdev->dev, DMA_BIT_MASK(32));
1760*3d829045SPawel Laszczak 	}
1761*3d829045SPawel Laszczak 
1762*3d829045SPawel Laszczak 	spin_lock_init(&pdev->lock);
1763*3d829045SPawel Laszczak 
1764*3d829045SPawel Laszczak 	ret = cdnsp_mem_init(pdev, GFP_KERNEL);
1765*3d829045SPawel Laszczak 	if (ret)
1766*3d829045SPawel Laszczak 		return ret;
1767*3d829045SPawel Laszczak 
1768*3d829045SPawel Laszczak 	/*
1769*3d829045SPawel Laszczak 	 * Software workaround for U1: after transition
1770*3d829045SPawel Laszczak 	 * to U1 the controller starts gating clock, and in some cases,
1771*3d829045SPawel Laszczak 	 * it causes that controller stack.
1772*3d829045SPawel Laszczak 	 */
1773*3d829045SPawel Laszczak 	reg = readl(&pdev->port3x_regs->mode_2);
1774*3d829045SPawel Laszczak 	reg &= ~CFG_3XPORT_U1_PIPE_CLK_GATE_EN;
1775*3d829045SPawel Laszczak 	writel(reg, &pdev->port3x_regs->mode_2);
1776*3d829045SPawel Laszczak 
1777*3d829045SPawel Laszczak 	return 0;
1778*3d829045SPawel Laszczak }
1779*3d829045SPawel Laszczak 
1780*3d829045SPawel Laszczak static int __cdnsp_gadget_init(struct cdns *cdns)
1781*3d829045SPawel Laszczak {
1782*3d829045SPawel Laszczak 	struct cdnsp_device *pdev;
1783*3d829045SPawel Laszczak 	u32 max_speed;
1784*3d829045SPawel Laszczak 	int ret = -ENOMEM;
1785*3d829045SPawel Laszczak 
1786*3d829045SPawel Laszczak 	cdns_drd_gadget_on(cdns);
1787*3d829045SPawel Laszczak 
1788*3d829045SPawel Laszczak 	pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
1789*3d829045SPawel Laszczak 	if (!pdev)
1790*3d829045SPawel Laszczak 		return -ENOMEM;
1791*3d829045SPawel Laszczak 
1792*3d829045SPawel Laszczak 	pm_runtime_get_sync(cdns->dev);
1793*3d829045SPawel Laszczak 
1794*3d829045SPawel Laszczak 	cdns->gadget_dev = pdev;
1795*3d829045SPawel Laszczak 	pdev->dev = cdns->dev;
1796*3d829045SPawel Laszczak 	pdev->regs = cdns->dev_regs;
1797*3d829045SPawel Laszczak 	max_speed = usb_get_maximum_speed(cdns->dev);
1798*3d829045SPawel Laszczak 
1799*3d829045SPawel Laszczak 	switch (max_speed) {
1800*3d829045SPawel Laszczak 	case USB_SPEED_FULL:
1801*3d829045SPawel Laszczak 	case USB_SPEED_HIGH:
1802*3d829045SPawel Laszczak 	case USB_SPEED_SUPER:
1803*3d829045SPawel Laszczak 	case USB_SPEED_SUPER_PLUS:
1804*3d829045SPawel Laszczak 		break;
1805*3d829045SPawel Laszczak 	default:
1806*3d829045SPawel Laszczak 		dev_err(cdns->dev, "invalid speed parameter %d\n", max_speed);
1807*3d829045SPawel Laszczak 		fallthrough;
1808*3d829045SPawel Laszczak 	case USB_SPEED_UNKNOWN:
1809*3d829045SPawel Laszczak 		/* Default to SSP */
1810*3d829045SPawel Laszczak 		max_speed = USB_SPEED_SUPER_PLUS;
1811*3d829045SPawel Laszczak 		break;
1812*3d829045SPawel Laszczak 	}
1813*3d829045SPawel Laszczak 
1814*3d829045SPawel Laszczak 	pdev->gadget.ops = &cdnsp_gadget_ops;
1815*3d829045SPawel Laszczak 	pdev->gadget.name = "cdnsp-gadget";
1816*3d829045SPawel Laszczak 	pdev->gadget.speed = USB_SPEED_UNKNOWN;
1817*3d829045SPawel Laszczak 	pdev->gadget.sg_supported = 1;
1818*3d829045SPawel Laszczak 	pdev->gadget.max_speed = USB_SPEED_SUPER_PLUS;
1819*3d829045SPawel Laszczak 	pdev->gadget.lpm_capable = 1;
1820*3d829045SPawel Laszczak 
1821*3d829045SPawel Laszczak 	pdev->setup_buf = kzalloc(CDNSP_EP0_SETUP_SIZE, GFP_KERNEL);
1822*3d829045SPawel Laszczak 	if (!pdev->setup_buf)
1823*3d829045SPawel Laszczak 		goto free_pdev;
1824*3d829045SPawel Laszczak 
1825*3d829045SPawel Laszczak 	/*
1826*3d829045SPawel Laszczak 	 * Controller supports not aligned buffer but it should improve
1827*3d829045SPawel Laszczak 	 * performance.
1828*3d829045SPawel Laszczak 	 */
1829*3d829045SPawel Laszczak 	pdev->gadget.quirk_ep_out_aligned_size = true;
1830*3d829045SPawel Laszczak 
1831*3d829045SPawel Laszczak 	ret = cdnsp_gen_setup(pdev);
1832*3d829045SPawel Laszczak 	if (ret) {
1833*3d829045SPawel Laszczak 		dev_err(pdev->dev, "Generic initialization failed %d\n", ret);
1834*3d829045SPawel Laszczak 		goto free_setup;
1835*3d829045SPawel Laszczak 	}
1836*3d829045SPawel Laszczak 
1837*3d829045SPawel Laszczak 	ret = cdnsp_gadget_init_endpoints(pdev);
1838*3d829045SPawel Laszczak 	if (ret) {
1839*3d829045SPawel Laszczak 		dev_err(pdev->dev, "failed to initialize endpoints\n");
1840*3d829045SPawel Laszczak 		goto halt_pdev;
1841*3d829045SPawel Laszczak 	}
1842*3d829045SPawel Laszczak 
1843*3d829045SPawel Laszczak 	ret = usb_add_gadget_udc(pdev->dev, &pdev->gadget);
1844*3d829045SPawel Laszczak 	if (ret) {
1845*3d829045SPawel Laszczak 		dev_err(pdev->dev, "failed to register udc\n");
1846*3d829045SPawel Laszczak 		goto free_endpoints;
1847*3d829045SPawel Laszczak 	}
1848*3d829045SPawel Laszczak 
1849*3d829045SPawel Laszczak 	ret = devm_request_threaded_irq(pdev->dev, cdns->dev_irq,
1850*3d829045SPawel Laszczak 					cdnsp_irq_handler,
1851*3d829045SPawel Laszczak 					cdnsp_thread_irq_handler, IRQF_SHARED,
1852*3d829045SPawel Laszczak 					dev_name(pdev->dev), pdev);
1853*3d829045SPawel Laszczak 	if (ret)
1854*3d829045SPawel Laszczak 		goto del_gadget;
1855*3d829045SPawel Laszczak 
1856*3d829045SPawel Laszczak 	return 0;
1857*3d829045SPawel Laszczak 
1858*3d829045SPawel Laszczak del_gadget:
1859*3d829045SPawel Laszczak 	usb_del_gadget_udc(&pdev->gadget);
1860*3d829045SPawel Laszczak free_endpoints:
1861*3d829045SPawel Laszczak 	cdnsp_gadget_free_endpoints(pdev);
1862*3d829045SPawel Laszczak halt_pdev:
1863*3d829045SPawel Laszczak 	cdnsp_halt(pdev);
1864*3d829045SPawel Laszczak 	cdnsp_reset(pdev);
1865*3d829045SPawel Laszczak 	cdnsp_mem_cleanup(pdev);
1866*3d829045SPawel Laszczak free_setup:
1867*3d829045SPawel Laszczak 	kfree(pdev->setup_buf);
1868*3d829045SPawel Laszczak free_pdev:
1869*3d829045SPawel Laszczak 	kfree(pdev);
1870*3d829045SPawel Laszczak 
1871*3d829045SPawel Laszczak 	return ret;
1872*3d829045SPawel Laszczak }
1873*3d829045SPawel Laszczak 
1874*3d829045SPawel Laszczak static void cdnsp_gadget_exit(struct cdns *cdns)
1875*3d829045SPawel Laszczak {
1876*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = cdns->gadget_dev;
1877*3d829045SPawel Laszczak 
1878*3d829045SPawel Laszczak 	devm_free_irq(pdev->dev, cdns->dev_irq, pdev);
1879*3d829045SPawel Laszczak 	pm_runtime_mark_last_busy(cdns->dev);
1880*3d829045SPawel Laszczak 	pm_runtime_put_autosuspend(cdns->dev);
1881*3d829045SPawel Laszczak 	usb_del_gadget_udc(&pdev->gadget);
1882*3d829045SPawel Laszczak 	cdnsp_gadget_free_endpoints(pdev);
1883*3d829045SPawel Laszczak 	cdnsp_mem_cleanup(pdev);
1884*3d829045SPawel Laszczak 	kfree(pdev);
1885*3d829045SPawel Laszczak 	cdns->gadget_dev = NULL;
1886*3d829045SPawel Laszczak 	cdns_drd_gadget_off(cdns);
1887*3d829045SPawel Laszczak }
1888*3d829045SPawel Laszczak 
1889*3d829045SPawel Laszczak static int cdnsp_gadget_suspend(struct cdns *cdns, bool do_wakeup)
1890*3d829045SPawel Laszczak {
1891*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = cdns->gadget_dev;
1892*3d829045SPawel Laszczak 	unsigned long flags;
1893*3d829045SPawel Laszczak 
1894*3d829045SPawel Laszczak 	if (pdev->link_state == XDEV_U3)
1895*3d829045SPawel Laszczak 		return 0;
1896*3d829045SPawel Laszczak 
1897*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1898*3d829045SPawel Laszczak 	cdnsp_disconnect_gadget(pdev);
1899*3d829045SPawel Laszczak 	cdnsp_stop(pdev);
1900*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1901*3d829045SPawel Laszczak 
1902*3d829045SPawel Laszczak 	return 0;
1903*3d829045SPawel Laszczak }
1904*3d829045SPawel Laszczak 
1905*3d829045SPawel Laszczak static int cdnsp_gadget_resume(struct cdns *cdns, bool hibernated)
1906*3d829045SPawel Laszczak {
1907*3d829045SPawel Laszczak 	struct cdnsp_device *pdev = cdns->gadget_dev;
1908*3d829045SPawel Laszczak 	enum usb_device_speed max_speed;
1909*3d829045SPawel Laszczak 	unsigned long flags;
1910*3d829045SPawel Laszczak 	int ret;
1911*3d829045SPawel Laszczak 
1912*3d829045SPawel Laszczak 	if (!pdev->gadget_driver)
1913*3d829045SPawel Laszczak 		return 0;
1914*3d829045SPawel Laszczak 
1915*3d829045SPawel Laszczak 	spin_lock_irqsave(&pdev->lock, flags);
1916*3d829045SPawel Laszczak 	max_speed = pdev->gadget_driver->max_speed;
1917*3d829045SPawel Laszczak 
1918*3d829045SPawel Laszczak 	/* Limit speed if necessary. */
1919*3d829045SPawel Laszczak 	max_speed = min(max_speed, pdev->gadget.max_speed);
1920*3d829045SPawel Laszczak 
1921*3d829045SPawel Laszczak 	ret = cdnsp_run(pdev, max_speed);
1922*3d829045SPawel Laszczak 
1923*3d829045SPawel Laszczak 	if (pdev->link_state == XDEV_U3)
1924*3d829045SPawel Laszczak 		__cdnsp_gadget_wakeup(pdev);
1925*3d829045SPawel Laszczak 
1926*3d829045SPawel Laszczak 	spin_unlock_irqrestore(&pdev->lock, flags);
1927*3d829045SPawel Laszczak 
1928*3d829045SPawel Laszczak 	return ret;
1929*3d829045SPawel Laszczak }
1930*3d829045SPawel Laszczak 
1931*3d829045SPawel Laszczak /**
1932*3d829045SPawel Laszczak  * cdnsp_gadget_init - initialize device structure
1933*3d829045SPawel Laszczak  * @cdns: cdnsp instance
1934*3d829045SPawel Laszczak  *
1935*3d829045SPawel Laszczak  * This function initializes the gadget.
1936*3d829045SPawel Laszczak  */
1937*3d829045SPawel Laszczak int cdnsp_gadget_init(struct cdns *cdns)
1938*3d829045SPawel Laszczak {
1939*3d829045SPawel Laszczak 	struct cdns_role_driver *rdrv;
1940*3d829045SPawel Laszczak 
1941*3d829045SPawel Laszczak 	rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
1942*3d829045SPawel Laszczak 	if (!rdrv)
1943*3d829045SPawel Laszczak 		return -ENOMEM;
1944*3d829045SPawel Laszczak 
1945*3d829045SPawel Laszczak 	rdrv->start	= __cdnsp_gadget_init;
1946*3d829045SPawel Laszczak 	rdrv->stop	= cdnsp_gadget_exit;
1947*3d829045SPawel Laszczak 	rdrv->suspend	= cdnsp_gadget_suspend;
1948*3d829045SPawel Laszczak 	rdrv->resume	= cdnsp_gadget_resume;
1949*3d829045SPawel Laszczak 	rdrv->state	= CDNS_ROLE_STATE_INACTIVE;
1950*3d829045SPawel Laszczak 	rdrv->name	= "gadget";
1951*3d829045SPawel Laszczak 	cdns->roles[USB_ROLE_DEVICE] = rdrv;
1952*3d829045SPawel Laszczak 
1953*3d829045SPawel Laszczak 	return 0;
1954*3d829045SPawel Laszczak }
1955