xref: /linux/drivers/usb/dwc3/dwc3-pci.c (revision bcb63314e2c23f1ed622418b65f9409512659c73)
1 /**
2  * dwc3-pci.c - PCI Specific glue layer
3  *
4  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5  *
6  * Authors: Felipe Balbi <balbi@ti.com>,
7  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2  of
11  * the License as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18 
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/pci.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/platform_device.h>
25 #include <linux/gpio/consumer.h>
26 #include <linux/acpi.h>
27 #include <linux/delay.h>
28 
29 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3		0xabcd
30 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI	0xabce
31 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31	0xabcf
32 #define PCI_DEVICE_ID_INTEL_BYT			0x0f37
33 #define PCI_DEVICE_ID_INTEL_MRFLD		0x119e
34 #define PCI_DEVICE_ID_INTEL_BSW			0x22b7
35 #define PCI_DEVICE_ID_INTEL_SPTLP		0x9d30
36 #define PCI_DEVICE_ID_INTEL_SPTH		0xa130
37 #define PCI_DEVICE_ID_INTEL_BXT			0x0aaa
38 #define PCI_DEVICE_ID_INTEL_BXT_M		0x1aaa
39 #define PCI_DEVICE_ID_INTEL_APL			0x5aaa
40 #define PCI_DEVICE_ID_INTEL_KBP			0xa2b0
41 
42 #define PCI_INTEL_BXT_DSM_UUID		"732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
43 #define PCI_INTEL_BXT_FUNC_PMU_PWR	4
44 #define PCI_INTEL_BXT_STATE_D0		0
45 #define PCI_INTEL_BXT_STATE_D3		3
46 
47 /**
48  * struct dwc3_pci - Driver private structure
49  * @dwc3: child dwc3 platform_device
50  * @pci: our link to PCI bus
51  * @uuid: _DSM UUID
52  * @has_dsm_for_pm: true for devices which need to run _DSM on runtime PM
53  */
54 struct dwc3_pci {
55 	struct platform_device *dwc3;
56 	struct pci_dev *pci;
57 
58 	u8 uuid[16];
59 
60 	unsigned int has_dsm_for_pm:1;
61 };
62 
63 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
64 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
65 
66 static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
67 	{ "reset-gpios", &reset_gpios, 1 },
68 	{ "cs-gpios", &cs_gpios, 1 },
69 	{ },
70 };
71 
72 static int dwc3_pci_quirks(struct dwc3_pci *dwc)
73 {
74 	struct platform_device		*dwc3 = dwc->dwc3;
75 	struct pci_dev			*pdev = dwc->pci;
76 	int				ret;
77 
78 	struct property_entry sysdev_property[] = {
79 		PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
80 		{ },
81 	};
82 
83 	ret = platform_device_add_properties(dwc3, sysdev_property);
84 	if (ret)
85 		return ret;
86 
87 	if (pdev->vendor == PCI_VENDOR_ID_AMD &&
88 	    pdev->device == PCI_DEVICE_ID_AMD_NL_USB) {
89 		struct property_entry properties[] = {
90 			PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"),
91 			PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf),
92 			PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"),
93 			PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"),
94 			PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"),
95 			PROPERTY_ENTRY_BOOL("snps,del_p1p2p3_quirk"),
96 			PROPERTY_ENTRY_BOOL("snps,del_phy_power_chg_quirk"),
97 			PROPERTY_ENTRY_BOOL("snps,lfps_filter_quirk"),
98 			PROPERTY_ENTRY_BOOL("snps,rx_detect_poll_quirk"),
99 			PROPERTY_ENTRY_BOOL("snps,tx_de_emphasis_quirk"),
100 			PROPERTY_ENTRY_U8("snps,tx_de_emphasis", 1),
101 			/*
102 			 * FIXME these quirks should be removed when AMD NL
103 			 * tapes out
104 			 */
105 			PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"),
106 			PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
107 			PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
108 			{ },
109 		};
110 
111 		return platform_device_add_properties(dwc3, properties);
112 	}
113 
114 	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
115 		int ret;
116 
117 		struct property_entry properties[] = {
118 			PROPERTY_ENTRY_STRING("dr-mode", "peripheral"),
119 			{ }
120 		};
121 
122 		ret = platform_device_add_properties(dwc3, properties);
123 		if (ret < 0)
124 			return ret;
125 
126 		if (pdev->device == PCI_DEVICE_ID_INTEL_BXT ||
127 				pdev->device == PCI_DEVICE_ID_INTEL_BXT_M) {
128 			acpi_str_to_uuid(PCI_INTEL_BXT_DSM_UUID, dwc->uuid);
129 			dwc->has_dsm_for_pm = true;
130 		}
131 
132 		if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
133 			struct gpio_desc *gpio;
134 
135 			acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
136 					acpi_dwc3_byt_gpios);
137 
138 			/*
139 			 * These GPIOs will turn on the USB2 PHY. Note that we have to
140 			 * put the gpio descriptors again here because the phy driver
141 			 * might want to grab them, too.
142 			 */
143 			gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW);
144 			if (IS_ERR(gpio))
145 				return PTR_ERR(gpio);
146 
147 			gpiod_set_value_cansleep(gpio, 1);
148 			gpiod_put(gpio);
149 
150 			gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
151 			if (IS_ERR(gpio))
152 				return PTR_ERR(gpio);
153 
154 			if (gpio) {
155 				gpiod_set_value_cansleep(gpio, 1);
156 				gpiod_put(gpio);
157 				usleep_range(10000, 11000);
158 			}
159 		}
160 	}
161 
162 	if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
163 	    (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 ||
164 	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI ||
165 	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) {
166 		struct property_entry properties[] = {
167 			PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"),
168 			PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"),
169 			PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"),
170 			{ },
171 		};
172 
173 		return platform_device_add_properties(dwc3, properties);
174 	}
175 
176 	return 0;
177 }
178 
179 static int dwc3_pci_probe(struct pci_dev *pci,
180 		const struct pci_device_id *id)
181 {
182 	struct dwc3_pci		*dwc;
183 	struct resource		res[2];
184 	int			ret;
185 	struct device		*dev = &pci->dev;
186 
187 	ret = pcim_enable_device(pci);
188 	if (ret) {
189 		dev_err(dev, "failed to enable pci device\n");
190 		return -ENODEV;
191 	}
192 
193 	pci_set_master(pci);
194 
195 	dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
196 	if (!dwc)
197 		return -ENOMEM;
198 
199 	dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
200 	if (!dwc->dwc3)
201 		return -ENOMEM;
202 
203 	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
204 
205 	res[0].start	= pci_resource_start(pci, 0);
206 	res[0].end	= pci_resource_end(pci, 0);
207 	res[0].name	= "dwc_usb3";
208 	res[0].flags	= IORESOURCE_MEM;
209 
210 	res[1].start	= pci->irq;
211 	res[1].name	= "dwc_usb3";
212 	res[1].flags	= IORESOURCE_IRQ;
213 
214 	ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res));
215 	if (ret) {
216 		dev_err(dev, "couldn't add resources to dwc3 device\n");
217 		return ret;
218 	}
219 
220 	dwc->pci = pci;
221 	dwc->dwc3->dev.parent = dev;
222 	ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
223 
224 	ret = dwc3_pci_quirks(dwc);
225 	if (ret)
226 		goto err;
227 
228 	ret = platform_device_add(dwc->dwc3);
229 	if (ret) {
230 		dev_err(dev, "failed to register dwc3 device\n");
231 		goto err;
232 	}
233 
234 	device_init_wakeup(dev, true);
235 	device_set_run_wake(dev, true);
236 	pci_set_drvdata(pci, dwc);
237 	pm_runtime_put(dev);
238 
239 	return 0;
240 err:
241 	platform_device_put(dwc->dwc3);
242 	return ret;
243 }
244 
245 static void dwc3_pci_remove(struct pci_dev *pci)
246 {
247 	struct dwc3_pci		*dwc = pci_get_drvdata(pci);
248 
249 	device_init_wakeup(&pci->dev, false);
250 	pm_runtime_get(&pci->dev);
251 	acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev));
252 	platform_device_unregister(dwc->dwc3);
253 }
254 
255 static const struct pci_device_id dwc3_pci_id_table[] = {
256 	{
257 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
258 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
259 	},
260 	{
261 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
262 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI),
263 	},
264 	{
265 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
266 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31),
267 	},
268 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
269 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
270 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
271 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), },
272 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },
273 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), },
274 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), },
275 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
276 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
277 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
278 	{  }	/* Terminating Entry */
279 };
280 MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
281 
282 #if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
283 static int dwc3_pci_dsm(struct dwc3_pci *dwc, int param)
284 {
285 	union acpi_object *obj;
286 	union acpi_object tmp;
287 	union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
288 
289 	if (!dwc->has_dsm_for_pm)
290 		return 0;
291 
292 	tmp.type = ACPI_TYPE_INTEGER;
293 	tmp.integer.value = param;
294 
295 	obj = acpi_evaluate_dsm(ACPI_HANDLE(&dwc->pci->dev), dwc->uuid,
296 			1, PCI_INTEL_BXT_FUNC_PMU_PWR, &argv4);
297 	if (!obj) {
298 		dev_err(&dwc->pci->dev, "failed to evaluate _DSM\n");
299 		return -EIO;
300 	}
301 
302 	ACPI_FREE(obj);
303 
304 	return 0;
305 }
306 #endif /* CONFIG_PM || CONFIG_PM_SLEEP */
307 
308 #ifdef CONFIG_PM
309 static int dwc3_pci_runtime_suspend(struct device *dev)
310 {
311 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
312 
313 	if (device_run_wake(dev))
314 		return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
315 
316 	return -EBUSY;
317 }
318 
319 static int dwc3_pci_runtime_resume(struct device *dev)
320 {
321 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
322 	struct platform_device	*dwc3 = dwc->dwc3;
323 	int			ret;
324 
325 	ret = dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
326 	if (ret)
327 		return ret;
328 
329 	return pm_runtime_get(&dwc3->dev);
330 }
331 #endif /* CONFIG_PM */
332 
333 #ifdef CONFIG_PM_SLEEP
334 static int dwc3_pci_suspend(struct device *dev)
335 {
336 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
337 
338 	return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
339 }
340 
341 static int dwc3_pci_resume(struct device *dev)
342 {
343 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
344 
345 	return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
346 }
347 #endif /* CONFIG_PM_SLEEP */
348 
349 static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
350 	SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume)
351 	SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume,
352 		NULL)
353 };
354 
355 static struct pci_driver dwc3_pci_driver = {
356 	.name		= "dwc3-pci",
357 	.id_table	= dwc3_pci_id_table,
358 	.probe		= dwc3_pci_probe,
359 	.remove		= dwc3_pci_remove,
360 	.driver		= {
361 		.pm	= &dwc3_pci_dev_pm_ops,
362 	}
363 };
364 
365 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
366 MODULE_LICENSE("GPL v2");
367 MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");
368 
369 module_pci_driver(dwc3_pci_driver);
370