2 * bdc_core.c - BRCM BDC USB3.0 device controller core operations
4 * Copyright (C) 2014 Broadcom Corporation
6 * Author: Ashwini Pahuja
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/spinlock.h>
18 #include <linux/platform_device.h>
19 #include <linux/interrupt.h>
20 #include <linux/ioport.h>
22 #include <linux/list.h>
23 #include <linux/delay.h>
24 #include <linux/dma-mapping.h>
25 #include <linux/dmapool.h>
27 #include <linux/moduleparam.h>
28 #include <linux/usb/ch9.h>
29 #include <linux/usb/gadget.h>
34 /* Poll till controller status is not OIP */
35 static int poll_oip(struct bdc
*bdc
, int usec
)
38 /* Poll till STS!= OIP */
40 status
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
41 if (BDC_CSTS(status
) != BDC_OIP
) {
43 "poll_oip complete status=%d",
50 dev_err(bdc
->dev
, "Err: operation timedout BDCSC: 0x%08x\n", status
);
55 /* Stop the BDC controller */
56 int bdc_stop(struct bdc
*bdc
)
61 dev_dbg(bdc
->dev
, "%s ()\n\n", __func__
);
62 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
63 /* Check if BDC is already halted */
64 if (BDC_CSTS(temp
) == BDC_HLT
) {
65 dev_vdbg(bdc
->dev
, "BDC already halted\n");
68 temp
&= ~BDC_COP_MASK
;
69 temp
|= BDC_COS
|BDC_COP_STP
;
70 bdc_writel(bdc
->regs
, BDC_BDCSC
, temp
);
72 ret
= poll_oip(bdc
, BDC_COP_TIMEOUT
);
74 dev_err(bdc
->dev
, "bdc stop operation failed");
79 /* Issue a reset to BDC controller */
80 int bdc_reset(struct bdc
*bdc
)
85 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
86 /* First halt the controller */
91 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
92 temp
&= ~BDC_COP_MASK
;
93 temp
|= BDC_COS
|BDC_COP_RST
;
94 bdc_writel(bdc
->regs
, BDC_BDCSC
, temp
);
95 ret
= poll_oip(bdc
, BDC_COP_TIMEOUT
);
97 dev_err(bdc
->dev
, "bdc reset operation failed");
102 /* Run the BDC controller */
103 int bdc_run(struct bdc
*bdc
)
108 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
109 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
110 /* if BDC is already in running state then do not do anything */
111 if (BDC_CSTS(temp
) == BDC_NOR
) {
112 dev_warn(bdc
->dev
, "bdc is already in running state\n");
115 temp
&= ~BDC_COP_MASK
;
118 bdc_writel(bdc
->regs
, BDC_BDCSC
, temp
);
119 ret
= poll_oip(bdc
, BDC_COP_TIMEOUT
);
121 dev_err(bdc
->dev
, "bdc run operation failed:%d", ret
);
124 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
125 if (BDC_CSTS(temp
) != BDC_NOR
) {
126 dev_err(bdc
->dev
, "bdc not in normal mode after RUN op :%d\n",
135 * Present the termination to the host, typically called from upstream port
136 * event with Vbus present =1
138 void bdc_softconn(struct bdc
*bdc
)
142 uspc
= bdc_readl(bdc
->regs
, BDC_USPC
);
143 uspc
&= ~BDC_PST_MASK
;
144 uspc
|= BDC_LINK_STATE_RX_DET
;
146 dev_dbg(bdc
->dev
, "%s () uspc=%08x\n", __func__
, uspc
);
147 bdc_writel(bdc
->regs
, BDC_USPC
, uspc
);
150 /* Remove the termination */
151 void bdc_softdisconn(struct bdc
*bdc
)
155 uspc
= bdc_readl(bdc
->regs
, BDC_USPC
);
158 dev_dbg(bdc
->dev
, "%s () uspc=%x\n", __func__
, uspc
);
159 bdc_writel(bdc
->regs
, BDC_USPC
, uspc
);
162 /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
163 static int scratchpad_setup(struct bdc
*bdc
)
169 sp_buff_size
= BDC_SPB(bdc_readl(bdc
->regs
, BDC_BDCCFG0
));
170 dev_dbg(bdc
->dev
, "%s() sp_buff_size=%d\n", __func__
, sp_buff_size
);
172 dev_dbg(bdc
->dev
, "Scratchpad buffer not needed\n");
175 /* Refer to BDC spec, Table 4 for description of SPB */
176 sp_buff_size
= 1 << (sp_buff_size
+ 5);
177 dev_dbg(bdc
->dev
, "Allocating %d bytes for scratchpad\n", sp_buff_size
);
178 bdc
->scratchpad
.buff
= dma_zalloc_coherent(bdc
->dev
, sp_buff_size
,
179 &bdc
->scratchpad
.sp_dma
, GFP_KERNEL
);
181 if (!bdc
->scratchpad
.buff
)
184 bdc
->sp_buff_size
= sp_buff_size
;
185 bdc
->scratchpad
.size
= sp_buff_size
;
186 low32
= lower_32_bits(bdc
->scratchpad
.sp_dma
);
187 upp32
= upper_32_bits(bdc
->scratchpad
.sp_dma
);
188 cpu_to_le32s(&low32
);
189 cpu_to_le32s(&upp32
);
190 bdc_writel(bdc
->regs
, BDC_SPBBAL
, low32
);
191 bdc_writel(bdc
->regs
, BDC_SPBBAH
, upp32
);
195 bdc
->scratchpad
.buff
= NULL
;
200 /* Allocate the status report ring */
201 static int setup_srr(struct bdc
*bdc
, int interrupter
)
203 dev_dbg(bdc
->dev
, "%s() NUM_SR_ENTRIES:%d\n", __func__
, NUM_SR_ENTRIES
);
205 bdc_writel(bdc
->regs
, BDC_SRRINT(0), BDC_SRR_RWS
| BDC_SRR_RST
);
206 bdc
->srr
.dqp_index
= 0;
207 /* allocate the status report descriptors */
208 bdc
->srr
.sr_bds
= dma_zalloc_coherent(
210 NUM_SR_ENTRIES
* sizeof(struct bdc_bd
),
213 if (!bdc
->srr
.sr_bds
)
219 /* Initialize the HW regs and internal data structures */
220 static void bdc_mem_init(struct bdc
*bdc
, bool reinit
)
228 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
229 bdc
->ep0_state
= WAIT_FOR_SETUP
;
231 bdc
->srr
.eqp_index
= 0;
232 bdc
->srr
.dqp_index
= 0;
233 bdc
->zlp_needed
= false;
234 bdc
->delayed_status
= false;
236 bdc_writel(bdc
->regs
, BDC_SPBBAL
, bdc
->scratchpad
.sp_dma
);
238 temp
= BDC_SRR_RWS
| BDC_SRR_RST
;
240 bdc_writel(bdc
->regs
, BDC_SRRINT(0), temp
);
241 dev_dbg(bdc
->dev
, "bdc->srr.sr_bds =%p\n", bdc
->srr
.sr_bds
);
242 temp
= lower_32_bits(bdc
->srr
.dma_addr
);
243 size
= fls(NUM_SR_ENTRIES
) - 2;
245 dev_dbg(bdc
->dev
, "SRRBAL[0]=%08x NUM_SR_ENTRIES:%d size:%d\n",
246 temp
, NUM_SR_ENTRIES
, size
);
248 low32
= lower_32_bits(temp
);
249 upp32
= upper_32_bits(bdc
->srr
.dma_addr
);
250 cpu_to_le32s(&low32
);
251 cpu_to_le32s(&upp32
);
253 /* Write the dma addresses into regs*/
254 bdc_writel(bdc
->regs
, BDC_SRRBAL(0), low32
);
255 bdc_writel(bdc
->regs
, BDC_SRRBAH(0), upp32
);
257 temp
= bdc_readl(bdc
->regs
, BDC_SRRINT(0));
259 temp
&= ~(BDC_SRR_RST
| BDC_SRR_RWS
);
260 bdc_writel(bdc
->regs
, BDC_SRRINT(0), temp
);
262 /* Set the Interrupt Coalescence ~500 usec */
263 temp
= bdc_readl(bdc
->regs
, BDC_INTCTLS(0));
266 bdc_writel(bdc
->regs
, BDC_INTCTLS(0), temp
);
268 usb2_pm
= bdc_readl(bdc
->regs
, BDC_USPPM2
);
269 dev_dbg(bdc
->dev
, "usb2_pm=%08x", usb2_pm
);
270 /* Enable hardware LPM Enable */
272 bdc_writel(bdc
->regs
, BDC_USPPM2
, usb2_pm
);
274 /* readback for debug */
275 usb2_pm
= bdc_readl(bdc
->regs
, BDC_USPPM2
);
276 dev_dbg(bdc
->dev
, "usb2_pm=%08x\n", usb2_pm
);
278 /* Disable any unwanted SR's on SRR */
279 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
280 /* We don't want Microframe counter wrap SR */
281 temp
|= BDC_MASK_MCW
;
282 bdc_writel(bdc
->regs
, BDC_BDCSC
, temp
);
285 * In some error cases, driver has to reset the entire BDC controller
286 * in that case reinit is passed as 1
289 /* Enable interrupts */
290 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
292 bdc_writel(bdc
->regs
, BDC_BDCSC
, temp
);
293 /* Init scratchpad to 0 */
294 memset(bdc
->scratchpad
.buff
, 0, bdc
->sp_buff_size
);
295 /* Initialize SRR to 0 */
296 memset(bdc
->srr
.sr_bds
, 0,
297 NUM_SR_ENTRIES
* sizeof(struct bdc_bd
));
299 /* One time initiaization only */
300 /* Enable status report function pointers */
301 bdc
->sr_handler
[0] = bdc_sr_xsf
;
302 bdc
->sr_handler
[1] = bdc_sr_uspc
;
304 /* EP0 status report function pointers */
305 bdc
->sr_xsf_ep0
[0] = bdc_xsf_ep0_setup_recv
;
306 bdc
->sr_xsf_ep0
[1] = bdc_xsf_ep0_data_start
;
307 bdc
->sr_xsf_ep0
[2] = bdc_xsf_ep0_status_start
;
311 /* Free the dynamic memory */
312 static void bdc_mem_free(struct bdc
*bdc
)
314 dev_dbg(bdc
->dev
, "%s\n", __func__
);
317 dma_free_coherent(bdc
->dev
,
318 NUM_SR_ENTRIES
* sizeof(struct bdc_bd
),
319 bdc
->srr
.sr_bds
, bdc
->srr
.dma_addr
);
321 /* Free scratchpad */
322 if (bdc
->scratchpad
.buff
)
323 dma_free_coherent(bdc
->dev
, bdc
->sp_buff_size
,
324 bdc
->scratchpad
.buff
, bdc
->scratchpad
.sp_dma
);
326 /* Destroy the dma pools */
327 dma_pool_destroy(bdc
->bd_table_pool
);
329 /* Free the bdc_ep array */
330 kfree(bdc
->bdc_ep_array
);
332 bdc
->srr
.sr_bds
= NULL
;
333 bdc
->scratchpad
.buff
= NULL
;
334 bdc
->bd_table_pool
= NULL
;
335 bdc
->bdc_ep_array
= NULL
;
339 * bdc reinit gives a controller reset and reinitialize the registers,
340 * called from disconnect/bus reset scenario's, to ensure proper HW cleanup
342 int bdc_reinit(struct bdc
*bdc
)
346 dev_dbg(bdc
->dev
, "%s\n", __func__
);
351 ret
= bdc_reset(bdc
);
355 /* the reinit flag is 1 */
356 bdc_mem_init(bdc
, true);
364 /* Allocate all the dyanmic memory */
365 static int bdc_mem_alloc(struct bdc
*bdc
)
368 unsigned int num_ieps
, num_oeps
;
371 "%s() NUM_BDS_PER_TABLE:%d\n", __func__
,
373 page_size
= BDC_PGS(bdc_readl(bdc
->regs
, BDC_BDCCFG0
));
374 /* page size is 2^pgs KB */
375 page_size
= 1 << page_size
;
378 dev_dbg(bdc
->dev
, "page_size=%d\n", page_size
);
380 /* Create a pool of bd tables */
382 dma_pool_create("BDC BD tables", bdc
->dev
, NUM_BDS_PER_TABLE
* 16,
385 if (!bdc
->bd_table_pool
)
388 if (scratchpad_setup(bdc
))
392 num_ieps
= NUM_NCS(bdc_readl(bdc
->regs
, BDC_FSCNIC
));
393 num_oeps
= NUM_NCS(bdc_readl(bdc
->regs
, BDC_FSCNOC
));
394 /* +2: 1 for ep0 and the other is rsvd i.e. bdc_ep[0] is rsvd */
395 bdc
->num_eps
= num_ieps
+ num_oeps
+ 2;
397 "ieps:%d eops:%d num_eps:%d\n",
398 num_ieps
, num_oeps
, bdc
->num_eps
);
399 /* allocate array of ep pointers */
400 bdc
->bdc_ep_array
= kcalloc(bdc
->num_eps
, sizeof(struct bdc_ep
*),
402 if (!bdc
->bdc_ep_array
)
405 dev_dbg(bdc
->dev
, "Allocating sr report0\n");
406 if (setup_srr(bdc
, 0))
411 dev_warn(bdc
->dev
, "Couldn't initialize memory\n");
417 /* opposite to bdc_hw_init */
418 static void bdc_hw_exit(struct bdc
*bdc
)
420 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
424 /* Initialize the bdc HW and memory */
425 static int bdc_hw_init(struct bdc
*bdc
)
429 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
430 ret
= bdc_reset(bdc
);
432 dev_err(bdc
->dev
, "err resetting bdc abort bdc init%d\n", ret
);
435 ret
= bdc_mem_alloc(bdc
);
437 dev_err(bdc
->dev
, "Mem alloc failed, aborting\n");
440 bdc_mem_init(bdc
, 0);
442 dev_dbg(bdc
->dev
, "HW Init done\n");
447 static int bdc_probe(struct platform_device
*pdev
)
450 struct resource
*res
;
454 struct device
*dev
= &pdev
->dev
;
456 dev_dbg(dev
, "%s()\n", __func__
);
457 bdc
= devm_kzalloc(dev
, sizeof(*bdc
), GFP_KERNEL
);
461 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
462 bdc
->regs
= devm_ioremap_resource(dev
, res
);
463 if (IS_ERR(bdc
->regs
)) {
464 dev_err(dev
, "ioremap error\n");
467 irq
= platform_get_irq(pdev
, 0);
469 dev_err(dev
, "platform_get_irq failed:%d\n", irq
);
472 spin_lock_init(&bdc
->lock
);
473 platform_set_drvdata(pdev
, bdc
);
476 dev_dbg(bdc
->dev
, "bdc->regs: %p irq=%d\n", bdc
->regs
, bdc
->irq
);
478 temp
= bdc_readl(bdc
->regs
, BDC_BDCSC
);
479 if ((temp
& BDC_P64
) &&
480 !dma_set_mask_and_coherent(dev
, DMA_BIT_MASK(64))) {
481 dev_dbg(bdc
->dev
, "Using 64-bit address\n");
483 ret
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(32));
485 dev_err(bdc
->dev
, "No suitable DMA config available, abort\n");
488 dev_dbg(bdc
->dev
, "Using 32-bit address\n");
490 ret
= bdc_hw_init(bdc
);
492 dev_err(bdc
->dev
, "BDC init failure:%d\n", ret
);
495 ret
= bdc_udc_init(bdc
);
497 dev_err(bdc
->dev
, "BDC Gadget init failure:%d\n", ret
);
508 static int bdc_remove(struct platform_device
*pdev
)
512 bdc
= platform_get_drvdata(pdev
);
513 dev_dbg(bdc
->dev
, "%s ()\n", __func__
);
520 static struct platform_driver bdc_driver
= {
522 .name
= BRCM_BDC_NAME
,
525 .remove
= bdc_remove
,
528 module_platform_driver(bdc_driver
);
529 MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>");
530 MODULE_LICENSE("GPL");
531 MODULE_DESCRIPTION(BRCM_BDC_DESC
);