xref: /openbmc/linux/drivers/usb/host/xhci-histb.c (revision f5ad1c74)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * xHCI host controller driver for HiSilicon STB SoCs
4  *
5  * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com
6  *
7  * Authors: Jianguo Sun <sunjianguo1@huawei.com>
8  */
9 
10 #include <linux/clk.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/reset.h>
18 
19 #include "xhci.h"
20 
21 #define GTXTHRCFG		0xc108
22 #define GRXTHRCFG		0xc10c
23 #define REG_GUSB2PHYCFG0	0xc200
24 #define BIT_UTMI_8_16		BIT(3)
25 #define BIT_UTMI_ULPI		BIT(4)
26 #define BIT_FREECLK_EXIST	BIT(30)
27 
28 #define REG_GUSB3PIPECTL0	0xc2c0
29 #define USB3_DEEMPHASIS_MASK	GENMASK(2, 1)
30 #define USB3_DEEMPHASIS0	BIT(1)
31 #define USB3_TX_MARGIN1		BIT(4)
32 
33 struct xhci_hcd_histb {
34 	struct device		*dev;
35 	struct usb_hcd		*hcd;
36 	void __iomem		*ctrl;
37 	struct clk		*bus_clk;
38 	struct clk		*utmi_clk;
39 	struct clk		*pipe_clk;
40 	struct clk		*suspend_clk;
41 	struct reset_control	*soft_reset;
42 };
43 
44 static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd)
45 {
46 	return dev_get_drvdata(hcd->self.controller);
47 }
48 
49 static int xhci_histb_config(struct xhci_hcd_histb *histb)
50 {
51 	struct device_node *np = histb->dev->of_node;
52 	u32 regval;
53 
54 	if (of_property_match_string(np, "phys-names", "inno") >= 0) {
55 		/* USB2 PHY chose ulpi 8bit interface */
56 		regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
57 		regval &= ~BIT_UTMI_ULPI;
58 		regval &= ~(BIT_UTMI_8_16);
59 		regval &= ~BIT_FREECLK_EXIST;
60 		writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
61 	}
62 
63 	if (of_property_match_string(np, "phys-names", "combo") >= 0) {
64 		/*
65 		 * write 0x010c0012 to GUSB3PIPECTL0
66 		 * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
67 		 * decrease TX voltage
68 		 * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
69 		 * refer to xHCI spec
70 		 */
71 		regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
72 		regval &= ~USB3_DEEMPHASIS_MASK;
73 		regval |= USB3_DEEMPHASIS0;
74 		regval |= USB3_TX_MARGIN1;
75 		writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
76 	}
77 
78 	writel(0x23100000, histb->ctrl + GTXTHRCFG);
79 	writel(0x23100000, histb->ctrl + GRXTHRCFG);
80 
81 	return 0;
82 }
83 
84 static int xhci_histb_clks_get(struct xhci_hcd_histb *histb)
85 {
86 	struct device *dev = histb->dev;
87 
88 	histb->bus_clk = devm_clk_get(dev, "bus");
89 	if (IS_ERR(histb->bus_clk)) {
90 		dev_err(dev, "fail to get bus clk\n");
91 		return PTR_ERR(histb->bus_clk);
92 	}
93 
94 	histb->utmi_clk = devm_clk_get(dev, "utmi");
95 	if (IS_ERR(histb->utmi_clk)) {
96 		dev_err(dev, "fail to get utmi clk\n");
97 		return PTR_ERR(histb->utmi_clk);
98 	}
99 
100 	histb->pipe_clk = devm_clk_get(dev, "pipe");
101 	if (IS_ERR(histb->pipe_clk)) {
102 		dev_err(dev, "fail to get pipe clk\n");
103 		return PTR_ERR(histb->pipe_clk);
104 	}
105 
106 	histb->suspend_clk = devm_clk_get(dev, "suspend");
107 	if (IS_ERR(histb->suspend_clk)) {
108 		dev_err(dev, "fail to get suspend clk\n");
109 		return PTR_ERR(histb->suspend_clk);
110 	}
111 
112 	return 0;
113 }
114 
115 static int xhci_histb_host_enable(struct xhci_hcd_histb *histb)
116 {
117 	int ret;
118 
119 	ret = clk_prepare_enable(histb->bus_clk);
120 	if (ret) {
121 		dev_err(histb->dev, "failed to enable bus clk\n");
122 		return ret;
123 	}
124 
125 	ret = clk_prepare_enable(histb->utmi_clk);
126 	if (ret) {
127 		dev_err(histb->dev, "failed to enable utmi clk\n");
128 		goto err_utmi_clk;
129 	}
130 
131 	ret = clk_prepare_enable(histb->pipe_clk);
132 	if (ret) {
133 		dev_err(histb->dev, "failed to enable pipe clk\n");
134 		goto err_pipe_clk;
135 	}
136 
137 	ret = clk_prepare_enable(histb->suspend_clk);
138 	if (ret) {
139 		dev_err(histb->dev, "failed to enable suspend clk\n");
140 		goto err_suspend_clk;
141 	}
142 
143 	reset_control_deassert(histb->soft_reset);
144 
145 	return 0;
146 
147 err_suspend_clk:
148 	clk_disable_unprepare(histb->pipe_clk);
149 err_pipe_clk:
150 	clk_disable_unprepare(histb->utmi_clk);
151 err_utmi_clk:
152 	clk_disable_unprepare(histb->bus_clk);
153 
154 	return ret;
155 }
156 
157 static void xhci_histb_host_disable(struct xhci_hcd_histb *histb)
158 {
159 	reset_control_assert(histb->soft_reset);
160 
161 	clk_disable_unprepare(histb->suspend_clk);
162 	clk_disable_unprepare(histb->pipe_clk);
163 	clk_disable_unprepare(histb->utmi_clk);
164 	clk_disable_unprepare(histb->bus_clk);
165 }
166 
167 static void xhci_histb_quirks(struct device *dev, struct xhci_hcd *xhci)
168 {
169 	/*
170 	 * As of now platform drivers don't provide MSI support so we ensure
171 	 * here that the generic code does not try to make a pci_dev from our
172 	 * dev struct in order to setup MSI
173 	 */
174 	xhci->quirks |= XHCI_PLAT;
175 }
176 
177 /* called during probe() after chip reset completes */
178 static int xhci_histb_setup(struct usb_hcd *hcd)
179 {
180 	struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
181 	int ret;
182 
183 	if (usb_hcd_is_primary_hcd(hcd)) {
184 		ret = xhci_histb_config(histb);
185 		if (ret)
186 			return ret;
187 	}
188 
189 	return xhci_gen_setup(hcd, xhci_histb_quirks);
190 }
191 
192 static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
193 	.reset = xhci_histb_setup,
194 };
195 
196 static struct hc_driver __read_mostly xhci_histb_hc_driver;
197 static int xhci_histb_probe(struct platform_device *pdev)
198 {
199 	struct device *dev = &pdev->dev;
200 	struct xhci_hcd_histb *histb;
201 	const struct hc_driver *driver;
202 	struct usb_hcd *hcd;
203 	struct xhci_hcd *xhci;
204 	struct resource *res;
205 	int irq;
206 	int ret = -ENODEV;
207 
208 	if (usb_disabled())
209 		return -ENODEV;
210 
211 	driver = &xhci_histb_hc_driver;
212 	histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
213 	if (!histb)
214 		return -ENOMEM;
215 
216 	histb->dev = dev;
217 
218 	irq = platform_get_irq(pdev, 0);
219 	if (irq < 0)
220 		return irq;
221 
222 	histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
223 	if (IS_ERR(histb->ctrl))
224 		return PTR_ERR(histb->ctrl);
225 
226 	ret = xhci_histb_clks_get(histb);
227 	if (ret)
228 		return ret;
229 
230 	histb->soft_reset = devm_reset_control_get(dev, "soft");
231 	if (IS_ERR(histb->soft_reset)) {
232 		dev_err(dev, "failed to get soft reset\n");
233 		return PTR_ERR(histb->soft_reset);
234 	}
235 
236 	pm_runtime_enable(dev);
237 	pm_runtime_get_sync(dev);
238 	device_enable_async_suspend(dev);
239 
240 	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
241 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
242 	if (ret)
243 		goto disable_pm;
244 
245 	hcd = usb_create_hcd(driver, dev, dev_name(dev));
246 	if (!hcd) {
247 		ret = -ENOMEM;
248 		goto disable_pm;
249 	}
250 
251 	hcd->regs = histb->ctrl;
252 	hcd->rsrc_start = res->start;
253 	hcd->rsrc_len = resource_size(res);
254 
255 	histb->hcd = hcd;
256 	dev_set_drvdata(hcd->self.controller, histb);
257 
258 	ret = xhci_histb_host_enable(histb);
259 	if (ret)
260 		goto put_hcd;
261 
262 	xhci = hcd_to_xhci(hcd);
263 
264 	device_wakeup_enable(hcd->self.controller);
265 
266 	xhci->main_hcd = hcd;
267 	xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
268 						 hcd);
269 	if (!xhci->shared_hcd) {
270 		ret = -ENOMEM;
271 		goto disable_host;
272 	}
273 
274 	if (device_property_read_bool(dev, "usb2-lpm-disable"))
275 		xhci->quirks |= XHCI_HW_LPM_DISABLE;
276 
277 	if (device_property_read_bool(dev, "usb3-lpm-capable"))
278 		xhci->quirks |= XHCI_LPM_SUPPORT;
279 
280 	/* imod_interval is the interrupt moderation value in nanoseconds. */
281 	xhci->imod_interval = 40000;
282 	device_property_read_u32(dev, "imod-interval-ns",
283 				 &xhci->imod_interval);
284 
285 	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
286 	if (ret)
287 		goto put_usb3_hcd;
288 
289 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
290 		xhci->shared_hcd->can_do_streams = 1;
291 
292 	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
293 	if (ret)
294 		goto dealloc_usb2_hcd;
295 
296 	device_enable_async_suspend(dev);
297 	pm_runtime_put_noidle(dev);
298 
299 	/*
300 	 * Prevent runtime pm from being on as default, users should enable
301 	 * runtime pm using power/control in sysfs.
302 	 */
303 	pm_runtime_forbid(dev);
304 
305 	return 0;
306 
307 dealloc_usb2_hcd:
308 	usb_remove_hcd(hcd);
309 put_usb3_hcd:
310 	usb_put_hcd(xhci->shared_hcd);
311 disable_host:
312 	xhci_histb_host_disable(histb);
313 put_hcd:
314 	usb_put_hcd(hcd);
315 disable_pm:
316 	pm_runtime_put_sync(dev);
317 	pm_runtime_disable(dev);
318 
319 	return ret;
320 }
321 
322 static int xhci_histb_remove(struct platform_device *dev)
323 {
324 	struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
325 	struct usb_hcd *hcd = histb->hcd;
326 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
327 	struct usb_hcd *shared_hcd = xhci->shared_hcd;
328 
329 	xhci->xhc_state |= XHCI_STATE_REMOVING;
330 
331 	usb_remove_hcd(shared_hcd);
332 	xhci->shared_hcd = NULL;
333 	device_wakeup_disable(&dev->dev);
334 
335 	usb_remove_hcd(hcd);
336 	usb_put_hcd(shared_hcd);
337 
338 	xhci_histb_host_disable(histb);
339 	usb_put_hcd(hcd);
340 	pm_runtime_put_sync(&dev->dev);
341 	pm_runtime_disable(&dev->dev);
342 
343 	return 0;
344 }
345 
346 static int __maybe_unused xhci_histb_suspend(struct device *dev)
347 {
348 	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
349 	struct usb_hcd *hcd = histb->hcd;
350 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
351 	int ret;
352 
353 	ret = xhci_suspend(xhci, device_may_wakeup(dev));
354 
355 	if (!device_may_wakeup(dev))
356 		xhci_histb_host_disable(histb);
357 
358 	return ret;
359 }
360 
361 static int __maybe_unused xhci_histb_resume(struct device *dev)
362 {
363 	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
364 	struct usb_hcd *hcd = histb->hcd;
365 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
366 
367 	if (!device_may_wakeup(dev))
368 		xhci_histb_host_enable(histb);
369 
370 	return xhci_resume(xhci, 0);
371 }
372 
373 static const struct dev_pm_ops xhci_histb_pm_ops = {
374 	SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
375 };
376 #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
377 
378 #ifdef CONFIG_OF
379 static const struct of_device_id histb_xhci_of_match[] = {
380 	{ .compatible = "hisilicon,hi3798cv200-xhci"},
381 	{ },
382 };
383 MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
384 #endif
385 
386 static struct platform_driver histb_xhci_driver = {
387 	.probe	= xhci_histb_probe,
388 	.remove	= xhci_histb_remove,
389 	.driver	= {
390 		.name = "xhci-histb",
391 		.pm = DEV_PM_OPS,
392 		.of_match_table = of_match_ptr(histb_xhci_of_match),
393 	},
394 };
395 MODULE_ALIAS("platform:xhci-histb");
396 
397 static int __init xhci_histb_init(void)
398 {
399 	xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
400 	return platform_driver_register(&histb_xhci_driver);
401 }
402 module_init(xhci_histb_init);
403 
404 static void __exit xhci_histb_exit(void)
405 {
406 	platform_driver_unregister(&histb_xhci_driver);
407 }
408 module_exit(xhci_histb_exit);
409 
410 MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
411 MODULE_LICENSE("GPL v2");
412