• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <dm.h>
14 #include <linux/delay.h>
15 #include <linux/iopoll.h>
16 #include <linux/kernel.h>
17 #include <linux/usb/otg.h>
18 
19 #include "gadget.h"
20 #include "drd.h"
21 #include "core.h"
22 
23 #define readl_poll_timeout_atomic readl_poll_timeout
24 #define usleep_range(a, b) udelay((b))
25 /**
26  * cdns3_set_mode - change mode of OTG Core
27  * @cdns: pointer to context structure
28  * @mode: selected mode from cdns_role
29  *
30  * Returns 0 on success otherwise negative errno
31  */
cdns3_set_mode(struct cdns3 * cdns,enum usb_dr_mode mode)32 int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode)
33 {
34 	int ret = 0;
35 	u32 reg;
36 
37 	switch (mode) {
38 	case USB_DR_MODE_PERIPHERAL:
39 		break;
40 	case USB_DR_MODE_HOST:
41 		break;
42 	case USB_DR_MODE_OTG:
43 		dev_dbg(cdns->dev, "Set controller to OTG mode\n");
44 		if (cdns->version == CDNS3_CONTROLLER_V1) {
45 			reg = readl(&cdns->otg_v1_regs->override);
46 			reg |= OVERRIDE_IDPULLUP;
47 			writel(reg, &cdns->otg_v1_regs->override);
48 		} else {
49 			reg = readl(&cdns->otg_v0_regs->ctrl1);
50 			reg |= OVERRIDE_IDPULLUP_V0;
51 			writel(reg, &cdns->otg_v0_regs->ctrl1);
52 		}
53 
54 		/*
55 		 * Hardware specification says: "ID_VALUE must be valid within
56 		 * 50ms after idpullup is set to '1" so driver must wait
57 		 * 50ms before reading this pin.
58 		 */
59 		usleep_range(50000, 60000);
60 		break;
61 	default:
62 		dev_err(cdns->dev, "Unsupported mode of operation %d\n", mode);
63 		return -EINVAL;
64 	}
65 
66 	return ret;
67 }
68 
cdns3_get_id(struct cdns3 * cdns)69 int cdns3_get_id(struct cdns3 *cdns)
70 {
71 	int id;
72 
73 	id = readl(&cdns->otg_regs->sts) & OTGSTS_ID_VALUE;
74 	dev_dbg(cdns->dev, "OTG ID: %d", id);
75 
76 	return id;
77 }
78 
cdns3_get_vbus(struct cdns3 * cdns)79 int cdns3_get_vbus(struct cdns3 *cdns)
80 {
81 	int vbus;
82 
83 	vbus = !!(readl(&cdns->otg_regs->sts) & OTGSTS_VBUS_VALID);
84 	dev_dbg(cdns->dev, "OTG VBUS: %d", vbus);
85 
86 	return vbus;
87 }
88 
cdns3_is_host(struct cdns3 * cdns)89 int cdns3_is_host(struct cdns3 *cdns)
90 {
91 	if (cdns->dr_mode == USB_DR_MODE_HOST)
92 		return 1;
93 	else if (!cdns3_get_id(cdns))
94 		return 1;
95 
96 	return 0;
97 }
98 
cdns3_is_device(struct cdns3 * cdns)99 int cdns3_is_device(struct cdns3 *cdns)
100 {
101 	if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL)
102 		return 1;
103 	else if (cdns->dr_mode == USB_DR_MODE_OTG)
104 		if (cdns3_get_id(cdns))
105 			return 1;
106 
107 	return 0;
108 }
109 
110 /**
111  * cdns3_drd_switch_host - start/stop host
112  * @cdns: Pointer to controller context structure
113  * @on: 1 for start, 0 for stop
114  *
115  * Returns 0 on success otherwise negative errno
116  */
cdns3_drd_switch_host(struct cdns3 * cdns,int on)117 int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
118 {
119 	int ret, val;
120 	u32 reg = OTGCMD_OTG_DIS;
121 
122 	/* switch OTG core */
123 	if (on) {
124 		writel(OTGCMD_HOST_BUS_REQ | reg, &cdns->otg_regs->cmd);
125 
126 		dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
127 		ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
128 						val & OTGSTS_XHCI_READY,
129 						100000);
130 		if (ret) {
131 			dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
132 			return ret;
133 		}
134 	} else {
135 		writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
136 		       OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
137 		       &cdns->otg_regs->cmd);
138 		/* Waiting till H_IDLE state.*/
139 		readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
140 					  !(val & OTGSTATE_HOST_STATE_MASK),
141 					  2000000);
142 	}
143 
144 	return 0;
145 }
146 
147 /**
148  * cdns3_drd_switch_gadget - start/stop gadget
149  * @cdns: Pointer to controller context structure
150  * @on: 1 for start, 0 for stop
151  *
152  * Returns 0 on success otherwise negative errno
153  */
cdns3_drd_switch_gadget(struct cdns3 * cdns,int on)154 int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
155 {
156 	int ret, val;
157 	u32 reg = OTGCMD_OTG_DIS;
158 
159 	/* switch OTG core */
160 	if (on) {
161 		writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
162 
163 		dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
164 
165 		ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
166 						val & OTGSTS_DEV_READY,
167 						100000);
168 		if (ret) {
169 			dev_err(cdns->dev, "timeout waiting for dev_ready\n");
170 			return ret;
171 		}
172 	} else {
173 		/*
174 		 * driver should wait at least 10us after disabling Device
175 		 * before turning-off Device (DEV_BUS_DROP)
176 		 */
177 		usleep_range(20, 30);
178 		writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
179 		       OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
180 		       &cdns->otg_regs->cmd);
181 		/* Waiting till DEV_IDLE state.*/
182 		readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
183 					  !(val & OTGSTATE_DEV_STATE_MASK),
184 					  2000000);
185 	}
186 
187 	return 0;
188 }
189 
190 /**
191  * cdns3_init_otg_mode - initialize drd controller
192  * @cdns: Pointer to controller context structure
193  *
194  * Returns 0 on success otherwise negative errno
195  */
cdns3_init_otg_mode(struct cdns3 * cdns)196 static int cdns3_init_otg_mode(struct cdns3 *cdns)
197 {
198 	int ret = 0;
199 
200 	/* clear all interrupts */
201 	writel(~0, &cdns->otg_regs->ivect);
202 
203 	ret = cdns3_set_mode(cdns, USB_DR_MODE_OTG);
204 	if (ret)
205 		return ret;
206 
207 	return ret;
208 }
209 
210 /**
211  * cdns3_drd_update_mode - initialize mode of operation
212  * @cdns: Pointer to controller context structure
213  *
214  * Returns 0 on success otherwise negative errno
215  */
cdns3_drd_update_mode(struct cdns3 * cdns)216 int cdns3_drd_update_mode(struct cdns3 *cdns)
217 {
218 	int ret = 0;
219 
220 	switch (cdns->dr_mode) {
221 	case USB_DR_MODE_PERIPHERAL:
222 		ret = cdns3_set_mode(cdns, USB_DR_MODE_PERIPHERAL);
223 		break;
224 	case USB_DR_MODE_HOST:
225 		ret = cdns3_set_mode(cdns, USB_DR_MODE_HOST);
226 		break;
227 	case USB_DR_MODE_OTG:
228 		ret = cdns3_init_otg_mode(cdns);
229 		break;
230 	default:
231 		dev_err(cdns->dev, "Unsupported mode of operation %d\n",
232 			cdns->dr_mode);
233 		return -EINVAL;
234 	}
235 
236 	return ret;
237 }
238 
cdns3_drd_init(struct cdns3 * cdns)239 int cdns3_drd_init(struct cdns3 *cdns)
240 {
241 	void __iomem *regs;
242 	int ret = 0;
243 	u32 state;
244 
245 	regs = dev_remap_addr_name(cdns->dev, "otg");
246 	if (!regs)
247 		return -EINVAL;
248 
249 	/* Detection of DRD version. Controller has been released
250 	 * in two versions. Both are similar, but they have same changes
251 	 * in register maps.
252 	 * The first register in old version is command register and it's read
253 	 * only, so driver should read 0 from it. On the other hand, in v1
254 	 * the first register contains device ID number which is not set to 0.
255 	 * Driver uses this fact to detect the proper version of
256 	 * controller.
257 	 */
258 	cdns->otg_v0_regs = regs;
259 	if (!readl(&cdns->otg_v0_regs->cmd)) {
260 		cdns->version  = CDNS3_CONTROLLER_V0;
261 		cdns->otg_v1_regs = NULL;
262 		cdns->otg_regs = regs;
263 		writel(1, &cdns->otg_v0_regs->simulate);
264 		dev_info(cdns->dev, "DRD version v0 (%08x)\n",
265 			 readl(&cdns->otg_v0_regs->version));
266 	} else {
267 		cdns->otg_v0_regs = NULL;
268 		cdns->otg_v1_regs = regs;
269 		cdns->otg_regs = (void *)&cdns->otg_v1_regs->cmd;
270 		cdns->version  = CDNS3_CONTROLLER_V1;
271 		writel(1, &cdns->otg_v1_regs->simulate);
272 		dev_info(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
273 			 readl(&cdns->otg_v1_regs->did),
274 			 readl(&cdns->otg_v1_regs->rid));
275 	}
276 
277 	state = OTGSTS_STRAP(readl(&cdns->otg_regs->sts));
278 
279 	/* Update dr_mode according to STRAP configuration. */
280 	cdns->dr_mode = USB_DR_MODE_OTG;
281 	if (state == OTGSTS_STRAP_HOST) {
282 		dev_dbg(cdns->dev, "Controller strapped to HOST\n");
283 		cdns->dr_mode = USB_DR_MODE_HOST;
284 	} else if (state == OTGSTS_STRAP_GADGET) {
285 		dev_dbg(cdns->dev, "Controller strapped to PERIPHERAL\n");
286 		cdns->dr_mode = USB_DR_MODE_PERIPHERAL;
287 	}
288 
289 	state = readl(&cdns->otg_regs->sts);
290 	if (OTGSTS_OTG_NRDY(state) != 0) {
291 		dev_err(cdns->dev, "Cadence USB3 OTG device not ready\n");
292 		return -ENODEV;
293 	}
294 
295 	return ret;
296 }
297 
cdns3_drd_exit(struct cdns3 * cdns)298 int cdns3_drd_exit(struct cdns3 *cdns)
299 {
300 	return 0;
301 }
302