xref: /linux/drivers/phy/socionext/phy-uniphier-ahci.c (revision 8c994eff8fcfe8ecb1f1dbebed25b4d7bb75be12)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * phy-uniphier-ahci.c - PHY driver for UniPhier AHCI controller
4  * Copyright 2016-2020, Socionext Inc.
5  * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/bitops.h>
10 #include <linux/clk.h>
11 #include <linux/iopoll.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_platform.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/reset.h>
18 
19 struct uniphier_ahciphy_priv {
20 	struct device *dev;
21 	void __iomem  *base;
22 	struct clk *clk, *clk_parent, *clk_parent_gio;
23 	struct reset_control *rst, *rst_parent, *rst_parent_gio;
24 	struct reset_control *rst_pm, *rst_tx, *rst_rx;
25 	const struct uniphier_ahciphy_soc_data *data;
26 };
27 
28 struct uniphier_ahciphy_soc_data {
29 	int (*init)(struct uniphier_ahciphy_priv *priv);
30 	int (*power_on)(struct uniphier_ahciphy_priv *priv);
31 	int (*power_off)(struct uniphier_ahciphy_priv *priv);
32 	bool is_legacy;
33 	bool is_ready_high;
34 	bool is_phy_clk;
35 };
36 
37 /* for Pro4 */
38 #define CKCTRL0				0x0
39 #define CKCTRL0_CK_OFF			BIT(9)
40 #define CKCTRL0_NCY_MASK		GENMASK(8, 4)
41 #define CKCTRL0_NCY5_MASK		GENMASK(3, 2)
42 #define CKCTRL0_PRESCALE_MASK		GENMASK(1, 0)
43 #define CKCTRL1				0x4
44 #define CKCTRL1_LOS_LVL_MASK		GENMASK(20, 16)
45 #define CKCTRL1_TX_LVL_MASK		GENMASK(12, 8)
46 #define RXTXCTRL			0x8
47 #define RXTXCTRL_RX_EQ_VALL_MASK	GENMASK(31, 29)
48 #define RXTXCTRL_RX_DPLL_MODE_MASK	GENMASK(28, 26)
49 #define RXTXCTRL_TX_ATTEN_MASK		GENMASK(14, 12)
50 #define RXTXCTRL_TX_BOOST_MASK		GENMASK(11, 8)
51 #define RXTXCTRL_TX_EDGERATE_MASK	GENMASK(3, 2)
52 #define RXTXCTRL_TX_CKO_EN		BIT(0)
53 #define RSTPWR				0x30
54 #define RSTPWR_RX_EN_VAL		BIT(18)
55 
56 /* for PXs2/PXs3 */
57 #define CKCTRL				0x0
58 #define CKCTRL_P0_READY			BIT(15)
59 #define CKCTRL_P0_RESET			BIT(10)
60 #define CKCTRL_REF_SSP_EN		BIT(9)
61 #define TXCTRL0				0x4
62 #define TXCTRL0_AMP_G3_MASK		GENMASK(22, 16)
63 #define TXCTRL0_AMP_G2_MASK		GENMASK(14, 8)
64 #define TXCTRL0_AMP_G1_MASK		GENMASK(6, 0)
65 #define TXCTRL1				0x8
66 #define TXCTRL1_DEEMPH_G3_MASK		GENMASK(21, 16)
67 #define TXCTRL1_DEEMPH_G2_MASK		GENMASK(13, 8)
68 #define TXCTRL1_DEEMPH_G1_MASK		GENMASK(5, 0)
69 #define RXCTRL				0xc
70 #define RXCTRL_LOS_LVL_MASK		GENMASK(20, 16)
71 #define RXCTRL_LOS_BIAS_MASK		GENMASK(10, 8)
72 #define RXCTRL_RX_EQ_MASK		GENMASK(2, 0)
73 
74 static int uniphier_ahciphy_pro4_init(struct uniphier_ahciphy_priv *priv)
75 {
76 	u32 val;
77 
78 	/* set phy MPLL parameters */
79 	val = readl(priv->base + CKCTRL0);
80 	val &= ~CKCTRL0_NCY_MASK;
81 	val |= FIELD_PREP(CKCTRL0_NCY_MASK, 0x6);
82 	val &= ~CKCTRL0_NCY5_MASK;
83 	val |= FIELD_PREP(CKCTRL0_NCY5_MASK, 0x2);
84 	val &= ~CKCTRL0_PRESCALE_MASK;
85 	val |= FIELD_PREP(CKCTRL0_PRESCALE_MASK, 0x1);
86 	writel(val, priv->base + CKCTRL0);
87 
88 	/* setup phy control parameters */
89 	val = readl(priv->base + CKCTRL1);
90 	val &= ~CKCTRL1_LOS_LVL_MASK;
91 	val |= FIELD_PREP(CKCTRL1_LOS_LVL_MASK, 0x10);
92 	val &= ~CKCTRL1_TX_LVL_MASK;
93 	val |= FIELD_PREP(CKCTRL1_TX_LVL_MASK, 0x06);
94 	writel(val, priv->base + CKCTRL1);
95 
96 	val = readl(priv->base + RXTXCTRL);
97 	val &= ~RXTXCTRL_RX_EQ_VALL_MASK;
98 	val |= FIELD_PREP(RXTXCTRL_RX_EQ_VALL_MASK, 0x6);
99 	val &= ~RXTXCTRL_RX_DPLL_MODE_MASK;
100 	val |= FIELD_PREP(RXTXCTRL_RX_DPLL_MODE_MASK, 0x3);
101 	val &= ~RXTXCTRL_TX_ATTEN_MASK;
102 	val |= FIELD_PREP(RXTXCTRL_TX_ATTEN_MASK, 0x3);
103 	val &= ~RXTXCTRL_TX_BOOST_MASK;
104 	val |= FIELD_PREP(RXTXCTRL_TX_BOOST_MASK, 0x5);
105 	val &= ~RXTXCTRL_TX_EDGERATE_MASK;
106 	val |= FIELD_PREP(RXTXCTRL_TX_EDGERATE_MASK, 0x0);
107 	writel(val, priv->base + RXTXCTRL);
108 
109 	return 0;
110 }
111 
112 static int uniphier_ahciphy_pro4_power_on(struct uniphier_ahciphy_priv *priv)
113 {
114 	u32 val;
115 	int ret;
116 
117 	/* enable reference clock for phy */
118 	val = readl(priv->base + CKCTRL0);
119 	val &= ~CKCTRL0_CK_OFF;
120 	writel(val, priv->base + CKCTRL0);
121 
122 	/* enable TX clock */
123 	val = readl(priv->base + RXTXCTRL);
124 	val |= RXTXCTRL_TX_CKO_EN;
125 	writel(val, priv->base + RXTXCTRL);
126 
127 	/* wait until RX is ready */
128 	ret = readl_poll_timeout(priv->base + RSTPWR, val,
129 				 !(val & RSTPWR_RX_EN_VAL), 200, 2000);
130 	if (ret) {
131 		dev_err(priv->dev, "Failed to check whether Rx is ready\n");
132 		goto out_disable_clock;
133 	}
134 
135 	/* release all reset */
136 	ret = reset_control_deassert(priv->rst_pm);
137 	if (ret) {
138 		dev_err(priv->dev, "Failed to release PM reset\n");
139 		goto out_disable_clock;
140 	}
141 
142 	ret = reset_control_deassert(priv->rst_tx);
143 	if (ret) {
144 		dev_err(priv->dev, "Failed to release Tx reset\n");
145 		goto out_reset_pm_assert;
146 	}
147 
148 	ret = reset_control_deassert(priv->rst_rx);
149 	if (ret) {
150 		dev_err(priv->dev, "Failed to release Rx reset\n");
151 		goto out_reset_tx_assert;
152 	}
153 
154 	return 0;
155 
156 out_reset_tx_assert:
157 	reset_control_assert(priv->rst_tx);
158 out_reset_pm_assert:
159 	reset_control_assert(priv->rst_pm);
160 
161 out_disable_clock:
162 	/* disable TX clock */
163 	val = readl(priv->base + RXTXCTRL);
164 	val &= ~RXTXCTRL_TX_CKO_EN;
165 	writel(val, priv->base + RXTXCTRL);
166 
167 	/* disable reference clock for phy */
168 	val = readl(priv->base + CKCTRL0);
169 	val |= CKCTRL0_CK_OFF;
170 	writel(val, priv->base + CKCTRL0);
171 
172 	return ret;
173 }
174 
175 static int uniphier_ahciphy_pro4_power_off(struct uniphier_ahciphy_priv *priv)
176 {
177 	u32 val;
178 
179 	reset_control_assert(priv->rst_rx);
180 	reset_control_assert(priv->rst_tx);
181 	reset_control_assert(priv->rst_pm);
182 
183 	/* disable TX clock */
184 	val = readl(priv->base + RXTXCTRL);
185 	val &= ~RXTXCTRL_TX_CKO_EN;
186 	writel(val, priv->base + RXTXCTRL);
187 
188 	/* disable reference clock for phy */
189 	val = readl(priv->base + CKCTRL0);
190 	val |= CKCTRL0_CK_OFF;
191 	writel(val, priv->base + CKCTRL0);
192 
193 	return 0;
194 }
195 
196 static void uniphier_ahciphy_pxs2_enable(struct uniphier_ahciphy_priv *priv,
197 					 bool enable)
198 {
199 	u32 val;
200 
201 	val = readl(priv->base + CKCTRL);
202 
203 	if (enable) {
204 		val |= CKCTRL_REF_SSP_EN;
205 		writel(val, priv->base + CKCTRL);
206 		val &= ~CKCTRL_P0_RESET;
207 		writel(val, priv->base + CKCTRL);
208 	} else {
209 		val |= CKCTRL_P0_RESET;
210 		writel(val, priv->base + CKCTRL);
211 		val &= ~CKCTRL_REF_SSP_EN;
212 		writel(val, priv->base + CKCTRL);
213 	}
214 }
215 
216 static int uniphier_ahciphy_pxs2_power_on(struct uniphier_ahciphy_priv *priv)
217 {
218 	int ret;
219 	u32 val;
220 
221 	uniphier_ahciphy_pxs2_enable(priv, true);
222 
223 	/* wait until PLL is ready */
224 	if (priv->data->is_ready_high)
225 		ret = readl_poll_timeout(priv->base + CKCTRL, val,
226 					 (val & CKCTRL_P0_READY), 200, 400);
227 	else
228 		ret = readl_poll_timeout(priv->base + CKCTRL, val,
229 					 !(val & CKCTRL_P0_READY), 200, 400);
230 	if (ret) {
231 		dev_err(priv->dev, "Failed to check whether PHY PLL is ready\n");
232 		uniphier_ahciphy_pxs2_enable(priv, false);
233 	}
234 
235 	return ret;
236 }
237 
238 static int uniphier_ahciphy_pxs2_power_off(struct uniphier_ahciphy_priv *priv)
239 {
240 	uniphier_ahciphy_pxs2_enable(priv, false);
241 
242 	return 0;
243 }
244 
245 static int uniphier_ahciphy_pxs3_init(struct uniphier_ahciphy_priv *priv)
246 {
247 	int i;
248 	u32 val;
249 
250 	/* setup port parameter */
251 	val = readl(priv->base + TXCTRL0);
252 	val &= ~TXCTRL0_AMP_G3_MASK;
253 	val |= FIELD_PREP(TXCTRL0_AMP_G3_MASK, 0x73);
254 	val &= ~TXCTRL0_AMP_G2_MASK;
255 	val |= FIELD_PREP(TXCTRL0_AMP_G2_MASK, 0x46);
256 	val &= ~TXCTRL0_AMP_G1_MASK;
257 	val |= FIELD_PREP(TXCTRL0_AMP_G1_MASK, 0x42);
258 	writel(val, priv->base + TXCTRL0);
259 
260 	val = readl(priv->base + TXCTRL1);
261 	val &= ~TXCTRL1_DEEMPH_G3_MASK;
262 	val |= FIELD_PREP(TXCTRL1_DEEMPH_G3_MASK, 0x23);
263 	val &= ~TXCTRL1_DEEMPH_G2_MASK;
264 	val |= FIELD_PREP(TXCTRL1_DEEMPH_G2_MASK, 0x05);
265 	val &= ~TXCTRL1_DEEMPH_G1_MASK;
266 	val |= FIELD_PREP(TXCTRL1_DEEMPH_G1_MASK, 0x05);
267 
268 	val = readl(priv->base + RXCTRL);
269 	val &= ~RXCTRL_LOS_LVL_MASK;
270 	val |= FIELD_PREP(RXCTRL_LOS_LVL_MASK, 0x9);
271 	val &= ~RXCTRL_LOS_BIAS_MASK;
272 	val |= FIELD_PREP(RXCTRL_LOS_BIAS_MASK, 0x2);
273 	val &= ~RXCTRL_RX_EQ_MASK;
274 	val |= FIELD_PREP(RXCTRL_RX_EQ_MASK, 0x1);
275 
276 	/* dummy read 25 times to make a wait time for the phy to stabilize */
277 	for (i = 0; i < 25; i++)
278 		readl(priv->base + CKCTRL);
279 
280 	return 0;
281 }
282 
283 static int uniphier_ahciphy_init(struct phy *phy)
284 {
285 	struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
286 	int ret;
287 
288 	ret = clk_prepare_enable(priv->clk_parent_gio);
289 	if (ret)
290 		return ret;
291 
292 	ret = clk_prepare_enable(priv->clk_parent);
293 	if (ret)
294 		goto out_clk_gio_disable;
295 
296 	ret = reset_control_deassert(priv->rst_parent_gio);
297 	if (ret)
298 		goto out_clk_disable;
299 
300 	ret = reset_control_deassert(priv->rst_parent);
301 	if (ret)
302 		goto out_rst_gio_assert;
303 
304 	if (priv->data->init) {
305 		ret = priv->data->init(priv);
306 		if (ret)
307 			goto out_rst_assert;
308 	}
309 
310 	return 0;
311 
312 out_rst_assert:
313 	reset_control_assert(priv->rst_parent);
314 out_rst_gio_assert:
315 	reset_control_assert(priv->rst_parent_gio);
316 out_clk_disable:
317 	clk_disable_unprepare(priv->clk_parent);
318 out_clk_gio_disable:
319 	clk_disable_unprepare(priv->clk_parent_gio);
320 
321 	return ret;
322 }
323 
324 static int uniphier_ahciphy_exit(struct phy *phy)
325 {
326 	struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
327 
328 	reset_control_assert(priv->rst_parent);
329 	reset_control_assert(priv->rst_parent_gio);
330 	clk_disable_unprepare(priv->clk_parent);
331 	clk_disable_unprepare(priv->clk_parent_gio);
332 
333 	return 0;
334 }
335 
336 static int uniphier_ahciphy_power_on(struct phy *phy)
337 {
338 	struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
339 	int ret = 0;
340 
341 	ret = clk_prepare_enable(priv->clk);
342 	if (ret)
343 		return ret;
344 
345 	ret = reset_control_deassert(priv->rst);
346 	if (ret)
347 		goto out_clk_disable;
348 
349 	if (priv->data->power_on) {
350 		ret = priv->data->power_on(priv);
351 		if (ret)
352 			goto out_reset_assert;
353 	}
354 
355 	return 0;
356 
357 out_reset_assert:
358 	reset_control_assert(priv->rst);
359 out_clk_disable:
360 	clk_disable_unprepare(priv->clk);
361 
362 	return ret;
363 }
364 
365 static int uniphier_ahciphy_power_off(struct phy *phy)
366 {
367 	struct uniphier_ahciphy_priv *priv = phy_get_drvdata(phy);
368 	int ret = 0;
369 
370 	if (priv->data->power_off)
371 		ret = priv->data->power_off(priv);
372 
373 	reset_control_assert(priv->rst);
374 	clk_disable_unprepare(priv->clk);
375 
376 	return ret;
377 }
378 
379 static const struct phy_ops uniphier_ahciphy_ops = {
380 	.init  = uniphier_ahciphy_init,
381 	.exit  = uniphier_ahciphy_exit,
382 	.power_on  = uniphier_ahciphy_power_on,
383 	.power_off = uniphier_ahciphy_power_off,
384 	.owner = THIS_MODULE,
385 };
386 
387 static int uniphier_ahciphy_probe(struct platform_device *pdev)
388 {
389 	struct device *dev = &pdev->dev;
390 	struct uniphier_ahciphy_priv *priv;
391 	struct phy *phy;
392 	struct phy_provider *phy_provider;
393 
394 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
395 	if (!priv)
396 		return -ENOMEM;
397 
398 	priv->dev = dev;
399 	priv->data = of_device_get_match_data(dev);
400 	if (WARN_ON(!priv->data))
401 		return -EINVAL;
402 
403 	priv->base = devm_platform_ioremap_resource(pdev, 0);
404 	if (IS_ERR(priv->base))
405 		return PTR_ERR(priv->base);
406 
407 	priv->clk_parent = devm_clk_get(dev, "link");
408 	if (IS_ERR(priv->clk_parent))
409 		return PTR_ERR(priv->clk_parent);
410 
411 	if (priv->data->is_phy_clk) {
412 		priv->clk = devm_clk_get(dev, "phy");
413 		if (IS_ERR(priv->clk))
414 			return PTR_ERR(priv->clk);
415 	}
416 
417 	priv->rst_parent = devm_reset_control_get_shared(dev, "link");
418 	if (IS_ERR(priv->rst_parent))
419 		return PTR_ERR(priv->rst_parent);
420 
421 	priv->rst = devm_reset_control_get_shared(dev, "phy");
422 	if (IS_ERR(priv->rst))
423 		return PTR_ERR(priv->rst);
424 
425 	if (priv->data->is_legacy) {
426 		priv->clk_parent_gio = devm_clk_get(dev, "gio");
427 		if (IS_ERR(priv->clk_parent_gio))
428 			return PTR_ERR(priv->clk_parent_gio);
429 		priv->rst_parent_gio =
430 			devm_reset_control_get_shared(dev, "gio");
431 		if (IS_ERR(priv->rst_parent_gio))
432 			return PTR_ERR(priv->rst_parent_gio);
433 
434 		priv->rst_pm = devm_reset_control_get_shared(dev, "pm");
435 		if (IS_ERR(priv->rst_pm))
436 			return PTR_ERR(priv->rst_pm);
437 
438 		priv->rst_tx = devm_reset_control_get_shared(dev, "tx");
439 		if (IS_ERR(priv->rst_tx))
440 			return PTR_ERR(priv->rst_tx);
441 
442 		priv->rst_rx = devm_reset_control_get_shared(dev, "rx");
443 		if (IS_ERR(priv->rst_rx))
444 			return PTR_ERR(priv->rst_rx);
445 	}
446 
447 	phy = devm_phy_create(dev, dev->of_node, &uniphier_ahciphy_ops);
448 	if (IS_ERR(phy)) {
449 		dev_err(dev, "failed to create phy\n");
450 		return PTR_ERR(phy);
451 	}
452 
453 	phy_set_drvdata(phy, priv);
454 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
455 	if (IS_ERR(phy_provider))
456 		return PTR_ERR(phy_provider);
457 
458 	return 0;
459 }
460 
461 static const struct uniphier_ahciphy_soc_data uniphier_pro4_data = {
462 	.init = uniphier_ahciphy_pro4_init,
463 	.power_on  = uniphier_ahciphy_pro4_power_on,
464 	.power_off = uniphier_ahciphy_pro4_power_off,
465 	.is_legacy = true,
466 	.is_phy_clk = false,
467 };
468 
469 static const struct uniphier_ahciphy_soc_data uniphier_pxs2_data = {
470 	.power_on  = uniphier_ahciphy_pxs2_power_on,
471 	.power_off = uniphier_ahciphy_pxs2_power_off,
472 	.is_legacy = false,
473 	.is_ready_high = false,
474 	.is_phy_clk = false,
475 };
476 
477 static const struct uniphier_ahciphy_soc_data uniphier_pxs3_data = {
478 	.init      = uniphier_ahciphy_pxs3_init,
479 	.power_on  = uniphier_ahciphy_pxs2_power_on,
480 	.power_off = uniphier_ahciphy_pxs2_power_off,
481 	.is_legacy = false,
482 	.is_ready_high = true,
483 	.is_phy_clk = true,
484 };
485 
486 static const struct of_device_id uniphier_ahciphy_match[] = {
487 	{
488 		.compatible = "socionext,uniphier-pro4-ahci-phy",
489 		.data = &uniphier_pro4_data,
490 	},
491 	{
492 		.compatible = "socionext,uniphier-pxs2-ahci-phy",
493 		.data = &uniphier_pxs2_data,
494 	},
495 	{
496 		.compatible = "socionext,uniphier-pxs3-ahci-phy",
497 		.data = &uniphier_pxs3_data,
498 	},
499 	{ /* Sentinel */ },
500 };
501 MODULE_DEVICE_TABLE(of, uniphier_ahciphy_match);
502 
503 static struct platform_driver uniphier_ahciphy_driver = {
504 	.probe = uniphier_ahciphy_probe,
505 	.driver = {
506 		.name = "uniphier-ahci-phy",
507 		.of_match_table = uniphier_ahciphy_match,
508 	},
509 };
510 module_platform_driver(uniphier_ahciphy_driver);
511 
512 MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
513 MODULE_DESCRIPTION("UniPhier PHY driver for AHCI controller");
514 MODULE_LICENSE("GPL v2");
515