1 /*
2  * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 and
6  * only version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14 
15 #include "phy-qcom-ufs-i.h"
16 
17 #define MAX_PROP_NAME              32
18 #define VDDA_PHY_MIN_UV            1000000
19 #define VDDA_PHY_MAX_UV            1000000
20 #define VDDA_PLL_MIN_UV            1800000
21 #define VDDA_PLL_MAX_UV            1800000
22 #define VDDP_REF_CLK_MIN_UV        1200000
23 #define VDDP_REF_CLK_MAX_UV        1200000
24 
25 static int __ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
26 				    const char *, bool);
27 static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
28 				  const char *);
29 static int ufs_qcom_phy_base_init(struct platform_device *pdev,
30 				  struct ufs_qcom_phy *phy_common);
31 
ufs_qcom_phy_calibrate(struct ufs_qcom_phy * ufs_qcom_phy,struct ufs_qcom_phy_calibration * tbl_A,int tbl_size_A,struct ufs_qcom_phy_calibration * tbl_B,int tbl_size_B,bool is_rate_B)32 int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
33 			   struct ufs_qcom_phy_calibration *tbl_A,
34 			   int tbl_size_A,
35 			   struct ufs_qcom_phy_calibration *tbl_B,
36 			   int tbl_size_B, bool is_rate_B)
37 {
38 	int i;
39 	int ret = 0;
40 
41 	if (!tbl_A) {
42 		dev_err(ufs_qcom_phy->dev, "%s: tbl_A is NULL", __func__);
43 		ret = EINVAL;
44 		goto out;
45 	}
46 
47 	for (i = 0; i < tbl_size_A; i++)
48 		writel_relaxed(tbl_A[i].cfg_value,
49 			       ufs_qcom_phy->mmio + tbl_A[i].reg_offset);
50 
51 	/*
52 	 * In case we would like to work in rate B, we need
53 	 * to override a registers that were configured in rate A table
54 	 * with registers of rate B table.
55 	 * table.
56 	 */
57 	if (is_rate_B) {
58 		if (!tbl_B) {
59 			dev_err(ufs_qcom_phy->dev, "%s: tbl_B is NULL",
60 				__func__);
61 			ret = EINVAL;
62 			goto out;
63 		}
64 
65 		for (i = 0; i < tbl_size_B; i++)
66 			writel_relaxed(tbl_B[i].cfg_value,
67 				ufs_qcom_phy->mmio + tbl_B[i].reg_offset);
68 	}
69 
70 	/* flush buffered writes */
71 	mb();
72 
73 out:
74 	return ret;
75 }
76 EXPORT_SYMBOL_GPL(ufs_qcom_phy_calibrate);
77 
ufs_qcom_phy_generic_probe(struct platform_device * pdev,struct ufs_qcom_phy * common_cfg,struct phy_ops * ufs_qcom_phy_gen_ops,struct ufs_qcom_phy_specific_ops * phy_spec_ops)78 struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
79 				struct ufs_qcom_phy *common_cfg,
80 				struct phy_ops *ufs_qcom_phy_gen_ops,
81 				struct ufs_qcom_phy_specific_ops *phy_spec_ops)
82 {
83 	int err;
84 	struct device *dev = &pdev->dev;
85 	struct phy *generic_phy = NULL;
86 	struct phy_provider *phy_provider;
87 
88 	err = ufs_qcom_phy_base_init(pdev, common_cfg);
89 	if (err) {
90 		dev_err(dev, "%s: phy base init failed %d\n", __func__, err);
91 		goto out;
92 	}
93 
94 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
95 	if (IS_ERR(phy_provider)) {
96 		err = PTR_ERR(phy_provider);
97 		dev_err(dev, "%s: failed to register phy %d\n", __func__, err);
98 		goto out;
99 	}
100 
101 	generic_phy = devm_phy_create(dev, NULL, ufs_qcom_phy_gen_ops);
102 	if (IS_ERR(generic_phy)) {
103 		err =  PTR_ERR(generic_phy);
104 		dev_err(dev, "%s: failed to create phy %d\n", __func__, err);
105 		generic_phy = NULL;
106 		goto out;
107 	}
108 
109 	common_cfg->phy_spec_ops = phy_spec_ops;
110 	common_cfg->dev = dev;
111 
112 out:
113 	return generic_phy;
114 }
115 EXPORT_SYMBOL_GPL(ufs_qcom_phy_generic_probe);
116 
117 /*
118  * This assumes the embedded phy structure inside generic_phy is of type
119  * struct ufs_qcom_phy. In order to function properly it's crucial
120  * to keep the embedded struct "struct ufs_qcom_phy common_cfg"
121  * as the first inside generic_phy.
122  */
get_ufs_qcom_phy(struct phy * generic_phy)123 struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy)
124 {
125 	return (struct ufs_qcom_phy *)phy_get_drvdata(generic_phy);
126 }
127 EXPORT_SYMBOL_GPL(get_ufs_qcom_phy);
128 
129 static
ufs_qcom_phy_base_init(struct platform_device * pdev,struct ufs_qcom_phy * phy_common)130 int ufs_qcom_phy_base_init(struct platform_device *pdev,
131 			   struct ufs_qcom_phy *phy_common)
132 {
133 	struct device *dev = &pdev->dev;
134 	struct resource *res;
135 	int err = 0;
136 
137 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_mem");
138 	phy_common->mmio = devm_ioremap_resource(dev, res);
139 	if (IS_ERR((void const *)phy_common->mmio)) {
140 		err = PTR_ERR((void const *)phy_common->mmio);
141 		phy_common->mmio = NULL;
142 		dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n",
143 			__func__, err);
144 		return err;
145 	}
146 
147 	/* "dev_ref_clk_ctrl_mem" is optional resource */
148 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
149 					   "dev_ref_clk_ctrl_mem");
150 	phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res);
151 	if (IS_ERR((void const *)phy_common->dev_ref_clk_ctrl_mmio))
152 		phy_common->dev_ref_clk_ctrl_mmio = NULL;
153 
154 	return 0;
155 }
156 
__ufs_qcom_phy_clk_get(struct phy * phy,const char * name,struct clk ** clk_out,bool err_print)157 static int __ufs_qcom_phy_clk_get(struct phy *phy,
158 			 const char *name, struct clk **clk_out, bool err_print)
159 {
160 	struct clk *clk;
161 	int err = 0;
162 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
163 	struct device *dev = ufs_qcom_phy->dev;
164 
165 	clk = devm_clk_get(dev, name);
166 	if (IS_ERR(clk)) {
167 		err = PTR_ERR(clk);
168 		if (err_print)
169 			dev_err(dev, "failed to get %s err %d", name, err);
170 	} else {
171 		*clk_out = clk;
172 	}
173 
174 	return err;
175 }
176 
177 static
ufs_qcom_phy_clk_get(struct phy * phy,const char * name,struct clk ** clk_out)178 int ufs_qcom_phy_clk_get(struct phy *phy,
179 			 const char *name, struct clk **clk_out)
180 {
181 	return __ufs_qcom_phy_clk_get(phy, name, clk_out, true);
182 }
183 
184 int
ufs_qcom_phy_init_clks(struct phy * generic_phy,struct ufs_qcom_phy * phy_common)185 ufs_qcom_phy_init_clks(struct phy *generic_phy,
186 		       struct ufs_qcom_phy *phy_common)
187 {
188 	int err;
189 
190 	err = ufs_qcom_phy_clk_get(generic_phy, "tx_iface_clk",
191 				   &phy_common->tx_iface_clk);
192 	if (err)
193 		goto out;
194 
195 	err = ufs_qcom_phy_clk_get(generic_phy, "rx_iface_clk",
196 				   &phy_common->rx_iface_clk);
197 	if (err)
198 		goto out;
199 
200 	err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk_src",
201 				   &phy_common->ref_clk_src);
202 	if (err)
203 		goto out;
204 
205 	/*
206 	 * "ref_clk_parent" is optional hence don't abort init if it's not
207 	 * found.
208 	 */
209 	__ufs_qcom_phy_clk_get(generic_phy, "ref_clk_parent",
210 				   &phy_common->ref_clk_parent, false);
211 
212 	err = ufs_qcom_phy_clk_get(generic_phy, "ref_clk",
213 				   &phy_common->ref_clk);
214 
215 out:
216 	return err;
217 }
218 EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_clks);
219 
220 int
ufs_qcom_phy_init_vregulators(struct phy * generic_phy,struct ufs_qcom_phy * phy_common)221 ufs_qcom_phy_init_vregulators(struct phy *generic_phy,
222 			      struct ufs_qcom_phy *phy_common)
223 {
224 	int err;
225 
226 	err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_pll,
227 		"vdda-pll");
228 	if (err)
229 		goto out;
230 
231 	err = ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vdda_phy,
232 		"vdda-phy");
233 
234 	if (err)
235 		goto out;
236 
237 	/* vddp-ref-clk-* properties are optional */
238 	__ufs_qcom_phy_init_vreg(generic_phy, &phy_common->vddp_ref_clk,
239 				 "vddp-ref-clk", true);
240 out:
241 	return err;
242 }
243 EXPORT_SYMBOL_GPL(ufs_qcom_phy_init_vregulators);
244 
__ufs_qcom_phy_init_vreg(struct phy * phy,struct ufs_qcom_phy_vreg * vreg,const char * name,bool optional)245 static int __ufs_qcom_phy_init_vreg(struct phy *phy,
246 		struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
247 {
248 	int err = 0;
249 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
250 	struct device *dev = ufs_qcom_phy->dev;
251 
252 	char prop_name[MAX_PROP_NAME];
253 
254 	vreg->name = kstrdup(name, GFP_KERNEL);
255 	if (!vreg->name) {
256 		err = -ENOMEM;
257 		goto out;
258 	}
259 
260 	vreg->reg = devm_regulator_get(dev, name);
261 	if (IS_ERR(vreg->reg)) {
262 		err = PTR_ERR(vreg->reg);
263 		vreg->reg = NULL;
264 		if (!optional)
265 			dev_err(dev, "failed to get %s, %d\n", name, err);
266 		goto out;
267 	}
268 
269 	if (dev->of_node) {
270 		snprintf(prop_name, MAX_PROP_NAME, "%s-max-microamp", name);
271 		err = of_property_read_u32(dev->of_node,
272 					prop_name, &vreg->max_uA);
273 		if (err && err != -EINVAL) {
274 			dev_err(dev, "%s: failed to read %s\n",
275 					__func__, prop_name);
276 			goto out;
277 		} else if (err == -EINVAL || !vreg->max_uA) {
278 			if (regulator_count_voltages(vreg->reg) > 0) {
279 				dev_err(dev, "%s: %s is mandatory\n",
280 						__func__, prop_name);
281 				goto out;
282 			}
283 			err = 0;
284 		}
285 		snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name);
286 		if (of_get_property(dev->of_node, prop_name, NULL))
287 			vreg->is_always_on = true;
288 		else
289 			vreg->is_always_on = false;
290 	}
291 
292 	if (!strcmp(name, "vdda-pll")) {
293 		vreg->max_uV = VDDA_PLL_MAX_UV;
294 		vreg->min_uV = VDDA_PLL_MIN_UV;
295 	} else if (!strcmp(name, "vdda-phy")) {
296 		vreg->max_uV = VDDA_PHY_MAX_UV;
297 		vreg->min_uV = VDDA_PHY_MIN_UV;
298 	} else if (!strcmp(name, "vddp-ref-clk")) {
299 		vreg->max_uV = VDDP_REF_CLK_MAX_UV;
300 		vreg->min_uV = VDDP_REF_CLK_MIN_UV;
301 	}
302 
303 out:
304 	if (err)
305 		kfree(vreg->name);
306 	return err;
307 }
308 
ufs_qcom_phy_init_vreg(struct phy * phy,struct ufs_qcom_phy_vreg * vreg,const char * name)309 static int ufs_qcom_phy_init_vreg(struct phy *phy,
310 			struct ufs_qcom_phy_vreg *vreg, const char *name)
311 {
312 	return __ufs_qcom_phy_init_vreg(phy, vreg, name, false);
313 }
314 
315 static
ufs_qcom_phy_cfg_vreg(struct phy * phy,struct ufs_qcom_phy_vreg * vreg,bool on)316 int ufs_qcom_phy_cfg_vreg(struct phy *phy,
317 			  struct ufs_qcom_phy_vreg *vreg, bool on)
318 {
319 	int ret = 0;
320 	struct regulator *reg = vreg->reg;
321 	const char *name = vreg->name;
322 	int min_uV;
323 	int uA_load;
324 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
325 	struct device *dev = ufs_qcom_phy->dev;
326 
327 	BUG_ON(!vreg);
328 
329 	if (regulator_count_voltages(reg) > 0) {
330 		min_uV = on ? vreg->min_uV : 0;
331 		ret = regulator_set_voltage(reg, min_uV, vreg->max_uV);
332 		if (ret) {
333 			dev_err(dev, "%s: %s set voltage failed, err=%d\n",
334 					__func__, name, ret);
335 			goto out;
336 		}
337 		uA_load = on ? vreg->max_uA : 0;
338 		ret = regulator_set_load(reg, uA_load);
339 		if (ret >= 0) {
340 			/*
341 			 * regulator_set_load() returns new regulator
342 			 * mode upon success.
343 			 */
344 			ret = 0;
345 		} else {
346 			dev_err(dev, "%s: %s set optimum mode(uA_load=%d) failed, err=%d\n",
347 					__func__, name, uA_load, ret);
348 			goto out;
349 		}
350 	}
351 out:
352 	return ret;
353 }
354 
355 static
ufs_qcom_phy_enable_vreg(struct phy * phy,struct ufs_qcom_phy_vreg * vreg)356 int ufs_qcom_phy_enable_vreg(struct phy *phy,
357 			     struct ufs_qcom_phy_vreg *vreg)
358 {
359 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
360 	struct device *dev = ufs_qcom_phy->dev;
361 	int ret = 0;
362 
363 	if (!vreg || vreg->enabled)
364 		goto out;
365 
366 	ret = ufs_qcom_phy_cfg_vreg(phy, vreg, true);
367 	if (ret) {
368 		dev_err(dev, "%s: ufs_qcom_phy_cfg_vreg() failed, err=%d\n",
369 			__func__, ret);
370 		goto out;
371 	}
372 
373 	ret = regulator_enable(vreg->reg);
374 	if (ret) {
375 		dev_err(dev, "%s: enable failed, err=%d\n",
376 				__func__, ret);
377 		goto out;
378 	}
379 
380 	vreg->enabled = true;
381 out:
382 	return ret;
383 }
384 
ufs_qcom_phy_enable_ref_clk(struct phy * generic_phy)385 int ufs_qcom_phy_enable_ref_clk(struct phy *generic_phy)
386 {
387 	int ret = 0;
388 	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
389 
390 	if (phy->is_ref_clk_enabled)
391 		goto out;
392 
393 	/*
394 	 * reference clock is propagated in a daisy-chained manner from
395 	 * source to phy, so ungate them at each stage.
396 	 */
397 	ret = clk_prepare_enable(phy->ref_clk_src);
398 	if (ret) {
399 		dev_err(phy->dev, "%s: ref_clk_src enable failed %d\n",
400 				__func__, ret);
401 		goto out;
402 	}
403 
404 	/*
405 	 * "ref_clk_parent" is optional clock hence make sure that clk reference
406 	 * is available before trying to enable the clock.
407 	 */
408 	if (phy->ref_clk_parent) {
409 		ret = clk_prepare_enable(phy->ref_clk_parent);
410 		if (ret) {
411 			dev_err(phy->dev, "%s: ref_clk_parent enable failed %d\n",
412 					__func__, ret);
413 			goto out_disable_src;
414 		}
415 	}
416 
417 	ret = clk_prepare_enable(phy->ref_clk);
418 	if (ret) {
419 		dev_err(phy->dev, "%s: ref_clk enable failed %d\n",
420 				__func__, ret);
421 		goto out_disable_parent;
422 	}
423 
424 	phy->is_ref_clk_enabled = true;
425 	goto out;
426 
427 out_disable_parent:
428 	if (phy->ref_clk_parent)
429 		clk_disable_unprepare(phy->ref_clk_parent);
430 out_disable_src:
431 	clk_disable_unprepare(phy->ref_clk_src);
432 out:
433 	return ret;
434 }
435 
436 static
ufs_qcom_phy_disable_vreg(struct phy * phy,struct ufs_qcom_phy_vreg * vreg)437 int ufs_qcom_phy_disable_vreg(struct phy *phy,
438 			      struct ufs_qcom_phy_vreg *vreg)
439 {
440 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(phy);
441 	struct device *dev = ufs_qcom_phy->dev;
442 	int ret = 0;
443 
444 	if (!vreg || !vreg->enabled || vreg->is_always_on)
445 		goto out;
446 
447 	ret = regulator_disable(vreg->reg);
448 
449 	if (!ret) {
450 		/* ignore errors on applying disable config */
451 		ufs_qcom_phy_cfg_vreg(phy, vreg, false);
452 		vreg->enabled = false;
453 	} else {
454 		dev_err(dev, "%s: %s disable failed, err=%d\n",
455 				__func__, vreg->name, ret);
456 	}
457 out:
458 	return ret;
459 }
460 
ufs_qcom_phy_disable_ref_clk(struct phy * generic_phy)461 void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
462 {
463 	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
464 
465 	if (phy->is_ref_clk_enabled) {
466 		clk_disable_unprepare(phy->ref_clk);
467 		/*
468 		 * "ref_clk_parent" is optional clock hence make sure that clk
469 		 * reference is available before trying to disable the clock.
470 		 */
471 		if (phy->ref_clk_parent)
472 			clk_disable_unprepare(phy->ref_clk_parent);
473 		clk_disable_unprepare(phy->ref_clk_src);
474 		phy->is_ref_clk_enabled = false;
475 	}
476 }
477 
478 #define UFS_REF_CLK_EN	(1 << 5)
479 
ufs_qcom_phy_dev_ref_clk_ctrl(struct phy * generic_phy,bool enable)480 static void ufs_qcom_phy_dev_ref_clk_ctrl(struct phy *generic_phy, bool enable)
481 {
482 	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
483 
484 	if (phy->dev_ref_clk_ctrl_mmio &&
485 	    (enable ^ phy->is_dev_ref_clk_enabled)) {
486 		u32 temp = readl_relaxed(phy->dev_ref_clk_ctrl_mmio);
487 
488 		if (enable)
489 			temp |= UFS_REF_CLK_EN;
490 		else
491 			temp &= ~UFS_REF_CLK_EN;
492 
493 		/*
494 		 * If we are here to disable this clock immediately after
495 		 * entering into hibern8, we need to make sure that device
496 		 * ref_clk is active atleast 1us after the hibern8 enter.
497 		 */
498 		if (!enable)
499 			udelay(1);
500 
501 		writel_relaxed(temp, phy->dev_ref_clk_ctrl_mmio);
502 		/* ensure that ref_clk is enabled/disabled before we return */
503 		wmb();
504 		/*
505 		 * If we call hibern8 exit after this, we need to make sure that
506 		 * device ref_clk is stable for atleast 1us before the hibern8
507 		 * exit command.
508 		 */
509 		if (enable)
510 			udelay(1);
511 
512 		phy->is_dev_ref_clk_enabled = enable;
513 	}
514 }
515 
ufs_qcom_phy_enable_dev_ref_clk(struct phy * generic_phy)516 void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
517 {
518 	ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
519 }
520 
ufs_qcom_phy_disable_dev_ref_clk(struct phy * generic_phy)521 void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
522 {
523 	ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
524 }
525 
526 /* Turn ON M-PHY RMMI interface clocks */
ufs_qcom_phy_enable_iface_clk(struct phy * generic_phy)527 int ufs_qcom_phy_enable_iface_clk(struct phy *generic_phy)
528 {
529 	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
530 	int ret = 0;
531 
532 	if (phy->is_iface_clk_enabled)
533 		goto out;
534 
535 	ret = clk_prepare_enable(phy->tx_iface_clk);
536 	if (ret) {
537 		dev_err(phy->dev, "%s: tx_iface_clk enable failed %d\n",
538 				__func__, ret);
539 		goto out;
540 	}
541 	ret = clk_prepare_enable(phy->rx_iface_clk);
542 	if (ret) {
543 		clk_disable_unprepare(phy->tx_iface_clk);
544 		dev_err(phy->dev, "%s: rx_iface_clk enable failed %d. disabling also tx_iface_clk\n",
545 				__func__, ret);
546 		goto out;
547 	}
548 	phy->is_iface_clk_enabled = true;
549 
550 out:
551 	return ret;
552 }
553 
554 /* Turn OFF M-PHY RMMI interface clocks */
ufs_qcom_phy_disable_iface_clk(struct phy * generic_phy)555 void ufs_qcom_phy_disable_iface_clk(struct phy *generic_phy)
556 {
557 	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);
558 
559 	if (phy->is_iface_clk_enabled) {
560 		clk_disable_unprepare(phy->tx_iface_clk);
561 		clk_disable_unprepare(phy->rx_iface_clk);
562 		phy->is_iface_clk_enabled = false;
563 	}
564 }
565 
ufs_qcom_phy_start_serdes(struct phy * generic_phy)566 int ufs_qcom_phy_start_serdes(struct phy *generic_phy)
567 {
568 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
569 	int ret = 0;
570 
571 	if (!ufs_qcom_phy->phy_spec_ops->start_serdes) {
572 		dev_err(ufs_qcom_phy->dev, "%s: start_serdes() callback is not supported\n",
573 			__func__);
574 		ret = -ENOTSUPP;
575 	} else {
576 		ufs_qcom_phy->phy_spec_ops->start_serdes(ufs_qcom_phy);
577 	}
578 
579 	return ret;
580 }
581 
ufs_qcom_phy_set_tx_lane_enable(struct phy * generic_phy,u32 tx_lanes)582 int ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes)
583 {
584 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
585 	int ret = 0;
586 
587 	if (!ufs_qcom_phy->phy_spec_ops->set_tx_lane_enable) {
588 		dev_err(ufs_qcom_phy->dev, "%s: set_tx_lane_enable() callback is not supported\n",
589 			__func__);
590 		ret = -ENOTSUPP;
591 	} else {
592 		ufs_qcom_phy->phy_spec_ops->set_tx_lane_enable(ufs_qcom_phy,
593 							       tx_lanes);
594 	}
595 
596 	return ret;
597 }
598 
ufs_qcom_phy_save_controller_version(struct phy * generic_phy,u8 major,u16 minor,u16 step)599 void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
600 					  u8 major, u16 minor, u16 step)
601 {
602 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
603 
604 	ufs_qcom_phy->host_ctrl_rev_major = major;
605 	ufs_qcom_phy->host_ctrl_rev_minor = minor;
606 	ufs_qcom_phy->host_ctrl_rev_step = step;
607 }
608 
ufs_qcom_phy_calibrate_phy(struct phy * generic_phy,bool is_rate_B)609 int ufs_qcom_phy_calibrate_phy(struct phy *generic_phy, bool is_rate_B)
610 {
611 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
612 	int ret = 0;
613 
614 	if (!ufs_qcom_phy->phy_spec_ops->calibrate_phy) {
615 		dev_err(ufs_qcom_phy->dev, "%s: calibrate_phy() callback is not supported\n",
616 			__func__);
617 		ret = -ENOTSUPP;
618 	} else {
619 		ret = ufs_qcom_phy->phy_spec_ops->
620 				calibrate_phy(ufs_qcom_phy, is_rate_B);
621 		if (ret)
622 			dev_err(ufs_qcom_phy->dev, "%s: calibrate_phy() failed %d\n",
623 				__func__, ret);
624 	}
625 
626 	return ret;
627 }
628 
ufs_qcom_phy_remove(struct phy * generic_phy,struct ufs_qcom_phy * ufs_qcom_phy)629 int ufs_qcom_phy_remove(struct phy *generic_phy,
630 			struct ufs_qcom_phy *ufs_qcom_phy)
631 {
632 	phy_power_off(generic_phy);
633 
634 	kfree(ufs_qcom_phy->vdda_pll.name);
635 	kfree(ufs_qcom_phy->vdda_phy.name);
636 
637 	return 0;
638 }
639 EXPORT_SYMBOL_GPL(ufs_qcom_phy_remove);
640 
ufs_qcom_phy_exit(struct phy * generic_phy)641 int ufs_qcom_phy_exit(struct phy *generic_phy)
642 {
643 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
644 
645 	if (ufs_qcom_phy->is_powered_on)
646 		phy_power_off(generic_phy);
647 
648 	return 0;
649 }
650 EXPORT_SYMBOL_GPL(ufs_qcom_phy_exit);
651 
ufs_qcom_phy_is_pcs_ready(struct phy * generic_phy)652 int ufs_qcom_phy_is_pcs_ready(struct phy *generic_phy)
653 {
654 	struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
655 
656 	if (!ufs_qcom_phy->phy_spec_ops->is_physical_coding_sublayer_ready) {
657 		dev_err(ufs_qcom_phy->dev, "%s: is_physical_coding_sublayer_ready() callback is not supported\n",
658 			__func__);
659 		return -ENOTSUPP;
660 	}
661 
662 	return ufs_qcom_phy->phy_spec_ops->
663 			is_physical_coding_sublayer_ready(ufs_qcom_phy);
664 }
665 
ufs_qcom_phy_power_on(struct phy * generic_phy)666 int ufs_qcom_phy_power_on(struct phy *generic_phy)
667 {
668 	struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
669 	struct device *dev = phy_common->dev;
670 	int err;
671 
672 	err = ufs_qcom_phy_enable_vreg(generic_phy, &phy_common->vdda_phy);
673 	if (err) {
674 		dev_err(dev, "%s enable vdda_phy failed, err=%d\n",
675 			__func__, err);
676 		goto out;
677 	}
678 
679 	phy_common->phy_spec_ops->power_control(phy_common, true);
680 
681 	/* vdda_pll also enables ref clock LDOs so enable it first */
682 	err = ufs_qcom_phy_enable_vreg(generic_phy, &phy_common->vdda_pll);
683 	if (err) {
684 		dev_err(dev, "%s enable vdda_pll failed, err=%d\n",
685 			__func__, err);
686 		goto out_disable_phy;
687 	}
688 
689 	err = ufs_qcom_phy_enable_ref_clk(generic_phy);
690 	if (err) {
691 		dev_err(dev, "%s enable phy ref clock failed, err=%d\n",
692 			__func__, err);
693 		goto out_disable_pll;
694 	}
695 
696 	/* enable device PHY ref_clk pad rail */
697 	if (phy_common->vddp_ref_clk.reg) {
698 		err = ufs_qcom_phy_enable_vreg(generic_phy,
699 					       &phy_common->vddp_ref_clk);
700 		if (err) {
701 			dev_err(dev, "%s enable vddp_ref_clk failed, err=%d\n",
702 				__func__, err);
703 			goto out_disable_ref_clk;
704 		}
705 	}
706 
707 	phy_common->is_powered_on = true;
708 	goto out;
709 
710 out_disable_ref_clk:
711 	ufs_qcom_phy_disable_ref_clk(generic_phy);
712 out_disable_pll:
713 	ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);
714 out_disable_phy:
715 	ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_phy);
716 out:
717 	return err;
718 }
719 EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_on);
720 
ufs_qcom_phy_power_off(struct phy * generic_phy)721 int ufs_qcom_phy_power_off(struct phy *generic_phy)
722 {
723 	struct ufs_qcom_phy *phy_common = get_ufs_qcom_phy(generic_phy);
724 
725 	phy_common->phy_spec_ops->power_control(phy_common, false);
726 
727 	if (phy_common->vddp_ref_clk.reg)
728 		ufs_qcom_phy_disable_vreg(generic_phy,
729 					  &phy_common->vddp_ref_clk);
730 	ufs_qcom_phy_disable_ref_clk(generic_phy);
731 
732 	ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_pll);
733 	ufs_qcom_phy_disable_vreg(generic_phy, &phy_common->vdda_phy);
734 	phy_common->is_powered_on = false;
735 
736 	return 0;
737 }
738 EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_off);
739