1/*
2 * bdc_core.c - BRCM BDC USB3.0 device controller core operations
3 *
4 * Copyright (C) 2014 Broadcom Corporation
5 *
6 * Author: Ashwini Pahuja
7 *
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.
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/moduleparam.h>
28#include <linux/usb/ch9.h>
29#include <linux/usb/gadget.h>
30
31#include "bdc.h"
32#include "bdc_dbg.h"
33
34/* Poll till controller status is not OIP */
35static int poll_oip(struct bdc *bdc, int usec)
36{
37	u32 status;
38	/* Poll till STS!= OIP */
39	while (usec) {
40		status = bdc_readl(bdc->regs, BDC_BDCSC);
41		if (BDC_CSTS(status) != BDC_OIP) {
42			dev_dbg(bdc->dev,
43				"poll_oip complete status=%d",
44				BDC_CSTS(status));
45			return 0;
46		}
47		udelay(10);
48		usec -= 10;
49	}
50	dev_err(bdc->dev, "Err: operation timedout BDCSC: 0x%08x\n", status);
51
52	return -ETIMEDOUT;
53}
54
55/* Stop the BDC controller */
56int bdc_stop(struct bdc *bdc)
57{
58	int ret;
59	u32 temp;
60
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");
66		return 0;
67	}
68	temp &= ~BDC_COP_MASK;
69	temp |= BDC_COS|BDC_COP_STP;
70	bdc_writel(bdc->regs, BDC_BDCSC, temp);
71
72	ret = poll_oip(bdc, BDC_COP_TIMEOUT);
73	if (ret)
74		dev_err(bdc->dev, "bdc stop operation failed");
75
76	return ret;
77}
78
79/* Issue a reset to BDC controller */
80int bdc_reset(struct bdc *bdc)
81{
82	u32 temp;
83	int ret;
84
85	dev_dbg(bdc->dev, "%s ()\n", __func__);
86	/* First halt the controller */
87	ret = bdc_stop(bdc);
88	if (ret)
89		return ret;
90
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);
96	if (ret)
97		dev_err(bdc->dev, "bdc reset operation failed");
98
99	return ret;
100}
101
102/* Run the BDC controller */
103int bdc_run(struct bdc *bdc)
104{
105	u32 temp;
106	int ret;
107
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");
113		return 0;
114	}
115	temp &= ~BDC_COP_MASK;
116	temp |= BDC_COP_RUN;
117	temp |= BDC_COS;
118	bdc_writel(bdc->regs, BDC_BDCSC, temp);
119	ret = poll_oip(bdc, BDC_COP_TIMEOUT);
120	if (ret) {
121		dev_err(bdc->dev, "bdc run operation failed:%d", ret);
122		return ret;
123	}
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",
127								BDC_CSTS(temp));
128		return -ESHUTDOWN;
129	}
130
131	return 0;
132}
133
134/*
135 * Present the termination to the host, typically called from upstream port
136 * event with Vbus present =1
137 */
138void bdc_softconn(struct bdc *bdc)
139{
140	u32 uspc;
141
142	uspc = bdc_readl(bdc->regs, BDC_USPC);
143	uspc &= ~BDC_PST_MASK;
144	uspc |= BDC_LINK_STATE_RX_DET;
145	uspc |= BDC_SWS;
146	dev_dbg(bdc->dev, "%s () uspc=%08x\n", __func__, uspc);
147	bdc_writel(bdc->regs, BDC_USPC, uspc);
148}
149
150/* Remove the termination */
151void bdc_softdisconn(struct bdc *bdc)
152{
153	u32 uspc;
154
155	uspc = bdc_readl(bdc->regs, BDC_USPC);
156	uspc |= BDC_SDC;
157	uspc &= ~BDC_SCN;
158	dev_dbg(bdc->dev, "%s () uspc=%x\n", __func__, uspc);
159	bdc_writel(bdc->regs, BDC_USPC, uspc);
160}
161
162/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
163static int scratchpad_setup(struct bdc *bdc)
164{
165	int sp_buff_size;
166	u32 low32;
167	u32 upp32;
168
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);
171	if (!sp_buff_size) {
172		dev_dbg(bdc->dev, "Scratchpad buffer not needed\n");
173		return 0;
174	}
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);
180
181	if (!bdc->scratchpad.buff)
182		goto fail;
183
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);
192	return 0;
193
194fail:
195	bdc->scratchpad.buff = NULL;
196
197	return -ENOMEM;
198}
199
200/* Allocate the status report ring */
201static int setup_srr(struct bdc *bdc, int interrupter)
202{
203	dev_dbg(bdc->dev, "%s() NUM_SR_ENTRIES:%d\n", __func__, NUM_SR_ENTRIES);
204	/* Reset the SRR */
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(
209					bdc->dev,
210					NUM_SR_ENTRIES * sizeof(struct bdc_bd),
211					&bdc->srr.dma_addr,
212					GFP_KERNEL);
213	if (!bdc->srr.sr_bds)
214		return -ENOMEM;
215
216	return 0;
217}
218
219/* Initialize the HW regs and internal data structures */
220static void bdc_mem_init(struct bdc *bdc, bool reinit)
221{
222	u8 size = 0;
223	u32 usb2_pm;
224	u32 low32;
225	u32 upp32;
226	u32 temp;
227
228	dev_dbg(bdc->dev, "%s ()\n", __func__);
229	bdc->ep0_state = WAIT_FOR_SETUP;
230	bdc->dev_addr = 0;
231	bdc->srr.eqp_index = 0;
232	bdc->srr.dqp_index = 0;
233	bdc->zlp_needed = false;
234	bdc->delayed_status = false;
235
236	bdc_writel(bdc->regs, BDC_SPBBAL, bdc->scratchpad.sp_dma);
237	/* Init the SRR */
238	temp = BDC_SRR_RWS | BDC_SRR_RST;
239	/* Reset the SRR */
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;
244	temp |= size;
245	dev_dbg(bdc->dev, "SRRBAL[0]=%08x NUM_SR_ENTRIES:%d size:%d\n",
246						temp, NUM_SR_ENTRIES, size);
247
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);
252
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);
256
257	temp = bdc_readl(bdc->regs, BDC_SRRINT(0));
258	temp |= BDC_SRR_IE;
259	temp &= ~(BDC_SRR_RST | BDC_SRR_RWS);
260	bdc_writel(bdc->regs, BDC_SRRINT(0), temp);
261
262	/* Set the Interrupt Coalescence ~500 usec */
263	temp = bdc_readl(bdc->regs, BDC_INTCTLS(0));
264	temp &= ~0xffff;
265	temp |= INT_CLS;
266	bdc_writel(bdc->regs, BDC_INTCTLS(0), temp);
267
268	usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2);
269	dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm);
270	/* Enable hardware LPM Enable */
271	usb2_pm |= BDC_HLE;
272	bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm);
273
274	/* readback for debug */
275	usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2);
276	dev_dbg(bdc->dev, "usb2_pm=%08x\n", usb2_pm);
277
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);
283
284	/*
285	 * In some error cases, driver has to reset the entire BDC controller
286	 * in that case reinit is passed as 1
287	 */
288	if (reinit) {
289		/* Enable interrupts */
290		temp = bdc_readl(bdc->regs, BDC_BDCSC);
291		temp |= BDC_GIE;
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));
298	} else {
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;
303
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;
308	}
309}
310
311/* Free the dynamic memory */
312static void bdc_mem_free(struct bdc *bdc)
313{
314	dev_dbg(bdc->dev, "%s\n", __func__);
315	/* Free SRR */
316	if (bdc->srr.sr_bds)
317		dma_free_coherent(bdc->dev,
318					NUM_SR_ENTRIES * sizeof(struct bdc_bd),
319					bdc->srr.sr_bds, bdc->srr.dma_addr);
320
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);
325
326	/* Destroy the dma pools */
327	if (bdc->bd_table_pool)
328		dma_pool_destroy(bdc->bd_table_pool);
329
330	/* Free the bdc_ep array */
331	kfree(bdc->bdc_ep_array);
332
333	bdc->srr.sr_bds = NULL;
334	bdc->scratchpad.buff = NULL;
335	bdc->bd_table_pool = NULL;
336	bdc->bdc_ep_array = NULL;
337}
338
339/*
340 * bdc reinit gives a controller reset and reinitialize the registers,
341 * called from disconnect/bus reset scenario's, to ensure proper HW cleanup
342 */
343int bdc_reinit(struct bdc *bdc)
344{
345	int ret;
346
347	dev_dbg(bdc->dev, "%s\n", __func__);
348	ret = bdc_stop(bdc);
349	if (ret)
350		goto out;
351
352	ret = bdc_reset(bdc);
353	if (ret)
354		goto out;
355
356	/* the reinit flag is 1 */
357	bdc_mem_init(bdc, true);
358	ret = bdc_run(bdc);
359out:
360	bdc->reinit = false;
361
362	return ret;
363}
364
365/* Allocate all the dyanmic memory */
366static int bdc_mem_alloc(struct bdc *bdc)
367{
368	u32 page_size;
369	unsigned int num_ieps, num_oeps;
370
371	dev_dbg(bdc->dev,
372		"%s() NUM_BDS_PER_TABLE:%d\n", __func__,
373		NUM_BDS_PER_TABLE);
374	page_size = BDC_PGS(bdc_readl(bdc->regs, BDC_BDCCFG0));
375	/* page size is 2^pgs KB */
376	page_size = 1 << page_size;
377	/* KB */
378	page_size <<= 10;
379	dev_dbg(bdc->dev, "page_size=%d\n", page_size);
380
381	/* Create a pool of bd tables */
382	bdc->bd_table_pool =
383	    dma_pool_create("BDC BD tables", bdc->dev, NUM_BDS_PER_TABLE * 16,
384								16, page_size);
385
386	if (!bdc->bd_table_pool)
387		goto fail;
388
389	if (scratchpad_setup(bdc))
390		goto fail;
391
392	/* read from regs */
393	num_ieps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNIC));
394	num_oeps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNOC));
395	/* +2: 1 for ep0 and the other is rsvd i.e. bdc_ep[0] is rsvd */
396	bdc->num_eps = num_ieps + num_oeps + 2;
397	dev_dbg(bdc->dev,
398		"ieps:%d eops:%d num_eps:%d\n",
399		num_ieps, num_oeps, bdc->num_eps);
400	/* allocate array of ep pointers */
401	bdc->bdc_ep_array = kcalloc(bdc->num_eps, sizeof(struct bdc_ep *),
402								GFP_KERNEL);
403	if (!bdc->bdc_ep_array)
404		goto fail;
405
406	dev_dbg(bdc->dev, "Allocating sr report0\n");
407	if (setup_srr(bdc, 0))
408		goto fail;
409
410	return 0;
411fail:
412	dev_warn(bdc->dev, "Couldn't initialize memory\n");
413	bdc_mem_free(bdc);
414
415	return -ENOMEM;
416}
417
418/* opposite to bdc_hw_init */
419static void bdc_hw_exit(struct bdc *bdc)
420{
421	dev_dbg(bdc->dev, "%s ()\n", __func__);
422	bdc_mem_free(bdc);
423}
424
425/* Initialize the bdc HW and memory */
426static int bdc_hw_init(struct bdc *bdc)
427{
428	int ret;
429
430	dev_dbg(bdc->dev, "%s ()\n", __func__);
431	ret = bdc_reset(bdc);
432	if (ret) {
433		dev_err(bdc->dev, "err resetting bdc abort bdc init%d\n", ret);
434		return ret;
435	}
436	ret = bdc_mem_alloc(bdc);
437	if (ret) {
438		dev_err(bdc->dev, "Mem alloc failed, aborting\n");
439		return -ENOMEM;
440	}
441	bdc_mem_init(bdc, 0);
442	bdc_dbg_regs(bdc);
443	dev_dbg(bdc->dev, "HW Init done\n");
444
445	return 0;
446}
447
448static int bdc_probe(struct platform_device *pdev)
449{
450	struct bdc *bdc;
451	struct resource *res;
452	int ret = -ENOMEM;
453	int irq;
454	u32 temp;
455	struct device *dev = &pdev->dev;
456
457	dev_dbg(dev, "%s()\n", __func__);
458	bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL);
459	if (!bdc)
460		return -ENOMEM;
461
462	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
463	bdc->regs = devm_ioremap_resource(dev, res);
464	if (IS_ERR(bdc->regs)) {
465		dev_err(dev, "ioremap error\n");
466		return -ENOMEM;
467	}
468	irq = platform_get_irq(pdev, 0);
469	if (irq < 0) {
470		dev_err(dev, "platform_get_irq failed:%d\n", irq);
471		return irq;
472	}
473	spin_lock_init(&bdc->lock);
474	platform_set_drvdata(pdev, bdc);
475	bdc->irq = irq;
476	bdc->dev = dev;
477	dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq);
478
479	temp = bdc_readl(bdc->regs, BDC_BDCSC);
480	if ((temp & BDC_P64) &&
481			!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
482		dev_dbg(bdc->dev, "Using 64-bit address\n");
483	} else {
484		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
485		if (ret) {
486			dev_err(bdc->dev, "No suitable DMA config available, abort\n");
487			return -ENOTSUPP;
488		}
489		dev_dbg(bdc->dev, "Using 32-bit address\n");
490	}
491	ret = bdc_hw_init(bdc);
492	if (ret) {
493		dev_err(bdc->dev, "BDC init failure:%d\n", ret);
494		return ret;
495	}
496	ret = bdc_udc_init(bdc);
497	if (ret) {
498		dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret);
499		goto cleanup;
500	}
501	return 0;
502
503cleanup:
504	bdc_hw_exit(bdc);
505
506	return ret;
507}
508
509static int bdc_remove(struct platform_device *pdev)
510{
511	struct bdc *bdc;
512
513	bdc  = platform_get_drvdata(pdev);
514	dev_dbg(bdc->dev, "%s ()\n", __func__);
515	bdc_udc_exit(bdc);
516	bdc_hw_exit(bdc);
517
518	return 0;
519}
520
521static struct platform_driver bdc_driver = {
522	.driver		= {
523		.name	= BRCM_BDC_NAME,
524	},
525	.probe		= bdc_probe,
526	.remove		= bdc_remove,
527};
528
529module_platform_driver(bdc_driver);
530MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>");
531MODULE_LICENSE("GPL");
532MODULE_DESCRIPTION(BRCM_BDC_DESC);
533