xref: /linux/drivers/usb/host/xhci-histb.c (revision db10cb9b)
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 /* called during probe() after chip reset completes */
168 static int xhci_histb_setup(struct usb_hcd *hcd)
169 {
170 	struct xhci_hcd_histb *histb = hcd_to_histb(hcd);
171 	int ret;
172 
173 	if (usb_hcd_is_primary_hcd(hcd)) {
174 		ret = xhci_histb_config(histb);
175 		if (ret)
176 			return ret;
177 	}
178 
179 	return xhci_gen_setup(hcd, NULL);
180 }
181 
182 static const struct xhci_driver_overrides xhci_histb_overrides __initconst = {
183 	.reset = xhci_histb_setup,
184 };
185 
186 static struct hc_driver __read_mostly xhci_histb_hc_driver;
187 static int xhci_histb_probe(struct platform_device *pdev)
188 {
189 	struct device *dev = &pdev->dev;
190 	struct xhci_hcd_histb *histb;
191 	const struct hc_driver *driver;
192 	struct usb_hcd *hcd;
193 	struct xhci_hcd *xhci;
194 	struct resource *res;
195 	int irq;
196 	int ret = -ENODEV;
197 
198 	if (usb_disabled())
199 		return -ENODEV;
200 
201 	driver = &xhci_histb_hc_driver;
202 	histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL);
203 	if (!histb)
204 		return -ENOMEM;
205 
206 	histb->dev = dev;
207 
208 	irq = platform_get_irq(pdev, 0);
209 	if (irq < 0)
210 		return irq;
211 
212 	histb->ctrl = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
213 	if (IS_ERR(histb->ctrl))
214 		return PTR_ERR(histb->ctrl);
215 
216 	ret = xhci_histb_clks_get(histb);
217 	if (ret)
218 		return ret;
219 
220 	histb->soft_reset = devm_reset_control_get(dev, "soft");
221 	if (IS_ERR(histb->soft_reset)) {
222 		dev_err(dev, "failed to get soft reset\n");
223 		return PTR_ERR(histb->soft_reset);
224 	}
225 
226 	pm_runtime_enable(dev);
227 	pm_runtime_get_sync(dev);
228 	device_enable_async_suspend(dev);
229 
230 	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
231 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
232 	if (ret)
233 		goto disable_pm;
234 
235 	hcd = usb_create_hcd(driver, dev, dev_name(dev));
236 	if (!hcd) {
237 		ret = -ENOMEM;
238 		goto disable_pm;
239 	}
240 
241 	hcd->regs = histb->ctrl;
242 	hcd->rsrc_start = res->start;
243 	hcd->rsrc_len = resource_size(res);
244 
245 	histb->hcd = hcd;
246 	dev_set_drvdata(hcd->self.controller, histb);
247 
248 	ret = xhci_histb_host_enable(histb);
249 	if (ret)
250 		goto put_hcd;
251 
252 	xhci = hcd_to_xhci(hcd);
253 
254 	device_wakeup_enable(hcd->self.controller);
255 
256 	xhci->main_hcd = hcd;
257 	xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev),
258 						 hcd);
259 	if (!xhci->shared_hcd) {
260 		ret = -ENOMEM;
261 		goto disable_host;
262 	}
263 
264 	if (device_property_read_bool(dev, "usb2-lpm-disable"))
265 		xhci->quirks |= XHCI_HW_LPM_DISABLE;
266 
267 	if (device_property_read_bool(dev, "usb3-lpm-capable"))
268 		xhci->quirks |= XHCI_LPM_SUPPORT;
269 
270 	/* imod_interval is the interrupt moderation value in nanoseconds. */
271 	xhci->imod_interval = 40000;
272 	device_property_read_u32(dev, "imod-interval-ns",
273 				 &xhci->imod_interval);
274 
275 	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
276 	if (ret)
277 		goto put_usb3_hcd;
278 
279 	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
280 		xhci->shared_hcd->can_do_streams = 1;
281 
282 	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
283 	if (ret)
284 		goto dealloc_usb2_hcd;
285 
286 	device_enable_async_suspend(dev);
287 	pm_runtime_put_noidle(dev);
288 
289 	/*
290 	 * Prevent runtime pm from being on as default, users should enable
291 	 * runtime pm using power/control in sysfs.
292 	 */
293 	pm_runtime_forbid(dev);
294 
295 	return 0;
296 
297 dealloc_usb2_hcd:
298 	usb_remove_hcd(hcd);
299 put_usb3_hcd:
300 	usb_put_hcd(xhci->shared_hcd);
301 disable_host:
302 	xhci_histb_host_disable(histb);
303 put_hcd:
304 	usb_put_hcd(hcd);
305 disable_pm:
306 	pm_runtime_put_sync(dev);
307 	pm_runtime_disable(dev);
308 
309 	return ret;
310 }
311 
312 static void xhci_histb_remove(struct platform_device *dev)
313 {
314 	struct xhci_hcd_histb *histb = platform_get_drvdata(dev);
315 	struct usb_hcd *hcd = histb->hcd;
316 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
317 	struct usb_hcd *shared_hcd = xhci->shared_hcd;
318 
319 	xhci->xhc_state |= XHCI_STATE_REMOVING;
320 
321 	usb_remove_hcd(shared_hcd);
322 	xhci->shared_hcd = NULL;
323 	device_wakeup_disable(&dev->dev);
324 
325 	usb_remove_hcd(hcd);
326 	usb_put_hcd(shared_hcd);
327 
328 	xhci_histb_host_disable(histb);
329 	usb_put_hcd(hcd);
330 	pm_runtime_put_sync(&dev->dev);
331 	pm_runtime_disable(&dev->dev);
332 }
333 
334 static int __maybe_unused xhci_histb_suspend(struct device *dev)
335 {
336 	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
337 	struct usb_hcd *hcd = histb->hcd;
338 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
339 	int ret;
340 
341 	ret = xhci_suspend(xhci, device_may_wakeup(dev));
342 
343 	if (!device_may_wakeup(dev))
344 		xhci_histb_host_disable(histb);
345 
346 	return ret;
347 }
348 
349 static int __maybe_unused xhci_histb_resume(struct device *dev)
350 {
351 	struct xhci_hcd_histb *histb = dev_get_drvdata(dev);
352 	struct usb_hcd *hcd = histb->hcd;
353 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
354 
355 	if (!device_may_wakeup(dev))
356 		xhci_histb_host_enable(histb);
357 
358 	return xhci_resume(xhci, PMSG_RESUME);
359 }
360 
361 static const struct dev_pm_ops xhci_histb_pm_ops = {
362 	SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume)
363 };
364 #define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL)
365 
366 #ifdef CONFIG_OF
367 static const struct of_device_id histb_xhci_of_match[] = {
368 	{ .compatible = "hisilicon,hi3798cv200-xhci"},
369 	{ },
370 };
371 MODULE_DEVICE_TABLE(of, histb_xhci_of_match);
372 #endif
373 
374 static struct platform_driver histb_xhci_driver = {
375 	.probe	= xhci_histb_probe,
376 	.remove_new = xhci_histb_remove,
377 	.driver	= {
378 		.name = "xhci-histb",
379 		.pm = DEV_PM_OPS,
380 		.of_match_table = of_match_ptr(histb_xhci_of_match),
381 	},
382 };
383 MODULE_ALIAS("platform:xhci-histb");
384 
385 static int __init xhci_histb_init(void)
386 {
387 	xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides);
388 	return platform_driver_register(&histb_xhci_driver);
389 }
390 module_init(xhci_histb_init);
391 
392 static void __exit xhci_histb_exit(void)
393 {
394 	platform_driver_unregister(&histb_xhci_driver);
395 }
396 module_exit(xhci_histb_exit);
397 
398 MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver");
399 MODULE_LICENSE("GPL v2");
400