xref: /linux/drivers/usb/cdns3/drd.c (revision f2835adf8afb2cea248dd10d6eb0444c34b3b51b)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Cadence USBSS DRD Driver.
4   *
5   * Copyright (C) 2018-2019 Cadence.
6   * Copyright (C) 2019 Texas Instruments
7   *
8   * Author: Pawel Laszczak <pawell@cadence.com>
9   *         Roger Quadros <rogerq@ti.com>
10   *
11   *
12   */
13  #include <linux/kernel.h>
14  #include <linux/interrupt.h>
15  #include <linux/delay.h>
16  #include <linux/iopoll.h>
17  #include <linux/usb/otg.h>
18  
19  #include "gadget.h"
20  #include "drd.h"
21  #include "core.h"
22  
23  /**
24   * cdns3_set_mode - change mode of OTG Core
25   * @cdns: pointer to context structure
26   * @mode: selected mode from cdns_role
27   *
28   * Returns 0 on success otherwise negative errno
29   */
30  int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
31  {
32  	int ret = 0;
33  	u32 reg;
34  
35  	switch (mode) {
36  	case USB_DR_MODE_PERIPHERAL:
37  		break;
38  	case USB_DR_MODE_HOST:
39  		break;
40  	case USB_DR_MODE_OTG:
41  		dev_dbg(cdns->dev, "Set controller to OTG mode\n");
42  		if (cdns->version == CDNS3_CONTROLLER_V1) {
43  			reg = readl(&cdns->otg_v1_regs->override);
44  			reg |= OVERRIDE_IDPULLUP;
45  			writel(reg, &cdns->otg_v1_regs->override);
46  		} else {
47  			reg = readl(&cdns->otg_v0_regs->ctrl1);
48  			reg |= OVERRIDE_IDPULLUP_V0;
49  			writel(reg, &cdns->otg_v0_regs->ctrl1);
50  		}
51  
52  		/*
53  		 * Hardware specification says: "ID_VALUE must be valid within
54  		 * 50ms after idpullup is set to '1" so driver must wait
55  		 * 50ms before reading this pin.
56  		 */
57  		usleep_range(50000, 60000);
58  		break;
59  	default:
60  		dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode);
61  		return -EINVAL;
62  	}
63  
64  	return ret;
65  }
66  
67  int cdns3_get_id(struct cdns3 *cdns)
68  {
69  	int id;
70  
71  	id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE;
72  	dev_dbg(cdns->dev, "OTG ID: %d", id);
73  
74  	return id;
75  }
76  
77  int cdns3_get_vbus(struct cdns3 *cdns)
78  {
79  	int vbus;
80  
81  	vbus = !!(readl(&cdns->otg_regs->sts) & OTGSTS_VBUS_VALID);
82  	dev_dbg(cdns->dev, "OTG VBUS: %d", vbus);
83  
84  	return vbus;
85  }
86  
87  int cdns3_is_host(struct cdns3 *cdns)
88  {
89  	if (cdns->dr_mode == USB_DR_MODE_HOST)
90  		return 1;
91  	else if (!cdns3_get_id(cdns))
92  		return 1;
93  
94  	return 0;
95  }
96  
97  int cdns3_is_device(struct cdns3 *cdns)
98  {
99  	if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
100  		return 1;
101  	else if (cdns->dr_mode == USB_DR_MODE_OTG)
102  		if (cdns3_get_id(cdns))
103  			return 1;
104  
105  	return 0;
106  }
107  
108  /**
109   * cdns3_otg_disable_irq - Disable all OTG interrupts
110   * @cdns: Pointer to controller context structure
111   */
112  static void cdns3_otg_disable_irq(struct cdns3 *cdns)
113  {
114  	writel(0, &cdns->otg_regs->ien);
115  }
116  
117  /**
118   * cdns3_otg_enable_irq - enable id and sess_valid interrupts
119   * @cdns: Pointer to controller context structure
120   */
121  static void cdns3_otg_enable_irq(struct cdns3 *cdns)
122  {
123  	writel(OTGIEN_ID_CHANGE_INT | OTGIEN_VBUSVALID_RISE_INT |
124  	       OTGIEN_VBUSVALID_FALL_INT, &cdns->otg_regs->ien);
125  }
126  
127  /**
128   * cdns3_drd_switch_host - start/stop host
129   * @cdns: Pointer to controller context structure
130   * @on: 1 for start, 0 for stop
131   *
132   * Returns 0 on success otherwise negative errno
133   */
134  int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
135  {
136  	int ret, val;
137  	u32 reg = OTGCMD_OTG_DIS;
138  
139  	/* switch OTG core */
140  	if (on) {
141  		writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd);
142  
143  		dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
144  		ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
145  						val & OTGSTS_XHCI_READY,
146  						1, 100000);
147  		if (ret) {
148  			dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
149  			return ret;
150  		}
151  	} else {
152  		writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
153  		       OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
154  		       &cdns->otg_regs->cmd);
155  		/* Waiting till H_IDLE state.*/
156  		readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
157  					  !(val & OTGSTATE_HOST_STATE_MASK),
158  					  1, 2000000);
159  	}
160  
161  	return 0;
162  }
163  
164  /**
165   * cdns3_drd_switch_gadget - start/stop gadget
166   * @cdns: Pointer to controller context structure
167   * @on: 1 for start, 0 for stop
168   *
169   * Returns 0 on success otherwise negative errno
170   */
171  int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
172  {
173  	int ret, val;
174  	u32 reg = OTGCMD_OTG_DIS;
175  
176  	/* switch OTG core */
177  	if (on) {
178  		writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
179  
180  		dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
181  
182  		ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
183  						val & OTGSTS_DEV_READY,
184  						1, 100000);
185  		if (ret) {
186  			dev_err(cdns->dev, "timeout waiting for dev_ready\n");
187  			return ret;
188  		}
189  	} else {
190  		/*
191  		 * driver should wait at least 10us after disabling Device
192  		 * before turning-off Device (DEV_BUS_DROP)
193  		 */
194  		usleep_range(20, 30);
195  		writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
196  		       OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
197  		       &cdns->otg_regs->cmd);
198  		/* Waiting till DEV_IDLE state.*/
199  		readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
200  					  !(val & OTGSTATE_DEV_STATE_MASK),
201  					  1, 2000000);
202  	}
203  
204  	return 0;
205  }
206  
207  /**
208   * cdns3_init_otg_mode - initialize drd controller
209   * @cdns: Pointer to controller context structure
210   *
211   * Returns 0 on success otherwise negative errno
212   */
213  static int cdns3_init_otg_mode(struct cdns3 *cdns)
214  {
215  	int ret = 0;
216  
217  	cdns3_otg_disable_irq(cdns);
218  	/* clear all interrupts */
219  	writel(~0, &cdns->otg_regs->ivect);
220  
221  	ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG);
222  	if (ret)
223  		return ret;
224  
225  	cdns3_otg_enable_irq(cdns);
226  	return ret;
227  }
228  
229  /**
230   * cdns3_drd_update_mode - initialize mode of operation
231   * @cdns: Pointer to controller context structure
232   *
233   * Returns 0 on success otherwise negative errno
234   */
235  int cdns3_drd_update_mode(struct cdns3 *cdns)
236  {
237  	int ret = 0;
238  
239  	switch (cdns->dr_mode) {
240  	case USB_DR_MODE_PERIPHERAL:
241  		ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
242  		break;
243  	case USB_DR_MODE_HOST:
244  		ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST);
245  		break;
246  	case USB_DR_MODE_OTG:
247  		ret = cdns3_init_otg_mode(cdns);
248  		break;
249  	default:
250  		dev_err(cdns->dev, "Unsupported mode of operation %d\n",
251  			cdns->dr_mode);
252  		return -EINVAL;
253  	}
254  
255  	return ret;
256  }
257  
258  static irqreturn_t cdns3_drd_thread_irq(int irq, void *data)
259  {
260  	struct cdns3 *cdns = data;
261  
262  	cdns3_hw_role_switch(cdns);
263  
264  	return IRQ_HANDLED;
265  }
266  
267  /**
268   * cdns3_drd_irq - interrupt handler for OTG events
269   *
270   * @irq: irq number for cdns3 core device
271   * @data: structure of cdns3
272   *
273   * Returns IRQ_HANDLED or IRQ_NONE
274   */
275  static irqreturn_t cdns3_drd_irq(int irq, void *data)
276  {
277  	irqreturn_t ret = IRQ_NONE;
278  	struct cdns3 *cdns = data;
279  	u32 reg;
280  
281  	if (cdns->dr_mode != USB_DR_MODE_OTG)
282  		return ret;
283  
284  	reg = readl(&cdns->otg_regs->ivect);
285  
286  	if (!reg)
287  		return ret;
288  
289  	if (reg & OTGIEN_ID_CHANGE_INT) {
290  		dev_dbg(cdns->dev, "OTG IRQ: new ID: %d\n",
291  			cdns3_get_id(cdns));
292  
293  		ret = IRQ_WAKE_THREAD;
294  	}
295  
296  	if (reg & (OTGIEN_VBUSVALID_RISE_INT | OTGIEN_VBUSVALID_FALL_INT)) {
297  		dev_dbg(cdns->dev, "OTG IRQ: new VBUS: %d\n",
298  			cdns3_get_vbus(cdns));
299  
300  		ret = IRQ_WAKE_THREAD;
301  	}
302  
303  	writel(~0, &cdns->otg_regs->ivect);
304  	return ret;
305  }
306  
307  int cdns3_drd_init(struct cdns3 *cdns)
308  {
309  	void __iomem *regs;
310  	int ret = 0;
311  	u32 state;
312  
313  	regs = devm_ioremap_resource(cdns->dev, &cdns->otg_res);
314  	if (IS_ERR(regs))
315  		return PTR_ERR(regs);
316  
317  	/* Detection of DRD version. Controller has been released
318  	 * in two versions. Both are similar, but they have same changes
319  	 * in register maps.
320  	 * The first register in old version is command register and it's read
321  	 * only, so driver should read 0 from it. On the other hand, in v1
322  	 * the first register contains device ID number which is not set to 0.
323  	 * Driver uses this fact to detect the proper version of
324  	 * controller.
325  	 */
326  	cdns->otg_v0_regs = regs;
327  	if (!readl(&cdns->otg_v0_regs->cmd)) {
328  		cdns->version  = CDNS3_CONTROLLER_V0;
329  		cdns->otg_v1_regs = NULL;
330  		cdns->otg_regs = regs;
331  		writel(1, &cdns->otg_v0_regs->simulate);
332  		dev_info(cdns->dev, "DRD version v0 (%08x)\n",
333  			 readl(&cdns->otg_v0_regs->version));
334  	} else {
335  		cdns->otg_v0_regs = NULL;
336  		cdns->otg_v1_regs = regs;
337  		cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd;
338  		cdns->version  = CDNS3_CONTROLLER_V1;
339  		writel(1, &cdns->otg_v1_regs->simulate);
340  		dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
341  			 readl(&cdns->otg_v1_regs->did),
342  			 readl(&cdns->otg_v1_regs->rid));
343  	}
344  
345  	state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts));
346  
347  	/* Update dr_mode according to STRAP configuration. */
348  	cdns->dr_mode = USB_DR_MODE_OTG;
349  	if (state == OTGSTS_STRAP_HOST) {
350  		dev_dbg(cdns->dev, "Controller strapped to HOST\n");
351  		cdns->dr_mode = USB_DR_MODE_HOST;
352  	} else if (state == OTGSTS_STRAP_GADGET) {
353  		dev_dbg(cdns->dev, "Controller strapped to PERIPHERAL\n");
354  		cdns->dr_mode = USB_DR_MODE_PERIPHERAL;
355  	}
356  
357  	ret = devm_request_threaded_irq(cdns->dev, cdns->otg_irq,
358  					cdns3_drd_irq,
359  					cdns3_drd_thread_irq,
360  					IRQF_SHARED,
361  					dev_name(cdns->dev), cdns);
362  
363  	if (ret) {
364  		dev_err(cdns->dev, "couldn't get otg_irq\n");
365  		return ret;
366  	}
367  
368  	state = readl(&cdns->otg_regs->sts);
369  	if (OTGSTS_OTG_NRDY(state) != 0) {
370  		dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
371  		return -ENODEV;
372  	}
373  
374  	return ret;
375  }
376  
377  int cdns3_drd_exit(struct cdns3 *cdns)
378  {
379  	cdns3_otg_disable_irq(cdns);
380  	return 0;
381  }
382