1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2009-2018, Linux Foundation. All rights reserved.
4  * Copyright (c) 2018-2020, Linaro Limited
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/io.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_graph.h>
14 #include <linux/phy/phy.h>
15 #include <linux/platform_device.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/reset.h>
18 #include <linux/slab.h>
19 
20 /* PHY register and bit definitions */
21 #define PHY_CTRL_COMMON0		0x078
22 #define SIDDQ				BIT(2)
23 #define PHY_IRQ_CMD			0x0d0
24 #define PHY_INTR_MASK0			0x0d4
25 #define PHY_INTR_CLEAR0			0x0dc
26 #define DPDM_MASK			0x1e
27 #define DP_1_0				BIT(4)
28 #define DP_0_1				BIT(3)
29 #define DM_1_0				BIT(2)
30 #define DM_0_1				BIT(1)
31 
32 enum hsphy_voltage {
33 	VOL_NONE,
34 	VOL_MIN,
35 	VOL_MAX,
36 	VOL_NUM,
37 };
38 
39 enum hsphy_vreg {
40 	VDD,
41 	VDDA_1P8,
42 	VDDA_3P3,
43 	VREG_NUM,
44 };
45 
46 struct hsphy_init_seq {
47 	int offset;
48 	int val;
49 	int delay;
50 };
51 
52 struct hsphy_data {
53 	const struct hsphy_init_seq *init_seq;
54 	unsigned int init_seq_num;
55 };
56 
57 struct hsphy_priv {
58 	void __iomem *base;
59 	struct clk_bulk_data *clks;
60 	int num_clks;
61 	struct reset_control *phy_reset;
62 	struct reset_control *por_reset;
63 	struct regulator_bulk_data vregs[VREG_NUM];
64 	const struct hsphy_data *data;
65 	enum phy_mode mode;
66 };
67 
68 static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode,
69 				    int submode)
70 {
71 	struct hsphy_priv *priv = phy_get_drvdata(phy);
72 
73 	priv->mode = PHY_MODE_INVALID;
74 
75 	if (mode > 0)
76 		priv->mode = mode;
77 
78 	return 0;
79 }
80 
81 static void qcom_snps_hsphy_enable_hv_interrupts(struct hsphy_priv *priv)
82 {
83 	u32 val;
84 
85 	/* Clear any existing interrupts before enabling the interrupts */
86 	val = readb(priv->base + PHY_INTR_CLEAR0);
87 	val |= DPDM_MASK;
88 	writeb(val, priv->base + PHY_INTR_CLEAR0);
89 
90 	writeb(0x0, priv->base + PHY_IRQ_CMD);
91 	usleep_range(200, 220);
92 	writeb(0x1, priv->base + PHY_IRQ_CMD);
93 
94 	/* Make sure the interrupts are cleared */
95 	usleep_range(200, 220);
96 
97 	val = readb(priv->base + PHY_INTR_MASK0);
98 	switch (priv->mode) {
99 	case PHY_MODE_USB_HOST_HS:
100 	case PHY_MODE_USB_HOST_FS:
101 	case PHY_MODE_USB_DEVICE_HS:
102 	case PHY_MODE_USB_DEVICE_FS:
103 		val |= DP_1_0 | DM_0_1;
104 		break;
105 	case PHY_MODE_USB_HOST_LS:
106 	case PHY_MODE_USB_DEVICE_LS:
107 		val |= DP_0_1 | DM_1_0;
108 		break;
109 	default:
110 		/* No device connected */
111 		val |= DP_0_1 | DM_0_1;
112 		break;
113 	}
114 	writeb(val, priv->base + PHY_INTR_MASK0);
115 }
116 
117 static void qcom_snps_hsphy_disable_hv_interrupts(struct hsphy_priv *priv)
118 {
119 	u32 val;
120 
121 	val = readb(priv->base + PHY_INTR_MASK0);
122 	val &= ~DPDM_MASK;
123 	writeb(val, priv->base + PHY_INTR_MASK0);
124 
125 	/* Clear any pending interrupts */
126 	val = readb(priv->base + PHY_INTR_CLEAR0);
127 	val |= DPDM_MASK;
128 	writeb(val, priv->base + PHY_INTR_CLEAR0);
129 
130 	writeb(0x0, priv->base + PHY_IRQ_CMD);
131 	usleep_range(200, 220);
132 
133 	writeb(0x1, priv->base + PHY_IRQ_CMD);
134 	usleep_range(200, 220);
135 }
136 
137 static void qcom_snps_hsphy_enter_retention(struct hsphy_priv *priv)
138 {
139 	u32 val;
140 
141 	val = readb(priv->base + PHY_CTRL_COMMON0);
142 	val |= SIDDQ;
143 	writeb(val, priv->base + PHY_CTRL_COMMON0);
144 }
145 
146 static void qcom_snps_hsphy_exit_retention(struct hsphy_priv *priv)
147 {
148 	u32 val;
149 
150 	val = readb(priv->base + PHY_CTRL_COMMON0);
151 	val &= ~SIDDQ;
152 	writeb(val, priv->base + PHY_CTRL_COMMON0);
153 }
154 
155 static int qcom_snps_hsphy_power_on(struct phy *phy)
156 {
157 	struct hsphy_priv *priv = phy_get_drvdata(phy);
158 	int ret;
159 
160 	ret = regulator_bulk_enable(VREG_NUM, priv->vregs);
161 	if (ret)
162 		return ret;
163 	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
164 	if (ret)
165 		goto err_disable_regulator;
166 	qcom_snps_hsphy_disable_hv_interrupts(priv);
167 	qcom_snps_hsphy_exit_retention(priv);
168 
169 	return 0;
170 
171 err_disable_regulator:
172 	regulator_bulk_disable(VREG_NUM, priv->vregs);
173 
174 	return ret;
175 }
176 
177 static int qcom_snps_hsphy_power_off(struct phy *phy)
178 {
179 	struct hsphy_priv *priv = phy_get_drvdata(phy);
180 
181 	qcom_snps_hsphy_enter_retention(priv);
182 	qcom_snps_hsphy_enable_hv_interrupts(priv);
183 	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
184 	regulator_bulk_disable(VREG_NUM, priv->vregs);
185 
186 	return 0;
187 }
188 
189 static int qcom_snps_hsphy_reset(struct hsphy_priv *priv)
190 {
191 	int ret;
192 
193 	ret = reset_control_assert(priv->phy_reset);
194 	if (ret)
195 		return ret;
196 
197 	usleep_range(10, 15);
198 
199 	ret = reset_control_deassert(priv->phy_reset);
200 	if (ret)
201 		return ret;
202 
203 	usleep_range(80, 100);
204 
205 	return 0;
206 }
207 
208 static void qcom_snps_hsphy_init_sequence(struct hsphy_priv *priv)
209 {
210 	const struct hsphy_data *data = priv->data;
211 	const struct hsphy_init_seq *seq;
212 	int i;
213 
214 	/* Device match data is optional. */
215 	if (!data)
216 		return;
217 
218 	seq = data->init_seq;
219 
220 	for (i = 0; i < data->init_seq_num; i++, seq++) {
221 		writeb(seq->val, priv->base + seq->offset);
222 		if (seq->delay)
223 			usleep_range(seq->delay, seq->delay + 10);
224 	}
225 }
226 
227 static int qcom_snps_hsphy_por_reset(struct hsphy_priv *priv)
228 {
229 	int ret;
230 
231 	ret = reset_control_assert(priv->por_reset);
232 	if (ret)
233 		return ret;
234 
235 	/*
236 	 * The Femto PHY is POR reset in the following scenarios.
237 	 *
238 	 * 1. After overriding the parameter registers.
239 	 * 2. Low power mode exit from PHY retention.
240 	 *
241 	 * Ensure that SIDDQ is cleared before bringing the PHY
242 	 * out of reset.
243 	 */
244 	qcom_snps_hsphy_exit_retention(priv);
245 
246 	/*
247 	 * As per databook, 10 usec delay is required between
248 	 * PHY POR assert and de-assert.
249 	 */
250 	usleep_range(10, 20);
251 	ret = reset_control_deassert(priv->por_reset);
252 	if (ret)
253 		return ret;
254 
255 	/*
256 	 * As per databook, it takes 75 usec for PHY to stabilize
257 	 * after the reset.
258 	 */
259 	usleep_range(80, 100);
260 
261 	return 0;
262 }
263 
264 static int qcom_snps_hsphy_init(struct phy *phy)
265 {
266 	struct hsphy_priv *priv = phy_get_drvdata(phy);
267 	int ret;
268 
269 	ret = qcom_snps_hsphy_reset(priv);
270 	if (ret)
271 		return ret;
272 
273 	qcom_snps_hsphy_init_sequence(priv);
274 
275 	ret = qcom_snps_hsphy_por_reset(priv);
276 	if (ret)
277 		return ret;
278 
279 	return 0;
280 }
281 
282 static const struct phy_ops qcom_snps_hsphy_ops = {
283 	.init = qcom_snps_hsphy_init,
284 	.power_on = qcom_snps_hsphy_power_on,
285 	.power_off = qcom_snps_hsphy_power_off,
286 	.set_mode = qcom_snps_hsphy_set_mode,
287 	.owner = THIS_MODULE,
288 };
289 
290 static const char * const qcom_snps_hsphy_clks[] = {
291 	"ref",
292 	"ahb",
293 	"sleep",
294 };
295 
296 static int qcom_snps_hsphy_probe(struct platform_device *pdev)
297 {
298 	struct device *dev = &pdev->dev;
299 	struct phy_provider *provider;
300 	struct hsphy_priv *priv;
301 	struct phy *phy;
302 	int ret;
303 	int i;
304 
305 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
306 	if (!priv)
307 		return -ENOMEM;
308 
309 	priv->base = devm_platform_ioremap_resource(pdev, 0);
310 	if (IS_ERR(priv->base))
311 		return PTR_ERR(priv->base);
312 
313 	priv->num_clks = ARRAY_SIZE(qcom_snps_hsphy_clks);
314 	priv->clks = devm_kcalloc(dev, priv->num_clks, sizeof(*priv->clks),
315 				  GFP_KERNEL);
316 	if (!priv->clks)
317 		return -ENOMEM;
318 
319 	for (i = 0; i < priv->num_clks; i++)
320 		priv->clks[i].id = qcom_snps_hsphy_clks[i];
321 
322 	ret = devm_clk_bulk_get(dev, priv->num_clks, priv->clks);
323 	if (ret)
324 		return ret;
325 
326 	priv->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
327 	if (IS_ERR(priv->phy_reset))
328 		return PTR_ERR(priv->phy_reset);
329 
330 	priv->por_reset = devm_reset_control_get_exclusive(dev, "por");
331 	if (IS_ERR(priv->por_reset))
332 		return PTR_ERR(priv->por_reset);
333 
334 	priv->vregs[VDD].supply = "vdd";
335 	priv->vregs[VDDA_1P8].supply = "vdda1p8";
336 	priv->vregs[VDDA_3P3].supply = "vdda3p3";
337 
338 	ret = devm_regulator_bulk_get(dev, VREG_NUM, priv->vregs);
339 	if (ret)
340 		return ret;
341 
342 	/* Get device match data */
343 	priv->data = device_get_match_data(dev);
344 
345 	phy = devm_phy_create(dev, dev->of_node, &qcom_snps_hsphy_ops);
346 	if (IS_ERR(phy))
347 		return PTR_ERR(phy);
348 
349 	phy_set_drvdata(phy, priv);
350 
351 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
352 	if (IS_ERR(provider))
353 		return PTR_ERR(provider);
354 
355 	ret = regulator_set_load(priv->vregs[VDDA_1P8].consumer, 19000);
356 	if (ret < 0)
357 		return ret;
358 
359 	ret = regulator_set_load(priv->vregs[VDDA_3P3].consumer, 16000);
360 	if (ret < 0)
361 		goto unset_1p8_load;
362 
363 	return 0;
364 
365 unset_1p8_load:
366 	regulator_set_load(priv->vregs[VDDA_1P8].consumer, 0);
367 
368 	return ret;
369 }
370 
371 /*
372  * The macro is used to define an initialization sequence.  Each tuple
373  * is meant to program 'value' into phy register at 'offset' with 'delay'
374  * in us followed.
375  */
376 #define HSPHY_INIT_CFG(o, v, d)	{ .offset = o, .val = v, .delay = d, }
377 
378 static const struct hsphy_init_seq init_seq_femtophy[] = {
379 	HSPHY_INIT_CFG(0xc0, 0x01, 0),
380 	HSPHY_INIT_CFG(0xe8, 0x0d, 0),
381 	HSPHY_INIT_CFG(0x74, 0x12, 0),
382 	HSPHY_INIT_CFG(0x98, 0x63, 0),
383 	HSPHY_INIT_CFG(0x9c, 0x03, 0),
384 	HSPHY_INIT_CFG(0xa0, 0x1d, 0),
385 	HSPHY_INIT_CFG(0xa4, 0x03, 0),
386 	HSPHY_INIT_CFG(0x8c, 0x23, 0),
387 	HSPHY_INIT_CFG(0x78, 0x08, 0),
388 	HSPHY_INIT_CFG(0x7c, 0xdc, 0),
389 	HSPHY_INIT_CFG(0x90, 0xe0, 20),
390 	HSPHY_INIT_CFG(0x74, 0x10, 0),
391 	HSPHY_INIT_CFG(0x90, 0x60, 0),
392 };
393 
394 static const struct hsphy_data hsphy_data_femtophy = {
395 	.init_seq = init_seq_femtophy,
396 	.init_seq_num = ARRAY_SIZE(init_seq_femtophy),
397 };
398 
399 static const struct of_device_id qcom_snps_hsphy_match[] = {
400 	{ .compatible = "qcom,usb-hs-28nm-femtophy", .data = &hsphy_data_femtophy, },
401 	{ },
402 };
403 MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_match);
404 
405 static struct platform_driver qcom_snps_hsphy_driver = {
406 	.probe = qcom_snps_hsphy_probe,
407 	.driver	= {
408 		.name = "qcom,usb-hs-28nm-phy",
409 		.of_match_table = qcom_snps_hsphy_match,
410 	},
411 };
412 module_platform_driver(qcom_snps_hsphy_driver);
413 
414 MODULE_DESCRIPTION("Qualcomm 28nm Hi-Speed USB PHY driver");
415 MODULE_LICENSE("GPL v2");
416