xref: /linux/drivers/ufs/host/ufshcd-pltfrm.c (revision 049380360ca6f4cc22ac2f67fe95b98967c887f0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Universal Flash Storage Host controller Platform bus based glue driver
4  * Copyright (C) 2011-2013 Samsung India Software Operations
5  *
6  * Authors:
7  *	Santosh Yaraganavi <santosh.sy@samsung.com>
8  *	Vinayak Holikatti <h.vinayak@samsung.com>
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_opp.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/of.h>
17 
18 #include <ufs/ufshcd.h>
19 #include "ufshcd-pltfrm.h"
20 #include <ufs/unipro.h>
21 
22 #define UFSHCD_DEFAULT_LANES_PER_DIRECTION		2
23 
ufshcd_parse_clock_info(struct ufs_hba * hba)24 static int ufshcd_parse_clock_info(struct ufs_hba *hba)
25 {
26 	int ret = 0;
27 	int cnt;
28 	int i;
29 	struct device *dev = hba->dev;
30 	struct device_node *np = dev->of_node;
31 	const char *name;
32 	u32 *clkfreq = NULL;
33 	struct ufs_clk_info *clki;
34 	ssize_t sz = 0;
35 
36 	if (!np)
37 		goto out;
38 
39 	cnt = of_property_count_strings(np, "clock-names");
40 	if (!cnt || (cnt == -EINVAL)) {
41 		dev_info(dev, "%s: Unable to find clocks, assuming enabled\n",
42 				__func__);
43 	} else if (cnt < 0) {
44 		dev_err(dev, "%s: count clock strings failed, err %d\n",
45 				__func__, cnt);
46 		ret = cnt;
47 	}
48 
49 	if (cnt <= 0)
50 		goto out;
51 
52 	sz = of_property_count_u32_elems(np, "freq-table-hz");
53 	if (sz <= 0) {
54 		dev_info(dev, "freq-table-hz property not specified\n");
55 		goto out;
56 	}
57 
58 	if (sz != 2 * cnt) {
59 		dev_err(dev, "%s len mismatch\n", "freq-table-hz");
60 		ret = -EINVAL;
61 		goto out;
62 	}
63 
64 	clkfreq = devm_kcalloc(dev, sz, sizeof(*clkfreq),
65 			       GFP_KERNEL);
66 	if (!clkfreq) {
67 		ret = -ENOMEM;
68 		goto out;
69 	}
70 
71 	ret = of_property_read_u32_array(np, "freq-table-hz",
72 			clkfreq, sz);
73 	if (ret && (ret != -EINVAL)) {
74 		dev_err(dev, "%s: error reading array %d\n",
75 				"freq-table-hz", ret);
76 		return ret;
77 	}
78 
79 	for (i = 0; i < sz; i += 2) {
80 		ret = of_property_read_string_index(np,	"clock-names", i/2,
81 						    &name);
82 		if (ret)
83 			goto out;
84 
85 		clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL);
86 		if (!clki) {
87 			ret = -ENOMEM;
88 			goto out;
89 		}
90 
91 		clki->min_freq = clkfreq[i];
92 		clki->max_freq = clkfreq[i+1];
93 		clki->name = devm_kstrdup(dev, name, GFP_KERNEL);
94 		if (!clki->name) {
95 			ret = -ENOMEM;
96 			goto out;
97 		}
98 
99 		if (!strcmp(name, "ref_clk"))
100 			clki->keep_link_active = true;
101 		dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz",
102 				clki->min_freq, clki->max_freq, clki->name);
103 		list_add_tail(&clki->list, &hba->clk_list_head);
104 	}
105 out:
106 	return ret;
107 }
108 
phandle_exists(const struct device_node * np,const char * phandle_name,int index)109 static bool phandle_exists(const struct device_node *np,
110 			   const char *phandle_name, int index)
111 {
112 	struct device_node *parse_np = of_parse_phandle(np, phandle_name, index);
113 
114 	if (parse_np)
115 		of_node_put(parse_np);
116 
117 	return parse_np != NULL;
118 }
119 
120 #define MAX_PROP_SIZE 32
ufshcd_populate_vreg(struct device * dev,const char * name,struct ufs_vreg ** out_vreg,bool skip_current)121 int ufshcd_populate_vreg(struct device *dev, const char *name,
122 			 struct ufs_vreg **out_vreg, bool skip_current)
123 {
124 	char prop_name[MAX_PROP_SIZE];
125 	struct ufs_vreg *vreg = NULL;
126 	struct device_node *np = dev->of_node;
127 
128 	if (!np) {
129 		dev_err(dev, "%s: non DT initialization\n", __func__);
130 		goto out;
131 	}
132 
133 	snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name);
134 	if (!phandle_exists(np, prop_name, 0)) {
135 		dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n",
136 				__func__, prop_name);
137 		goto out;
138 	}
139 
140 	vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
141 	if (!vreg)
142 		return -ENOMEM;
143 
144 	vreg->name = devm_kstrdup(dev, name, GFP_KERNEL);
145 	if (!vreg->name)
146 		return -ENOMEM;
147 
148 	if (skip_current) {
149 		vreg->max_uA = 0;
150 		goto out;
151 	}
152 
153 	snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name);
154 	if (of_property_read_u32(np, prop_name, &vreg->max_uA)) {
155 		dev_info(dev, "%s: unable to find %s\n", __func__, prop_name);
156 		vreg->max_uA = 0;
157 	}
158 out:
159 	*out_vreg = vreg;
160 	return 0;
161 }
162 EXPORT_SYMBOL_GPL(ufshcd_populate_vreg);
163 
164 /**
165  * ufshcd_parse_regulator_info - get regulator info from device tree
166  * @hba: per adapter instance
167  *
168  * Get regulator info from device tree for vcc, vccq, vccq2 power supplies.
169  * If any of the supplies are not defined it is assumed that they are always-on
170  * and hence return zero. If the property is defined but parsing is failed
171  * then return corresponding error.
172  *
173  * Return: 0 upon success; < 0 upon failure.
174  */
ufshcd_parse_regulator_info(struct ufs_hba * hba)175 static int ufshcd_parse_regulator_info(struct ufs_hba *hba)
176 {
177 	int err;
178 	struct device *dev = hba->dev;
179 	struct ufs_vreg_info *info = &hba->vreg_info;
180 
181 	err = ufshcd_populate_vreg(dev, "vdd-hba", &info->vdd_hba, true);
182 	if (err)
183 		goto out;
184 
185 	err = ufshcd_populate_vreg(dev, "vcc", &info->vcc, false);
186 	if (err)
187 		goto out;
188 
189 	err = ufshcd_populate_vreg(dev, "vccq", &info->vccq, false);
190 	if (err)
191 		goto out;
192 
193 	err = ufshcd_populate_vreg(dev, "vccq2", &info->vccq2, false);
194 out:
195 	return err;
196 }
197 
ufshcd_init_lanes_per_dir(struct ufs_hba * hba)198 static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
199 {
200 	struct device *dev = hba->dev;
201 	int ret;
202 
203 	ret = of_property_read_u32(dev->of_node, "lanes-per-direction",
204 		&hba->lanes_per_direction);
205 	if (ret) {
206 		dev_dbg(hba->dev,
207 			"%s: failed to read lanes-per-direction, ret=%d\n",
208 			__func__, ret);
209 		/* Old R-Car S4 DTBs lack "lanes-per-direction = <1>" */
210 		if (of_device_is_compatible(dev->of_node, "renesas,r8a779f0-ufs"))
211 			hba->lanes_per_direction = 1;
212 		else
213 			hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION;
214 	}
215 }
216 
ufshcd_parse_tx_precode_enable(struct ufs_hba * hba,bool host_precode_en[UFS_MAX_LANES],bool device_precode_en[UFS_MAX_LANES])217 static int ufshcd_parse_tx_precode_enable(struct ufs_hba *hba,
218 					  bool host_precode_en[UFS_MAX_LANES],
219 					  bool device_precode_en[UFS_MAX_LANES])
220 {
221 	const char *prop_name = "tx-precode-enable-g6";
222 	u32 num_elems = 2 * hba->lanes_per_direction;
223 	const u32 lpd = hba->lanes_per_direction;
224 	u32 precode[UFS_MAX_LANES * 2];
225 	struct device *dev = hba->dev;
226 	int count, err, i;
227 
228 	count = of_property_count_u32_elems(dev->of_node, prop_name);
229 	if (count == -EINVAL || count == -ENODATA)
230 		return 0;
231 
232 	if (count < 0)
233 		return count;
234 
235 	if (count != num_elems) {
236 		dev_err(dev, "Property %s has invalid count (%d), expecting %u\n",
237 			prop_name, count, num_elems);
238 		return -EINVAL;
239 	}
240 
241 	err = of_property_read_u32_array(dev->of_node, prop_name, precode, num_elems);
242 	if (err) {
243 		dev_err(dev, "Failed to read %s property, %d\n", prop_name, err);
244 		return err;
245 	}
246 
247 	for (i = 0; i < num_elems; i++) {
248 		if (precode[i] > 1) {
249 			dev_err(dev, "Invalid TX precode value (%u) in %s property\n",
250 				precode[i], prop_name);
251 			return -EINVAL;
252 		}
253 	}
254 
255 	for (i = 0; i < lpd; i++) {
256 		host_precode_en[i] = precode[i * 2];
257 		device_precode_en[i] = precode[i * 2 + 1];
258 	}
259 
260 	return 0;
261 }
262 
ufshcd_parse_tx_eq_value_array(struct ufs_hba * hba,const char * prop_name,const u32 max_value,u32 values[UFS_MAX_LANES * 2])263 static int ufshcd_parse_tx_eq_value_array(struct ufs_hba *hba,
264 					  const char *prop_name,
265 					  const u32 max_value,
266 					  u32 values[UFS_MAX_LANES * 2])
267 {
268 	u32 num_elems = 2 * hba->lanes_per_direction;
269 	struct device *dev = hba->dev;
270 	int count, err, i;
271 
272 	count = of_property_count_u32_elems(dev->of_node, prop_name);
273 	if (count < 0)
274 		return count;
275 
276 	if (count != num_elems) {
277 		dev_err(dev, "Property %s has invalid count (%d), expecting %u\n",
278 			prop_name, count, num_elems);
279 		return -EINVAL;
280 	}
281 
282 	err = of_property_read_u32_array(dev->of_node, prop_name, values, num_elems);
283 	if (err) {
284 		dev_err(dev, "Failed to read %s property, %d\n", prop_name, err);
285 		return err;
286 	}
287 
288 	for (i = 0; i < num_elems; i++) {
289 		if (values[i] >= max_value) {
290 			dev_err(dev, "Invalid TX EQ value (%u) in %s property\n",
291 				values[i], prop_name);
292 			return -EINVAL;
293 		}
294 	}
295 
296 	return 0;
297 }
298 
299 /**
300  * ufshcd_parse_tx_eq_settings_for_gear - Parse static TX EQ DT settings for one gear
301  * @hba: per adapter instance
302  * @gear: target HS gear
303  *
304  * Reads the txeq-preshoot-gN, txeq-deemphasis-gN, and (for G6)
305  * tx-precode-enable-g6 device-tree properties.
306  * If all present values are valid, stores them as static TX Equalization
307  * settings for the given gear.
308  */
ufshcd_parse_tx_eq_settings_for_gear(struct ufs_hba * hba,int gear)309 static void ufshcd_parse_tx_eq_settings_for_gear(struct ufs_hba *hba, int gear)
310 {
311 	bool device_precode_en[UFS_MAX_LANES] = { false };
312 	bool host_precode_en[UFS_MAX_LANES] = { false };
313 	const u32 lpd = hba->lanes_per_direction;
314 	struct ufshcd_tx_eq_params *params;
315 	u32 deemphasis[UFS_MAX_LANES * 2];
316 	u32 preshoot[UFS_MAX_LANES * 2];
317 	char prop_name[MAX_PROP_SIZE];
318 	int err, lane;
319 
320 	snprintf(prop_name, MAX_PROP_SIZE, "txeq-preshoot-g%d", gear);
321 	err = ufshcd_parse_tx_eq_value_array(hba, prop_name, TX_HS_NUM_PRESHOOT, preshoot);
322 	if (err)
323 		return;
324 
325 	snprintf(prop_name, MAX_PROP_SIZE, "txeq-deemphasis-g%d", gear);
326 	err = ufshcd_parse_tx_eq_value_array(hba, prop_name, TX_HS_NUM_DEEMPHASIS, deemphasis);
327 	if (err)
328 		return;
329 
330 	if (gear == UFS_HS_G6) {
331 		err = ufshcd_parse_tx_precode_enable(hba, host_precode_en, device_precode_en);
332 		if (err)
333 			return;
334 	}
335 
336 	params = &hba->tx_eq_params[gear - 1];
337 	for (lane = 0; lane < lpd; lane++) {
338 		params->host[lane].preshoot = preshoot[lane * 2];
339 		params->host[lane].deemphasis = deemphasis[lane * 2];
340 		params->host[lane].precode_en = host_precode_en[lane];
341 
342 		params->device[lane].preshoot = preshoot[lane * 2 + 1];
343 		params->device[lane].deemphasis = deemphasis[lane * 2 + 1];
344 		params->device[lane].precode_en = device_precode_en[lane];
345 	}
346 
347 	params->is_valid = true;
348 	params->from_dt = true;
349 }
350 
ufshcd_parse_static_tx_eq_settings(struct ufs_hba * hba)351 static void ufshcd_parse_static_tx_eq_settings(struct ufs_hba *hba)
352 {
353 	const u32 lpd = hba->lanes_per_direction;
354 	int gear;
355 
356 	if (!lpd)
357 		return;
358 
359 	if (lpd > UFS_MAX_LANES) {
360 		dev_warn(hba->dev, "lanes_per_direction (%u) exceeds UFS_MAX_LANES (%u)\n",
361 			 lpd, UFS_MAX_LANES);
362 		return;
363 	}
364 
365 	for (gear = UFS_HS_G1; gear <= UFS_HS_GEAR_MAX; gear++)
366 		ufshcd_parse_tx_eq_settings_for_gear(hba, gear);
367 }
368 
369 /**
370  * ufshcd_parse_clock_min_max_freq  - Parse MIN and MAX clocks freq
371  * @hba: per adapter instance
372  *
373  * This function parses MIN and MAX frequencies of all clocks required
374  * by the host drivers.
375  *
376  * Returns 0 for success and non-zero for failure
377  */
ufshcd_parse_clock_min_max_freq(struct ufs_hba * hba)378 static int ufshcd_parse_clock_min_max_freq(struct ufs_hba *hba)
379 {
380 	struct list_head *head = &hba->clk_list_head;
381 	struct ufs_clk_info *clki;
382 	struct dev_pm_opp *opp;
383 	unsigned long freq;
384 	u8 idx = 0;
385 
386 	list_for_each_entry(clki, head, list) {
387 		if (!clki->name)
388 			continue;
389 
390 		clki->clk = devm_clk_get(hba->dev, clki->name);
391 		if (IS_ERR(clki->clk))
392 			continue;
393 
394 		/* Find Max Freq */
395 		freq = ULONG_MAX;
396 		opp = dev_pm_opp_find_freq_floor_indexed(hba->dev, &freq, idx);
397 		if (IS_ERR(opp)) {
398 			dev_err(hba->dev, "Failed to find OPP for MAX frequency\n");
399 			return PTR_ERR(opp);
400 		}
401 		clki->max_freq = dev_pm_opp_get_freq_indexed(opp, idx);
402 		dev_pm_opp_put(opp);
403 
404 		/* Find Min Freq */
405 		freq = 0;
406 		opp = dev_pm_opp_find_freq_ceil_indexed(hba->dev, &freq, idx);
407 		if (IS_ERR(opp)) {
408 			dev_err(hba->dev, "Failed to find OPP for MIN frequency\n");
409 			return PTR_ERR(opp);
410 		}
411 		clki->min_freq = dev_pm_opp_get_freq_indexed(opp, idx++);
412 		dev_pm_opp_put(opp);
413 	}
414 
415 	return 0;
416 }
417 
ufshcd_parse_operating_points(struct ufs_hba * hba)418 static int ufshcd_parse_operating_points(struct ufs_hba *hba)
419 {
420 	struct device *dev = hba->dev;
421 	struct device_node *np = dev->of_node;
422 	struct dev_pm_opp_config config = {};
423 	struct ufs_clk_info *clki;
424 	const char **clk_names;
425 	int cnt, i, ret;
426 
427 	if (!of_property_present(np, "operating-points-v2"))
428 		return 0;
429 
430 	if (of_property_present(np, "freq-table-hz")) {
431 		dev_err(dev, "%s: operating-points and freq-table-hz are incompatible\n",
432 			 __func__);
433 		return -EINVAL;
434 	}
435 
436 	cnt = of_property_count_strings(np, "clock-names");
437 	if (cnt <= 0) {
438 		dev_err(dev, "%s: Missing clock-names\n",  __func__);
439 		return -ENODEV;
440 	}
441 
442 	/* OPP expects clk_names to be NULL terminated */
443 	clk_names = devm_kcalloc(dev, cnt + 1, sizeof(*clk_names), GFP_KERNEL);
444 	if (!clk_names)
445 		return -ENOMEM;
446 
447 	/*
448 	 * We still need to get reference to all clocks as the UFS core uses
449 	 * them separately.
450 	 */
451 	for (i = 0; i < cnt; i++) {
452 		ret = of_property_read_string_index(np, "clock-names", i,
453 						    &clk_names[i]);
454 		if (ret)
455 			return ret;
456 
457 		clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL);
458 		if (!clki)
459 			return -ENOMEM;
460 
461 		clki->name = devm_kstrdup(dev, clk_names[i], GFP_KERNEL);
462 		if (!clki->name)
463 			return -ENOMEM;
464 
465 		if (!strcmp(clk_names[i], "ref_clk"))
466 			clki->keep_link_active = true;
467 
468 		list_add_tail(&clki->list, &hba->clk_list_head);
469 	}
470 
471 	config.clk_names = clk_names,
472 	config.config_clks = ufshcd_opp_config_clks;
473 
474 	ret = devm_pm_opp_set_config(dev, &config);
475 	if (ret)
476 		return ret;
477 
478 	ret = devm_pm_opp_of_add_table(dev);
479 	if (ret) {
480 		dev_err(dev, "Failed to add OPP table: %d\n", ret);
481 		return ret;
482 	}
483 
484 	ret = ufshcd_parse_clock_min_max_freq(hba);
485 	if (ret)
486 		return ret;
487 
488 	hba->use_pm_opp = true;
489 
490 	return 0;
491 }
492 
493 /**
494  * ufshcd_negotiate_pwr_params - find power mode settings that are supported by
495  *				 both the controller and the device
496  * @host_params: pointer to host parameters
497  * @dev_max: pointer to device attributes
498  * @agreed_pwr: returned agreed attributes
499  *
500  * Return: 0 on success, non-zero value on failure.
501  */
ufshcd_negotiate_pwr_params(const struct ufs_host_params * host_params,const struct ufs_pa_layer_attr * dev_max,struct ufs_pa_layer_attr * agreed_pwr)502 int ufshcd_negotiate_pwr_params(const struct ufs_host_params *host_params,
503 				const struct ufs_pa_layer_attr *dev_max,
504 				struct ufs_pa_layer_attr *agreed_pwr)
505 {
506 	int min_host_gear;
507 	int min_dev_gear;
508 	bool is_dev_sup_hs = false;
509 	bool is_host_max_hs = false;
510 
511 	if (dev_max->pwr_rx == FAST_MODE)
512 		is_dev_sup_hs = true;
513 
514 	if (host_params->desired_working_mode == UFS_HS_MODE) {
515 		is_host_max_hs = true;
516 		min_host_gear = min_t(u32, host_params->hs_rx_gear,
517 					host_params->hs_tx_gear);
518 	} else {
519 		min_host_gear = min_t(u32, host_params->pwm_rx_gear,
520 					host_params->pwm_tx_gear);
521 	}
522 
523 	/*
524 	 * device doesn't support HS but host_params->desired_working_mode is HS,
525 	 * thus device and host_params don't agree
526 	 */
527 	if (!is_dev_sup_hs && is_host_max_hs) {
528 		pr_info("%s: device doesn't support HS\n",
529 			__func__);
530 		return -ENOTSUPP;
531 	} else if (is_dev_sup_hs && is_host_max_hs) {
532 		/*
533 		 * since device supports HS, it supports FAST_MODE.
534 		 * since host_params->desired_working_mode is also HS
535 		 * then final decision (FAST/FASTAUTO) is done according
536 		 * to pltfrm_params as it is the restricting factor
537 		 */
538 		agreed_pwr->pwr_rx = host_params->rx_pwr_hs;
539 		agreed_pwr->pwr_tx = agreed_pwr->pwr_rx;
540 	} else {
541 		/*
542 		 * here host_params->desired_working_mode is PWM.
543 		 * it doesn't matter whether device supports HS or PWM,
544 		 * in both cases host_params->desired_working_mode will
545 		 * determine the mode
546 		 */
547 		agreed_pwr->pwr_rx = host_params->rx_pwr_pwm;
548 		agreed_pwr->pwr_tx = agreed_pwr->pwr_rx;
549 	}
550 
551 	/*
552 	 * we would like tx to work in the minimum number of lanes
553 	 * between device capability and vendor preferences.
554 	 * the same decision will be made for rx
555 	 */
556 	agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx,
557 				    host_params->tx_lanes);
558 	agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx,
559 				    host_params->rx_lanes);
560 
561 	/* device maximum gear is the minimum between device rx and tx gears */
562 	min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx);
563 
564 	/*
565 	 * if both device capabilities and vendor pre-defined preferences are
566 	 * both HS or both PWM then set the minimum gear to be the chosen
567 	 * working gear.
568 	 * if one is PWM and one is HS then the one that is PWM get to decide
569 	 * what is the gear, as it is the one that also decided previously what
570 	 * pwr the device will be configured to.
571 	 */
572 	if ((is_dev_sup_hs && is_host_max_hs) ||
573 	    (!is_dev_sup_hs && !is_host_max_hs)) {
574 		agreed_pwr->gear_rx =
575 			min_t(u32, min_dev_gear, min_host_gear);
576 	} else if (!is_dev_sup_hs) {
577 		agreed_pwr->gear_rx = min_dev_gear;
578 	} else {
579 		agreed_pwr->gear_rx = min_host_gear;
580 	}
581 	agreed_pwr->gear_tx = agreed_pwr->gear_rx;
582 
583 	agreed_pwr->hs_rate = host_params->hs_rate;
584 
585 	return 0;
586 }
587 EXPORT_SYMBOL_GPL(ufshcd_negotiate_pwr_params);
588 
589 /**
590  * ufshcd_parse_gear_limits - Parse DT-based gear and rate limits for UFS
591  * @hba: Pointer to UFS host bus adapter instance
592  * @host_params: Pointer to UFS host parameters structure to be updated
593  *
594  * This function reads optional device tree properties to apply
595  * platform-specific constraints.
596  *
597  * "limit-hs-gear": Specifies the max HS gear.
598  * "limit-gear-rate": Specifies the max High-Speed rate.
599  */
ufshcd_parse_gear_limits(struct ufs_hba * hba,struct ufs_host_params * host_params)600 void ufshcd_parse_gear_limits(struct ufs_hba *hba, struct ufs_host_params *host_params)
601 {
602 	struct device_node *np = hba->dev->of_node;
603 	u32 hs_gear;
604 	const char *hs_rate;
605 
606 	if (!of_property_read_u32(np, "limit-hs-gear", &hs_gear)) {
607 		host_params->hs_tx_gear = hs_gear;
608 		host_params->hs_rx_gear = hs_gear;
609 	}
610 
611 	if (!of_property_read_string(np, "limit-gear-rate", &hs_rate)) {
612 		if (!strcmp(hs_rate, "rate-a"))
613 			host_params->hs_rate = PA_HS_MODE_A;
614 		else if (!strcmp(hs_rate, "rate-b"))
615 			host_params->hs_rate = PA_HS_MODE_B;
616 		else
617 			dev_warn(hba->dev, "Invalid rate: %s\n", hs_rate);
618 	}
619 }
620 EXPORT_SYMBOL_GPL(ufshcd_parse_gear_limits);
621 
ufshcd_init_host_params(struct ufs_host_params * host_params)622 void ufshcd_init_host_params(struct ufs_host_params *host_params)
623 {
624 	*host_params = (struct ufs_host_params){
625 		.tx_lanes = UFS_LANE_2,
626 		.rx_lanes = UFS_LANE_2,
627 		.hs_rx_gear = UFS_HS_G3,
628 		.hs_tx_gear = UFS_HS_G3,
629 		.pwm_rx_gear = UFS_PWM_G4,
630 		.pwm_tx_gear = UFS_PWM_G4,
631 		.rx_pwr_pwm = SLOW_MODE,
632 		.tx_pwr_pwm = SLOW_MODE,
633 		.rx_pwr_hs = FAST_MODE,
634 		.tx_pwr_hs = FAST_MODE,
635 		.hs_rate = PA_HS_MODE_B,
636 		.desired_working_mode = UFS_HS_MODE,
637 	};
638 }
639 EXPORT_SYMBOL_GPL(ufshcd_init_host_params);
640 
641 /**
642  * ufshcd_pltfrm_init - probe routine of the driver
643  * @pdev: pointer to Platform device handle
644  * @vops: pointer to variant ops
645  *
646  * Return: 0 on success, non-zero value on failure.
647  */
ufshcd_pltfrm_init(struct platform_device * pdev,const struct ufs_hba_variant_ops * vops)648 int ufshcd_pltfrm_init(struct platform_device *pdev,
649 		       const struct ufs_hba_variant_ops *vops)
650 {
651 	struct ufs_hba *hba;
652 	void __iomem *mmio_base;
653 	int irq, err;
654 	struct device *dev = &pdev->dev;
655 
656 	mmio_base = devm_platform_ioremap_resource(pdev, 0);
657 	if (IS_ERR(mmio_base))
658 		return PTR_ERR(mmio_base);
659 
660 	irq = platform_get_irq(pdev, 0);
661 	if (irq < 0)
662 		return irq;
663 
664 	err = ufshcd_alloc_host(dev, &hba);
665 	if (err) {
666 		dev_err(dev, "Allocation failed\n");
667 		return err;
668 	}
669 
670 	hba->vops = vops;
671 
672 	err = ufshcd_parse_clock_info(hba);
673 	if (err) {
674 		dev_err(dev, "%s: clock parse failed %d\n",
675 				__func__, err);
676 		return err;
677 	}
678 	err = ufshcd_parse_regulator_info(hba);
679 	if (err) {
680 		dev_err(dev, "%s: regulator init failed %d\n",
681 				__func__, err);
682 		return err;
683 	}
684 
685 	ufshcd_init_lanes_per_dir(hba);
686 
687 	ufshcd_parse_static_tx_eq_settings(hba);
688 
689 	err = ufshcd_parse_operating_points(hba);
690 	if (err) {
691 		dev_err(dev, "%s: OPP parse failed %d\n", __func__, err);
692 		return err;
693 	}
694 
695 	err = ufshcd_init(hba, mmio_base, irq);
696 	if (err) {
697 		dev_err_probe(dev, err, "Initialization failed with error %d\n",
698 			      err);
699 		return err;
700 	}
701 
702 	pm_runtime_set_active(dev);
703 	pm_runtime_enable(dev);
704 
705 	return 0;
706 }
707 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);
708 
709 /**
710  * ufshcd_pltfrm_remove - Remove ufshcd platform
711  * @pdev: pointer to Platform device handle
712  */
ufshcd_pltfrm_remove(struct platform_device * pdev)713 void ufshcd_pltfrm_remove(struct platform_device *pdev)
714 {
715 	struct ufs_hba *hba =  platform_get_drvdata(pdev);
716 
717 	pm_runtime_get_sync(&pdev->dev);
718 	ufshcd_remove(hba);
719 	pm_runtime_disable(&pdev->dev);
720 	pm_runtime_put_noidle(&pdev->dev);
721 }
722 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_remove);
723 
724 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
725 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
726 MODULE_DESCRIPTION("UFS host controller Platform bus based glue driver");
727 MODULE_LICENSE("GPL");
728