1
2
3
4
5
6
7
8
9
10
11
12
13
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>
21#include <linux/io.h>
22#include <linux/list.h>
23#include <linux/delay.h>
24#include <linux/dma-mapping.h>
25#include <linux/dmapool.h>
26#include <linux/of.h>
27#include <linux/phy/phy.h>
28#include <linux/moduleparam.h>
29#include <linux/usb/ch9.h>
30#include <linux/usb/gadget.h>
31#include <linux/clk.h>
32
33#include "bdc.h"
34#include "bdc_dbg.h"
35
36
37static int poll_oip(struct bdc *bdc, int usec)
38{
39 u32 status;
40
41 while (usec) {
42 status = bdc_readl(bdc->regs, BDC_BDCSC);
43 if (BDC_CSTS(status) != BDC_OIP) {
44 dev_dbg(bdc->dev,
45 "poll_oip complete status=%d",
46 BDC_CSTS(status));
47 return 0;
48 }
49 udelay(10);
50 usec -= 10;
51 }
52 dev_err(bdc->dev, "Err: operation timedout BDCSC: 0x%08x\n", status);
53
54 return -ETIMEDOUT;
55}
56
57
58int bdc_stop(struct bdc *bdc)
59{
60 int ret;
61 u32 temp;
62
63 dev_dbg(bdc->dev, "%s ()\n\n", __func__);
64 temp = bdc_readl(bdc->regs, BDC_BDCSC);
65
66 if (BDC_CSTS(temp) == BDC_HLT) {
67 dev_vdbg(bdc->dev, "BDC already halted\n");
68 return 0;
69 }
70 temp &= ~BDC_COP_MASK;
71 temp |= BDC_COS|BDC_COP_STP;
72 bdc_writel(bdc->regs, BDC_BDCSC, temp);
73
74 ret = poll_oip(bdc, BDC_COP_TIMEOUT);
75 if (ret)
76 dev_err(bdc->dev, "bdc stop operation failed");
77
78 return ret;
79}
80
81
82int bdc_reset(struct bdc *bdc)
83{
84 u32 temp;
85 int ret;
86
87 dev_dbg(bdc->dev, "%s ()\n", __func__);
88
89 ret = bdc_stop(bdc);
90 if (ret)
91 return ret;
92
93 temp = bdc_readl(bdc->regs, BDC_BDCSC);
94 temp &= ~BDC_COP_MASK;
95 temp |= BDC_COS|BDC_COP_RST;
96 bdc_writel(bdc->regs, BDC_BDCSC, temp);
97 ret = poll_oip(bdc, BDC_COP_TIMEOUT);
98 if (ret)
99 dev_err(bdc->dev, "bdc reset operation failed");
100
101 return ret;
102}
103
104
105int bdc_run(struct bdc *bdc)
106{
107 u32 temp;
108 int ret;
109
110 dev_dbg(bdc->dev, "%s ()\n", __func__);
111 temp = bdc_readl(bdc->regs, BDC_BDCSC);
112
113 if (BDC_CSTS(temp) == BDC_NOR) {
114 dev_warn(bdc->dev, "bdc is already in running state\n");
115 return 0;
116 }
117 temp &= ~BDC_COP_MASK;
118 temp |= BDC_COP_RUN;
119 temp |= BDC_COS;
120 bdc_writel(bdc->regs, BDC_BDCSC, temp);
121 ret = poll_oip(bdc, BDC_COP_TIMEOUT);
122 if (ret) {
123 dev_err(bdc->dev, "bdc run operation failed:%d", ret);
124 return ret;
125 }
126 temp = bdc_readl(bdc->regs, BDC_BDCSC);
127 if (BDC_CSTS(temp) != BDC_NOR) {
128 dev_err(bdc->dev, "bdc not in normal mode after RUN op :%d\n",
129 BDC_CSTS(temp));
130 return -ESHUTDOWN;
131 }
132
133 return 0;
134}
135
136
137
138
139
140void bdc_softconn(struct bdc *bdc)
141{
142 u32 uspc;
143
144 uspc = bdc_readl(bdc->regs, BDC_USPC);
145 uspc &= ~BDC_PST_MASK;
146 uspc |= BDC_LINK_STATE_RX_DET;
147 uspc |= BDC_SWS;
148 dev_dbg(bdc->dev, "%s () uspc=%08x\n", __func__, uspc);
149 bdc_writel(bdc->regs, BDC_USPC, uspc);
150}
151
152
153void bdc_softdisconn(struct bdc *bdc)
154{
155 u32 uspc;
156
157 uspc = bdc_readl(bdc->regs, BDC_USPC);
158 uspc |= BDC_SDC;
159 uspc &= ~BDC_SCN;
160 dev_dbg(bdc->dev, "%s () uspc=%x\n", __func__, uspc);
161 bdc_writel(bdc->regs, BDC_USPC, uspc);
162}
163
164
165static int scratchpad_setup(struct bdc *bdc)
166{
167 int sp_buff_size;
168 u32 low32;
169 u32 upp32;
170
171 sp_buff_size = BDC_SPB(bdc_readl(bdc->regs, BDC_BDCCFG0));
172 dev_dbg(bdc->dev, "%s() sp_buff_size=%d\n", __func__, sp_buff_size);
173 if (!sp_buff_size) {
174 dev_dbg(bdc->dev, "Scratchpad buffer not needed\n");
175 return 0;
176 }
177
178 sp_buff_size = 1 << (sp_buff_size + 5);
179 dev_dbg(bdc->dev, "Allocating %d bytes for scratchpad\n", sp_buff_size);
180 bdc->scratchpad.buff = dma_zalloc_coherent(bdc->dev, sp_buff_size,
181 &bdc->scratchpad.sp_dma, GFP_KERNEL);
182
183 if (!bdc->scratchpad.buff)
184 goto fail;
185
186 bdc->sp_buff_size = sp_buff_size;
187 bdc->scratchpad.size = sp_buff_size;
188 low32 = lower_32_bits(bdc->scratchpad.sp_dma);
189 upp32 = upper_32_bits(bdc->scratchpad.sp_dma);
190 cpu_to_le32s(&low32);
191 cpu_to_le32s(&upp32);
192 bdc_writel(bdc->regs, BDC_SPBBAL, low32);
193 bdc_writel(bdc->regs, BDC_SPBBAH, upp32);
194 return 0;
195
196fail:
197 bdc->scratchpad.buff = NULL;
198
199 return -ENOMEM;
200}
201
202
203static int setup_srr(struct bdc *bdc, int interrupter)
204{
205 dev_dbg(bdc->dev, "%s() NUM_SR_ENTRIES:%d\n", __func__, NUM_SR_ENTRIES);
206
207 bdc_writel(bdc->regs, BDC_SRRINT(0), BDC_SRR_RWS | BDC_SRR_RST);
208 bdc->srr.dqp_index = 0;
209
210 bdc->srr.sr_bds = dma_zalloc_coherent(
211 bdc->dev,
212 NUM_SR_ENTRIES * sizeof(struct bdc_bd),
213 &bdc->srr.dma_addr,
214 GFP_KERNEL);
215 if (!bdc->srr.sr_bds)
216 return -ENOMEM;
217
218 return 0;
219}
220
221
222static void bdc_mem_init(struct bdc *bdc, bool reinit)
223{
224 u8 size = 0;
225 u32 usb2_pm;
226 u32 low32;
227 u32 upp32;
228 u32 temp;
229
230 dev_dbg(bdc->dev, "%s ()\n", __func__);
231 bdc->ep0_state = WAIT_FOR_SETUP;
232 bdc->dev_addr = 0;
233 bdc->srr.eqp_index = 0;
234 bdc->srr.dqp_index = 0;
235 bdc->zlp_needed = false;
236 bdc->delayed_status = false;
237
238 bdc_writel(bdc->regs, BDC_SPBBAL, bdc->scratchpad.sp_dma);
239
240 temp = BDC_SRR_RWS | BDC_SRR_RST;
241
242 bdc_writel(bdc->regs, BDC_SRRINT(0), temp);
243 dev_dbg(bdc->dev, "bdc->srr.sr_bds =%p\n", bdc->srr.sr_bds);
244 temp = lower_32_bits(bdc->srr.dma_addr);
245 size = fls(NUM_SR_ENTRIES) - 2;
246 temp |= size;
247 dev_dbg(bdc->dev, "SRRBAL[0]=%08x NUM_SR_ENTRIES:%d size:%d\n",
248 temp, NUM_SR_ENTRIES, size);
249
250 low32 = lower_32_bits(temp);
251 upp32 = upper_32_bits(bdc->srr.dma_addr);
252 cpu_to_le32s(&low32);
253 cpu_to_le32s(&upp32);
254
255
256 bdc_writel(bdc->regs, BDC_SRRBAL(0), low32);
257 bdc_writel(bdc->regs, BDC_SRRBAH(0), upp32);
258
259 temp = bdc_readl(bdc->regs, BDC_SRRINT(0));
260 temp |= BDC_SRR_IE;
261 temp &= ~(BDC_SRR_RST | BDC_SRR_RWS);
262 bdc_writel(bdc->regs, BDC_SRRINT(0), temp);
263
264
265 temp = bdc_readl(bdc->regs, BDC_INTCTLS(0));
266 temp &= ~0xffff;
267 temp |= INT_CLS;
268 bdc_writel(bdc->regs, BDC_INTCTLS(0), temp);
269
270 usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2);
271 dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm);
272
273 usb2_pm |= BDC_HLE;
274 bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm);
275
276
277 usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2);
278 dev_dbg(bdc->dev, "usb2_pm=%08x\n", usb2_pm);
279
280
281 temp = bdc_readl(bdc->regs, BDC_BDCSC);
282
283 temp |= BDC_MASK_MCW;
284 bdc_writel(bdc->regs, BDC_BDCSC, temp);
285
286
287
288
289
290 if (reinit) {
291
292 temp = bdc_readl(bdc->regs, BDC_BDCSC);
293 temp |= BDC_GIE;
294 bdc_writel(bdc->regs, BDC_BDCSC, temp);
295
296 memset(bdc->scratchpad.buff, 0, bdc->sp_buff_size);
297
298 memset(bdc->srr.sr_bds, 0,
299 NUM_SR_ENTRIES * sizeof(struct bdc_bd));
300 } else {
301
302
303 bdc->sr_handler[0] = bdc_sr_xsf;
304 bdc->sr_handler[1] = bdc_sr_uspc;
305
306
307 bdc->sr_xsf_ep0[0] = bdc_xsf_ep0_setup_recv;
308 bdc->sr_xsf_ep0[1] = bdc_xsf_ep0_data_start;
309 bdc->sr_xsf_ep0[2] = bdc_xsf_ep0_status_start;
310 }
311}
312
313
314static void bdc_mem_free(struct bdc *bdc)
315{
316 dev_dbg(bdc->dev, "%s\n", __func__);
317
318 if (bdc->srr.sr_bds)
319 dma_free_coherent(bdc->dev,
320 NUM_SR_ENTRIES * sizeof(struct bdc_bd),
321 bdc->srr.sr_bds, bdc->srr.dma_addr);
322
323
324 if (bdc->scratchpad.buff)
325 dma_free_coherent(bdc->dev, bdc->sp_buff_size,
326 bdc->scratchpad.buff, bdc->scratchpad.sp_dma);
327
328
329 dma_pool_destroy(bdc->bd_table_pool);
330
331
332 kfree(bdc->bdc_ep_array);
333
334 bdc->srr.sr_bds = NULL;
335 bdc->scratchpad.buff = NULL;
336 bdc->bd_table_pool = NULL;
337 bdc->bdc_ep_array = NULL;
338}
339
340
341
342
343
344int bdc_reinit(struct bdc *bdc)
345{
346 int ret;
347
348 dev_dbg(bdc->dev, "%s\n", __func__);
349 ret = bdc_stop(bdc);
350 if (ret)
351 goto out;
352
353 ret = bdc_reset(bdc);
354 if (ret)
355 goto out;
356
357
358 bdc_mem_init(bdc, true);
359 ret = bdc_run(bdc);
360out:
361 bdc->reinit = false;
362
363 return ret;
364}
365
366
367static int bdc_mem_alloc(struct bdc *bdc)
368{
369 u32 page_size;
370 unsigned int num_ieps, num_oeps;
371
372 dev_dbg(bdc->dev,
373 "%s() NUM_BDS_PER_TABLE:%d\n", __func__,
374 NUM_BDS_PER_TABLE);
375 page_size = BDC_PGS(bdc_readl(bdc->regs, BDC_BDCCFG0));
376
377 page_size = 1 << page_size;
378
379 page_size <<= 10;
380 dev_dbg(bdc->dev, "page_size=%d\n", page_size);
381
382
383 bdc->bd_table_pool =
384 dma_pool_create("BDC BD tables", bdc->dev, NUM_BDS_PER_TABLE * 16,
385 16, page_size);
386
387 if (!bdc->bd_table_pool)
388 goto fail;
389
390 if (scratchpad_setup(bdc))
391 goto fail;
392
393
394 num_ieps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNIC));
395 num_oeps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNOC));
396
397 bdc->num_eps = num_ieps + num_oeps + 2;
398 dev_dbg(bdc->dev,
399 "ieps:%d eops:%d num_eps:%d\n",
400 num_ieps, num_oeps, bdc->num_eps);
401
402 bdc->bdc_ep_array = kcalloc(bdc->num_eps, sizeof(struct bdc_ep *),
403 GFP_KERNEL);
404 if (!bdc->bdc_ep_array)
405 goto fail;
406
407 dev_dbg(bdc->dev, "Allocating sr report0\n");
408 if (setup_srr(bdc, 0))
409 goto fail;
410
411 return 0;
412fail:
413 dev_warn(bdc->dev, "Couldn't initialize memory\n");
414 bdc_mem_free(bdc);
415
416 return -ENOMEM;
417}
418
419
420static void bdc_hw_exit(struct bdc *bdc)
421{
422 dev_dbg(bdc->dev, "%s ()\n", __func__);
423 bdc_mem_free(bdc);
424}
425
426
427static int bdc_hw_init(struct bdc *bdc)
428{
429 int ret;
430
431 dev_dbg(bdc->dev, "%s ()\n", __func__);
432 ret = bdc_reset(bdc);
433 if (ret) {
434 dev_err(bdc->dev, "err resetting bdc abort bdc init%d\n", ret);
435 return ret;
436 }
437 ret = bdc_mem_alloc(bdc);
438 if (ret) {
439 dev_err(bdc->dev, "Mem alloc failed, aborting\n");
440 return -ENOMEM;
441 }
442 bdc_mem_init(bdc, 0);
443 bdc_dbg_regs(bdc);
444 dev_dbg(bdc->dev, "HW Init done\n");
445
446 return 0;
447}
448
449static int bdc_phy_init(struct bdc *bdc)
450{
451 int phy_num;
452 int ret;
453
454 for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
455 ret = phy_init(bdc->phys[phy_num]);
456 if (ret)
457 goto err_exit_phy;
458 ret = phy_power_on(bdc->phys[phy_num]);
459 if (ret) {
460 phy_exit(bdc->phys[phy_num]);
461 goto err_exit_phy;
462 }
463 }
464
465 return 0;
466
467err_exit_phy:
468 while (--phy_num >= 0) {
469 phy_power_off(bdc->phys[phy_num]);
470 phy_exit(bdc->phys[phy_num]);
471 }
472
473 return ret;
474}
475
476static void bdc_phy_exit(struct bdc *bdc)
477{
478 int phy_num;
479
480 for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
481 phy_power_off(bdc->phys[phy_num]);
482 phy_exit(bdc->phys[phy_num]);
483 }
484}
485
486static int bdc_probe(struct platform_device *pdev)
487{
488 struct bdc *bdc;
489 struct resource *res;
490 int ret = -ENOMEM;
491 int irq;
492 u32 temp;
493 struct device *dev = &pdev->dev;
494 struct clk *clk;
495 int phy_num;
496
497 dev_dbg(dev, "%s()\n", __func__);
498
499 clk = devm_clk_get(dev, "sw_usbd");
500 if (IS_ERR(clk)) {
501 dev_info(dev, "Clock not found in Device Tree\n");
502 clk = NULL;
503 }
504
505 ret = clk_prepare_enable(clk);
506 if (ret) {
507 dev_err(dev, "could not enable clock\n");
508 return ret;
509 }
510
511 bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL);
512 if (!bdc)
513 return -ENOMEM;
514
515 bdc->clk = clk;
516
517 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
518 bdc->regs = devm_ioremap_resource(dev, res);
519 if (IS_ERR(bdc->regs)) {
520 dev_err(dev, "ioremap error\n");
521 return -ENOMEM;
522 }
523 irq = platform_get_irq(pdev, 0);
524 if (irq < 0) {
525 dev_err(dev, "platform_get_irq failed:%d\n", irq);
526 return irq;
527 }
528 spin_lock_init(&bdc->lock);
529 platform_set_drvdata(pdev, bdc);
530 bdc->irq = irq;
531 bdc->dev = dev;
532 dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);
533
534 bdc->num_phys = of_count_phandle_with_args(dev->of_node,
535 "phys", "#phy-cells");
536 if (bdc->num_phys > 0) {
537 bdc->phys = devm_kcalloc(dev, bdc->num_phys,
538 sizeof(struct phy *), GFP_KERNEL);
539 if (!bdc->phys)
540 return -ENOMEM;
541 } else {
542 bdc->num_phys = 0;
543 }
544 dev_info(dev, "Using %d phy(s)\n", bdc->num_phys);
545
546 for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) {
547 bdc->phys[phy_num] = devm_of_phy_get_by_index(
548 dev, dev->of_node, phy_num);
549 if (IS_ERR(bdc->phys[phy_num])) {
550 ret = PTR_ERR(bdc->phys[phy_num]);
551 dev_err(bdc->dev,
552 "BDC phy specified but not found:%d\n", ret);
553 return ret;
554 }
555 }
556
557 ret = bdc_phy_init(bdc);
558 if (ret) {
559 dev_err(bdc->dev, "BDC phy init failure:%d\n", ret);
560 return ret;
561 }
562
563 temp = bdc_readl(bdc->regs, BDC_BDCCAP1);
564 if ((temp & BDC_P64) &&
565 !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
566 dev_dbg(dev, "Using 64-bit address\n");
567 } else {
568 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
569 if (ret) {
570 dev_err(dev,
571 "No suitable DMA config available, abort\n");
572 return -ENOTSUPP;
573 }
574 dev_dbg(dev, "Using 32-bit address\n");
575 }
576 ret = bdc_hw_init(bdc);
577 if (ret) {
578 dev_err(dev, "BDC init failure:%d\n", ret);
579 goto phycleanup;
580 }
581 ret = bdc_udc_init(bdc);
582 if (ret) {
583 dev_err(dev, "BDC Gadget init failure:%d\n", ret);
584 goto cleanup;
585 }
586 return 0;
587
588cleanup:
589 bdc_hw_exit(bdc);
590phycleanup:
591 bdc_phy_exit(bdc);
592 return ret;
593}
594
595static int bdc_remove(struct platform_device *pdev)
596{
597 struct bdc *bdc;
598
599 bdc = platform_get_drvdata(pdev);
600 dev_dbg(bdc->dev, "%s ()\n", __func__);
601 bdc_udc_exit(bdc);
602 bdc_hw_exit(bdc);
603 bdc_phy_exit(bdc);
604 clk_disable_unprepare(bdc->clk);
605 return 0;
606}
607
608#ifdef CONFIG_PM_SLEEP
609static int bdc_suspend(struct device *dev)
610{
611 struct bdc *bdc = dev_get_drvdata(dev);
612
613 clk_disable_unprepare(bdc->clk);
614 return 0;
615}
616
617static int bdc_resume(struct device *dev)
618{
619 struct bdc *bdc = dev_get_drvdata(dev);
620 int ret;
621
622 ret = clk_prepare_enable(bdc->clk);
623 if (ret) {
624 dev_err(bdc->dev, "err enabling the clock\n");
625 return ret;
626 }
627 ret = bdc_reinit(bdc);
628 if (ret) {
629 dev_err(bdc->dev, "err in bdc reinit\n");
630 return ret;
631 }
632
633 return 0;
634}
635
636#endif
637
638static SIMPLE_DEV_PM_OPS(bdc_pm_ops, bdc_suspend,
639 bdc_resume);
640
641static const struct of_device_id bdc_of_match[] = {
642 { .compatible = "brcm,bdc-v0.16" },
643 { .compatible = "brcm,bdc" },
644 { }
645};
646
647static struct platform_driver bdc_driver = {
648 .driver = {
649 .name = BRCM_BDC_NAME,
650 .owner = THIS_MODULE,
651 .pm = &bdc_pm_ops,
652 .of_match_table = bdc_of_match,
653 },
654 .probe = bdc_probe,
655 .remove = bdc_remove,
656};
657
658module_platform_driver(bdc_driver);
659MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>");
660MODULE_LICENSE("GPL");
661MODULE_DESCRIPTION(BRCM_BDC_DESC);
662