1 // SPDX-License-Identifier: GPL-2.0+
3 * bdc_cmd.c - BRCM BDC USB3.0 device controller
5 * Copyright (C) 2014 Broadcom Corporation
7 * Author: Ashwini Pahuja
9 #include <linux/scatterlist.h>
10 #include <linux/slab.h>
16 /* Issues a cmd to cmd processor and waits for cmd completion */
17 static int bdc_issue_cmd(struct bdc
*bdc
, u32 cmd_sc
, u32 param0
,
18 u32 param1
, u32 param2
)
20 u32 timeout
= BDC_CMD_TIMEOUT
;
24 bdc_writel(bdc
->regs
, BDC_CMDPAR0
, param0
);
25 bdc_writel(bdc
->regs
, BDC_CMDPAR1
, param1
);
26 bdc_writel(bdc
->regs
, BDC_CMDPAR2
, param2
);
29 /* Make sure the cmd params are written before asking HW to exec cmd */
31 bdc_writel(bdc
->regs
, BDC_CMDSC
, cmd_sc
| BDC_CMD_CWS
| BDC_CMD_SRD
);
33 temp
= bdc_readl(bdc
->regs
, BDC_CMDSC
);
34 dev_dbg_ratelimited(bdc
->dev
, "cmdsc=%x", temp
);
35 cmd_status
= BDC_CMD_CST(temp
);
36 if (cmd_status
!= BDC_CMDS_BUSY
) {
38 "command completed cmd_sts:%x\n", cmd_status
);
45 "command operation timedout cmd_status=%d\n", cmd_status
);
50 /* Submits cmd and analyze the return value of bdc_issue_cmd */
51 static int bdc_submit_cmd(struct bdc
*bdc
, u32 cmd_sc
,
52 u32 param0
, u32 param1
, u32 param2
)
57 temp
= bdc_readl(bdc
->regs
, BDC_CMDSC
);
59 "%s:CMDSC:%08x cmdsc:%08x param0=%08x param1=%08x param2=%08x\n",
60 __func__
, temp
, cmd_sc
, param0
, param1
, param2
);
62 cmd_status
= BDC_CMD_CST(temp
);
63 if (cmd_status
== BDC_CMDS_BUSY
) {
64 dev_err(bdc
->dev
, "command processor busy: %x\n", cmd_status
);
67 ret
= bdc_issue_cmd(bdc
, cmd_sc
, param0
, param1
, param2
);
70 dev_dbg(bdc
->dev
, "command completed successfully\n");
75 dev_err(bdc
->dev
, "command parameter error\n");
80 dev_err(bdc
->dev
, "Invalid device/ep state\n");
85 dev_err(bdc
->dev
, "Command failed?\n");
90 dev_err(bdc
->dev
, "BDC Internal error\n");
96 "command timedout waited for %dusec\n",
101 dev_dbg(bdc
->dev
, "Unknown command completion code:%x\n", ret
);
107 /* Deconfigure the endpoint from HW */
108 int bdc_dconfig_ep(struct bdc
*bdc
, struct bdc_ep
*ep
)
112 cmd_sc
= BDC_SUB_CMD_DRP_EP
|BDC_CMD_EPN(ep
->ep_num
)|BDC_CMD_EPC
;
113 dev_dbg(bdc
->dev
, "%s ep->ep_num =%d cmd_sc=%x\n", __func__
,
116 return bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, 0);
119 /* Reinitalize the bdlist after config ep command */
120 static void ep_bd_list_reinit(struct bdc_ep
*ep
)
122 struct bdc
*bdc
= ep
->bdc
;
125 ep
->bd_list
.eqp_bdi
= 0;
126 ep
->bd_list
.hwd_bdi
= 0;
127 bd
= ep
->bd_list
.bd_table_array
[0]->start_bd
;
128 dev_dbg(bdc
->dev
, "%s ep:%p bd:%p\n", __func__
, ep
, bd
);
129 memset(bd
, 0, sizeof(struct bdc_bd
));
130 bd
->offset
[3] |= cpu_to_le32(BD_SBF
);
133 /* Configure an endpoint */
134 int bdc_config_ep(struct bdc
*bdc
, struct bdc_ep
*ep
)
136 const struct usb_ss_ep_comp_descriptor
*comp_desc
;
137 const struct usb_endpoint_descriptor
*desc
;
138 u32 param0
, param1
, param2
, cmd_sc
;
139 u32 mps
, mbs
, mul
, si
;
143 comp_desc
= ep
->comp_desc
;
144 cmd_sc
= mul
= mbs
= param2
= 0;
145 param0
= lower_32_bits(ep
->bd_list
.bd_table_array
[0]->dma
);
146 param1
= upper_32_bits(ep
->bd_list
.bd_table_array
[0]->dma
);
147 cpu_to_le32s(¶m0
);
148 cpu_to_le32s(¶m1
);
150 dev_dbg(bdc
->dev
, "%s: param0=%08x param1=%08x",
151 __func__
, param0
, param1
);
152 si
= desc
->bInterval
;
153 si
= clamp_val(si
, 1, 16) - 1;
155 mps
= usb_endpoint_maxp(desc
);
157 param2
|= mps
<< MP_SHIFT
;
158 param2
|= usb_endpoint_type(desc
) << EPT_SHIFT
;
160 switch (bdc
->gadget
.speed
) {
161 case USB_SPEED_SUPER
:
162 if (usb_endpoint_xfer_int(desc
) ||
163 usb_endpoint_xfer_isoc(desc
)) {
165 if (usb_endpoint_xfer_isoc(desc
) && comp_desc
)
166 mul
= comp_desc
->bmAttributes
;
169 param2
|= mul
<< EPM_SHIFT
;
171 mbs
= comp_desc
->bMaxBurst
;
172 param2
|= mbs
<< MB_SHIFT
;
176 if (usb_endpoint_xfer_isoc(desc
) ||
177 usb_endpoint_xfer_int(desc
)) {
180 mbs
= usb_endpoint_maxp_mult(desc
);
181 param2
|= mbs
<< MB_SHIFT
;
187 /* the hardware accepts SI in 125usec range */
188 if (usb_endpoint_xfer_isoc(desc
))
192 * FS Int endpoints can have si of 1-255ms but the controller
193 * accepts 2^bInterval*125usec, so convert ms to nearest power
196 if (usb_endpoint_xfer_int(desc
))
197 si
= fls(desc
->bInterval
* 8) - 1;
202 dev_err(bdc
->dev
, "UNKNOWN speed ERR\n");
206 cmd_sc
|= BDC_CMD_EPC
|BDC_CMD_EPN(ep
->ep_num
)|BDC_SUB_CMD_ADD_EP
;
208 dev_dbg(bdc
->dev
, "cmd_sc=%x param2=%08x\n", cmd_sc
, param2
);
209 ret
= bdc_submit_cmd(bdc
, cmd_sc
, param0
, param1
, param2
);
211 dev_err(bdc
->dev
, "command failed :%x\n", ret
);
214 ep_bd_list_reinit(ep
);
220 * Change the HW deq pointer, if this command is successful, HW will start
221 * fetching the next bd from address dma_addr.
223 int bdc_ep_bla(struct bdc
*bdc
, struct bdc_ep
*ep
, dma_addr_t dma_addr
)
228 dev_dbg(bdc
->dev
, "%s: add=%08llx\n", __func__
,
229 (unsigned long long)(dma_addr
));
230 param0
= lower_32_bits(dma_addr
);
231 param1
= upper_32_bits(dma_addr
);
232 cpu_to_le32s(¶m0
);
233 cpu_to_le32s(¶m1
);
235 cmd_sc
|= BDC_CMD_EPN(ep
->ep_num
)|BDC_CMD_BLA
;
236 dev_dbg(bdc
->dev
, "cmd_sc=%x\n", cmd_sc
);
238 return bdc_submit_cmd(bdc
, cmd_sc
, param0
, param1
, 0);
241 /* Set the address sent bu Host in SET_ADD request */
242 int bdc_address_device(struct bdc
*bdc
, u32 add
)
247 dev_dbg(bdc
->dev
, "%s: add=%d\n", __func__
, add
);
248 cmd_sc
|= BDC_SUB_CMD_ADD
|BDC_CMD_DVC
;
251 return bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, param2
);
254 /* Send a Function Wake notification packet using FH command */
255 int bdc_function_wake_fh(struct bdc
*bdc
, u8 intf
)
261 dev_dbg(bdc
->dev
, "%s intf=%d\n", __func__
, intf
);
262 cmd_sc
|= BDC_CMD_FH
;
263 param0
|= TRA_PACKET
;
264 param0
|= (bdc
->dev_addr
<< 25);
265 param1
|= DEV_NOTF_TYPE
;
266 param1
|= (FWK_SUBTYPE
<<4);
267 dev_dbg(bdc
->dev
, "param0=%08x param1=%08x\n", param0
, param1
);
269 return bdc_submit_cmd(bdc
, cmd_sc
, param0
, param1
, 0);
272 /* Send a Function Wake notification packet using DNC command */
273 int bdc_function_wake(struct bdc
*bdc
, u8 intf
)
278 dev_dbg(bdc
->dev
, "%s intf=%d", __func__
, intf
);
280 cmd_sc
|= BDC_SUB_CMD_FWK
|BDC_CMD_DNC
;
282 return bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, param2
);
285 /* Stall the endpoint */
286 int bdc_ep_set_stall(struct bdc
*bdc
, int epnum
)
290 dev_dbg(bdc
->dev
, "%s epnum=%d\n", __func__
, epnum
);
291 /* issue a stall endpoint command */
292 cmd_sc
|= BDC_SUB_CMD_EP_STL
| BDC_CMD_EPN(epnum
) | BDC_CMD_EPO
;
294 return bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, 0);
297 /* resets the endpoint, called when host sends CLEAR_FEATURE(HALT) */
298 int bdc_ep_clear_stall(struct bdc
*bdc
, int epnum
)
304 dev_dbg(bdc
->dev
, "%s: epnum=%d\n", __func__
, epnum
);
305 ep
= bdc
->bdc_ep_array
[epnum
];
307 * If we are not in stalled then stall Endpoint and issue clear stall,
308 * his will reset the seq number for non EP0.
311 /* if the endpoint it not stallled */
312 if (!(ep
->flags
& BDC_EP_STALL
)) {
313 ret
= bdc_ep_set_stall(bdc
, epnum
);
318 /* Preserve the seq number for ep0 only */
320 cmd_sc
|= BDC_CMD_EPO_RST_SN
;
322 /* issue a reset endpoint command */
323 cmd_sc
|= BDC_SUB_CMD_EP_RST
| BDC_CMD_EPN(epnum
) | BDC_CMD_EPO
;
325 ret
= bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, 0);
327 dev_err(bdc
->dev
, "command failed:%x\n", ret
);
330 bdc_notify_xfr(bdc
, epnum
);
335 /* Stop the endpoint, called when software wants to dequeue some request */
336 int bdc_stop_ep(struct bdc
*bdc
, int epnum
)
342 ep
= bdc
->bdc_ep_array
[epnum
];
343 dev_dbg(bdc
->dev
, "%s: ep:%s ep->flags:%08x\n", __func__
,
344 ep
->name
, ep
->flags
);
345 /* Endpoint has to be in running state to execute stop ep command */
346 if (!(ep
->flags
& BDC_EP_ENABLED
)) {
347 dev_err(bdc
->dev
, "stop endpoint called for disabled ep\n");
350 if ((ep
->flags
& BDC_EP_STALL
) || (ep
->flags
& BDC_EP_STOP
))
353 /* issue a stop endpoint command */
354 cmd_sc
|= BDC_CMD_EP0_XSD
| BDC_SUB_CMD_EP_STP
355 | BDC_CMD_EPN(epnum
) | BDC_CMD_EPO
;
357 ret
= bdc_submit_cmd(bdc
, cmd_sc
, 0, 0, 0);
360 "stop endpoint command didn't complete:%d ep:%s\n",
364 ep
->flags
|= BDC_EP_STOP
;