xref: /linux/drivers/phy/socionext/phy-uniphier-usb3ss.c (revision 5ab43d0f86979d6741c1dda685af3e053982e03e)
1*5ab43d0fSKunihiko Hayashi // SPDX-License-Identifier: GPL-2.0
2*5ab43d0fSKunihiko Hayashi /*
3*5ab43d0fSKunihiko Hayashi  * phy-uniphier-usb3ss.c - SS-PHY driver for Socionext UniPhier USB3 controller
4*5ab43d0fSKunihiko Hayashi  * Copyright 2015-2018 Socionext Inc.
5*5ab43d0fSKunihiko Hayashi  * Author:
6*5ab43d0fSKunihiko Hayashi  *      Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
7*5ab43d0fSKunihiko Hayashi  * Contributors:
8*5ab43d0fSKunihiko Hayashi  *      Motoya Tanigawa <tanigawa.motoya@socionext.com>
9*5ab43d0fSKunihiko Hayashi  *      Masami Hiramatsu <masami.hiramatsu@linaro.org>
10*5ab43d0fSKunihiko Hayashi  */
11*5ab43d0fSKunihiko Hayashi 
12*5ab43d0fSKunihiko Hayashi #include <linux/bitfield.h>
13*5ab43d0fSKunihiko Hayashi #include <linux/bitops.h>
14*5ab43d0fSKunihiko Hayashi #include <linux/clk.h>
15*5ab43d0fSKunihiko Hayashi #include <linux/io.h>
16*5ab43d0fSKunihiko Hayashi #include <linux/module.h>
17*5ab43d0fSKunihiko Hayashi #include <linux/of.h>
18*5ab43d0fSKunihiko Hayashi #include <linux/of_platform.h>
19*5ab43d0fSKunihiko Hayashi #include <linux/phy/phy.h>
20*5ab43d0fSKunihiko Hayashi #include <linux/platform_device.h>
21*5ab43d0fSKunihiko Hayashi #include <linux/regulator/consumer.h>
22*5ab43d0fSKunihiko Hayashi #include <linux/reset.h>
23*5ab43d0fSKunihiko Hayashi 
24*5ab43d0fSKunihiko Hayashi #define SSPHY_TESTI		0x0
25*5ab43d0fSKunihiko Hayashi #define SSPHY_TESTO		0x4
26*5ab43d0fSKunihiko Hayashi #define TESTI_DAT_MASK		GENMASK(13, 6)
27*5ab43d0fSKunihiko Hayashi #define TESTI_ADR_MASK		GENMASK(5, 1)
28*5ab43d0fSKunihiko Hayashi #define TESTI_WR_EN		BIT(0)
29*5ab43d0fSKunihiko Hayashi 
30*5ab43d0fSKunihiko Hayashi #define PHY_F(regno, msb, lsb) { (regno), (msb), (lsb) }
31*5ab43d0fSKunihiko Hayashi 
32*5ab43d0fSKunihiko Hayashi #define CDR_CPD_TRIM	PHY_F(7, 3, 0)	/* RxPLL charge pump current */
33*5ab43d0fSKunihiko Hayashi #define CDR_CPF_TRIM	PHY_F(8, 3, 0)	/* RxPLL charge pump current 2 */
34*5ab43d0fSKunihiko Hayashi #define TX_PLL_TRIM	PHY_F(9, 3, 0)	/* TxPLL charge pump current */
35*5ab43d0fSKunihiko Hayashi #define BGAP_TRIM	PHY_F(11, 3, 0)	/* Bandgap voltage */
36*5ab43d0fSKunihiko Hayashi #define CDR_TRIM	PHY_F(13, 6, 5)	/* Clock Data Recovery setting */
37*5ab43d0fSKunihiko Hayashi #define VCO_CTRL	PHY_F(26, 7, 4)	/* VCO control */
38*5ab43d0fSKunihiko Hayashi #define VCOPLL_CTRL	PHY_F(27, 2, 0)	/* TxPLL VCO tuning */
39*5ab43d0fSKunihiko Hayashi #define VCOPLL_CM	PHY_F(28, 1, 0)	/* TxPLL voltage */
40*5ab43d0fSKunihiko Hayashi 
41*5ab43d0fSKunihiko Hayashi #define MAX_PHY_PARAMS	7
42*5ab43d0fSKunihiko Hayashi 
43*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_param {
44*5ab43d0fSKunihiko Hayashi 	struct {
45*5ab43d0fSKunihiko Hayashi 		int reg_no;
46*5ab43d0fSKunihiko Hayashi 		int msb;
47*5ab43d0fSKunihiko Hayashi 		int lsb;
48*5ab43d0fSKunihiko Hayashi 	} field;
49*5ab43d0fSKunihiko Hayashi 	u8 value;
50*5ab43d0fSKunihiko Hayashi };
51*5ab43d0fSKunihiko Hayashi 
52*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv {
53*5ab43d0fSKunihiko Hayashi 	struct device *dev;
54*5ab43d0fSKunihiko Hayashi 	void __iomem *base;
55*5ab43d0fSKunihiko Hayashi 	struct clk *clk, *clk_ext, *clk_parent, *clk_parent_gio;
56*5ab43d0fSKunihiko Hayashi 	struct reset_control *rst, *rst_parent, *rst_parent_gio;
57*5ab43d0fSKunihiko Hayashi 	struct regulator *vbus;
58*5ab43d0fSKunihiko Hayashi 	const struct uniphier_u3ssphy_soc_data *data;
59*5ab43d0fSKunihiko Hayashi };
60*5ab43d0fSKunihiko Hayashi 
61*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_soc_data {
62*5ab43d0fSKunihiko Hayashi 	bool is_legacy;
63*5ab43d0fSKunihiko Hayashi 	int nparams;
64*5ab43d0fSKunihiko Hayashi 	const struct uniphier_u3ssphy_param param[MAX_PHY_PARAMS];
65*5ab43d0fSKunihiko Hayashi };
66*5ab43d0fSKunihiko Hayashi 
67*5ab43d0fSKunihiko Hayashi static void uniphier_u3ssphy_testio_write(struct uniphier_u3ssphy_priv *priv,
68*5ab43d0fSKunihiko Hayashi 					  u32 data)
69*5ab43d0fSKunihiko Hayashi {
70*5ab43d0fSKunihiko Hayashi 	/* need to read TESTO twice after accessing TESTI */
71*5ab43d0fSKunihiko Hayashi 	writel(data, priv->base + SSPHY_TESTI);
72*5ab43d0fSKunihiko Hayashi 	readl(priv->base + SSPHY_TESTO);
73*5ab43d0fSKunihiko Hayashi 	readl(priv->base + SSPHY_TESTO);
74*5ab43d0fSKunihiko Hayashi }
75*5ab43d0fSKunihiko Hayashi 
76*5ab43d0fSKunihiko Hayashi static void uniphier_u3ssphy_set_param(struct uniphier_u3ssphy_priv *priv,
77*5ab43d0fSKunihiko Hayashi 				       const struct uniphier_u3ssphy_param *p)
78*5ab43d0fSKunihiko Hayashi {
79*5ab43d0fSKunihiko Hayashi 	u32 val;
80*5ab43d0fSKunihiko Hayashi 	u8 field_mask = GENMASK(p->field.msb, p->field.lsb);
81*5ab43d0fSKunihiko Hayashi 	u8 data;
82*5ab43d0fSKunihiko Hayashi 
83*5ab43d0fSKunihiko Hayashi 	/* read previous data */
84*5ab43d0fSKunihiko Hayashi 	val  = FIELD_PREP(TESTI_DAT_MASK, 1);
85*5ab43d0fSKunihiko Hayashi 	val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no);
86*5ab43d0fSKunihiko Hayashi 	uniphier_u3ssphy_testio_write(priv, val);
87*5ab43d0fSKunihiko Hayashi 	val = readl(priv->base + SSPHY_TESTO);
88*5ab43d0fSKunihiko Hayashi 
89*5ab43d0fSKunihiko Hayashi 	/* update value */
90*5ab43d0fSKunihiko Hayashi 	val &= ~FIELD_PREP(TESTI_DAT_MASK, field_mask);
91*5ab43d0fSKunihiko Hayashi 	data = field_mask & (p->value << p->field.lsb);
92*5ab43d0fSKunihiko Hayashi 	val  = FIELD_PREP(TESTI_DAT_MASK, data);
93*5ab43d0fSKunihiko Hayashi 	val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no);
94*5ab43d0fSKunihiko Hayashi 	uniphier_u3ssphy_testio_write(priv, val);
95*5ab43d0fSKunihiko Hayashi 	uniphier_u3ssphy_testio_write(priv, val | TESTI_WR_EN);
96*5ab43d0fSKunihiko Hayashi 	uniphier_u3ssphy_testio_write(priv, val);
97*5ab43d0fSKunihiko Hayashi 
98*5ab43d0fSKunihiko Hayashi 	/* read current data as dummy */
99*5ab43d0fSKunihiko Hayashi 	val  = FIELD_PREP(TESTI_DAT_MASK, 1);
100*5ab43d0fSKunihiko Hayashi 	val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no);
101*5ab43d0fSKunihiko Hayashi 	uniphier_u3ssphy_testio_write(priv, val);
102*5ab43d0fSKunihiko Hayashi 	readl(priv->base + SSPHY_TESTO);
103*5ab43d0fSKunihiko Hayashi }
104*5ab43d0fSKunihiko Hayashi 
105*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_power_on(struct phy *phy)
106*5ab43d0fSKunihiko Hayashi {
107*5ab43d0fSKunihiko Hayashi 	struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy);
108*5ab43d0fSKunihiko Hayashi 	int ret;
109*5ab43d0fSKunihiko Hayashi 
110*5ab43d0fSKunihiko Hayashi 	ret = clk_prepare_enable(priv->clk_ext);
111*5ab43d0fSKunihiko Hayashi 	if (ret)
112*5ab43d0fSKunihiko Hayashi 		return ret;
113*5ab43d0fSKunihiko Hayashi 
114*5ab43d0fSKunihiko Hayashi 	ret = clk_prepare_enable(priv->clk);
115*5ab43d0fSKunihiko Hayashi 	if (ret)
116*5ab43d0fSKunihiko Hayashi 		goto out_clk_ext_disable;
117*5ab43d0fSKunihiko Hayashi 
118*5ab43d0fSKunihiko Hayashi 	ret = reset_control_deassert(priv->rst);
119*5ab43d0fSKunihiko Hayashi 	if (ret)
120*5ab43d0fSKunihiko Hayashi 		goto out_clk_disable;
121*5ab43d0fSKunihiko Hayashi 
122*5ab43d0fSKunihiko Hayashi 	if (priv->vbus) {
123*5ab43d0fSKunihiko Hayashi 		ret = regulator_enable(priv->vbus);
124*5ab43d0fSKunihiko Hayashi 		if (ret)
125*5ab43d0fSKunihiko Hayashi 			goto out_rst_assert;
126*5ab43d0fSKunihiko Hayashi 	}
127*5ab43d0fSKunihiko Hayashi 
128*5ab43d0fSKunihiko Hayashi 	return 0;
129*5ab43d0fSKunihiko Hayashi 
130*5ab43d0fSKunihiko Hayashi out_rst_assert:
131*5ab43d0fSKunihiko Hayashi 	reset_control_assert(priv->rst);
132*5ab43d0fSKunihiko Hayashi out_clk_disable:
133*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk);
134*5ab43d0fSKunihiko Hayashi out_clk_ext_disable:
135*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_ext);
136*5ab43d0fSKunihiko Hayashi 
137*5ab43d0fSKunihiko Hayashi 	return ret;
138*5ab43d0fSKunihiko Hayashi }
139*5ab43d0fSKunihiko Hayashi 
140*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_power_off(struct phy *phy)
141*5ab43d0fSKunihiko Hayashi {
142*5ab43d0fSKunihiko Hayashi 	struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy);
143*5ab43d0fSKunihiko Hayashi 
144*5ab43d0fSKunihiko Hayashi 	if (priv->vbus)
145*5ab43d0fSKunihiko Hayashi 		regulator_disable(priv->vbus);
146*5ab43d0fSKunihiko Hayashi 
147*5ab43d0fSKunihiko Hayashi 	reset_control_assert(priv->rst);
148*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk);
149*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_ext);
150*5ab43d0fSKunihiko Hayashi 
151*5ab43d0fSKunihiko Hayashi 	return 0;
152*5ab43d0fSKunihiko Hayashi }
153*5ab43d0fSKunihiko Hayashi 
154*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_init(struct phy *phy)
155*5ab43d0fSKunihiko Hayashi {
156*5ab43d0fSKunihiko Hayashi 	struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy);
157*5ab43d0fSKunihiko Hayashi 	int i, ret;
158*5ab43d0fSKunihiko Hayashi 
159*5ab43d0fSKunihiko Hayashi 	ret = clk_prepare_enable(priv->clk_parent);
160*5ab43d0fSKunihiko Hayashi 	if (ret)
161*5ab43d0fSKunihiko Hayashi 		return ret;
162*5ab43d0fSKunihiko Hayashi 
163*5ab43d0fSKunihiko Hayashi 	ret = clk_prepare_enable(priv->clk_parent_gio);
164*5ab43d0fSKunihiko Hayashi 	if (ret)
165*5ab43d0fSKunihiko Hayashi 		goto out_clk_disable;
166*5ab43d0fSKunihiko Hayashi 
167*5ab43d0fSKunihiko Hayashi 	ret = reset_control_deassert(priv->rst_parent);
168*5ab43d0fSKunihiko Hayashi 	if (ret)
169*5ab43d0fSKunihiko Hayashi 		goto out_clk_gio_disable;
170*5ab43d0fSKunihiko Hayashi 
171*5ab43d0fSKunihiko Hayashi 	ret = reset_control_deassert(priv->rst_parent_gio);
172*5ab43d0fSKunihiko Hayashi 	if (ret)
173*5ab43d0fSKunihiko Hayashi 		goto out_rst_assert;
174*5ab43d0fSKunihiko Hayashi 
175*5ab43d0fSKunihiko Hayashi 	if (priv->data->is_legacy)
176*5ab43d0fSKunihiko Hayashi 		return 0;
177*5ab43d0fSKunihiko Hayashi 
178*5ab43d0fSKunihiko Hayashi 	for (i = 0; i < priv->data->nparams; i++)
179*5ab43d0fSKunihiko Hayashi 		uniphier_u3ssphy_set_param(priv, &priv->data->param[i]);
180*5ab43d0fSKunihiko Hayashi 
181*5ab43d0fSKunihiko Hayashi 	return 0;
182*5ab43d0fSKunihiko Hayashi 
183*5ab43d0fSKunihiko Hayashi out_rst_assert:
184*5ab43d0fSKunihiko Hayashi 	reset_control_assert(priv->rst_parent);
185*5ab43d0fSKunihiko Hayashi out_clk_gio_disable:
186*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_parent_gio);
187*5ab43d0fSKunihiko Hayashi out_clk_disable:
188*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_parent);
189*5ab43d0fSKunihiko Hayashi 
190*5ab43d0fSKunihiko Hayashi 	return ret;
191*5ab43d0fSKunihiko Hayashi }
192*5ab43d0fSKunihiko Hayashi 
193*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_exit(struct phy *phy)
194*5ab43d0fSKunihiko Hayashi {
195*5ab43d0fSKunihiko Hayashi 	struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy);
196*5ab43d0fSKunihiko Hayashi 
197*5ab43d0fSKunihiko Hayashi 	reset_control_assert(priv->rst_parent_gio);
198*5ab43d0fSKunihiko Hayashi 	reset_control_assert(priv->rst_parent);
199*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_parent_gio);
200*5ab43d0fSKunihiko Hayashi 	clk_disable_unprepare(priv->clk_parent);
201*5ab43d0fSKunihiko Hayashi 
202*5ab43d0fSKunihiko Hayashi 	return 0;
203*5ab43d0fSKunihiko Hayashi }
204*5ab43d0fSKunihiko Hayashi 
205*5ab43d0fSKunihiko Hayashi static const struct phy_ops uniphier_u3ssphy_ops = {
206*5ab43d0fSKunihiko Hayashi 	.init           = uniphier_u3ssphy_init,
207*5ab43d0fSKunihiko Hayashi 	.exit           = uniphier_u3ssphy_exit,
208*5ab43d0fSKunihiko Hayashi 	.power_on       = uniphier_u3ssphy_power_on,
209*5ab43d0fSKunihiko Hayashi 	.power_off      = uniphier_u3ssphy_power_off,
210*5ab43d0fSKunihiko Hayashi 	.owner          = THIS_MODULE,
211*5ab43d0fSKunihiko Hayashi };
212*5ab43d0fSKunihiko Hayashi 
213*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_probe(struct platform_device *pdev)
214*5ab43d0fSKunihiko Hayashi {
215*5ab43d0fSKunihiko Hayashi 	struct device *dev = &pdev->dev;
216*5ab43d0fSKunihiko Hayashi 	struct uniphier_u3ssphy_priv *priv;
217*5ab43d0fSKunihiko Hayashi 	struct phy_provider *phy_provider;
218*5ab43d0fSKunihiko Hayashi 	struct resource *res;
219*5ab43d0fSKunihiko Hayashi 	struct phy *phy;
220*5ab43d0fSKunihiko Hayashi 
221*5ab43d0fSKunihiko Hayashi 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
222*5ab43d0fSKunihiko Hayashi 	if (!priv)
223*5ab43d0fSKunihiko Hayashi 		return -ENOMEM;
224*5ab43d0fSKunihiko Hayashi 
225*5ab43d0fSKunihiko Hayashi 	priv->dev = dev;
226*5ab43d0fSKunihiko Hayashi 	priv->data = of_device_get_match_data(dev);
227*5ab43d0fSKunihiko Hayashi 	if (WARN_ON(!priv->data ||
228*5ab43d0fSKunihiko Hayashi 		    priv->data->nparams > MAX_PHY_PARAMS))
229*5ab43d0fSKunihiko Hayashi 		return -EINVAL;
230*5ab43d0fSKunihiko Hayashi 
231*5ab43d0fSKunihiko Hayashi 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
232*5ab43d0fSKunihiko Hayashi 	priv->base = devm_ioremap_resource(dev, res);
233*5ab43d0fSKunihiko Hayashi 	if (IS_ERR(priv->base))
234*5ab43d0fSKunihiko Hayashi 		return PTR_ERR(priv->base);
235*5ab43d0fSKunihiko Hayashi 
236*5ab43d0fSKunihiko Hayashi 	if (!priv->data->is_legacy) {
237*5ab43d0fSKunihiko Hayashi 		priv->clk = devm_clk_get(dev, "phy");
238*5ab43d0fSKunihiko Hayashi 		if (IS_ERR(priv->clk))
239*5ab43d0fSKunihiko Hayashi 			return PTR_ERR(priv->clk);
240*5ab43d0fSKunihiko Hayashi 
241*5ab43d0fSKunihiko Hayashi 		priv->clk_ext = devm_clk_get(dev, "phy-ext");
242*5ab43d0fSKunihiko Hayashi 		if (IS_ERR(priv->clk_ext)) {
243*5ab43d0fSKunihiko Hayashi 			if (PTR_ERR(priv->clk_ext) == -ENOENT)
244*5ab43d0fSKunihiko Hayashi 				priv->clk_ext = NULL;
245*5ab43d0fSKunihiko Hayashi 			else
246*5ab43d0fSKunihiko Hayashi 				return PTR_ERR(priv->clk_ext);
247*5ab43d0fSKunihiko Hayashi 		}
248*5ab43d0fSKunihiko Hayashi 
249*5ab43d0fSKunihiko Hayashi 		priv->rst = devm_reset_control_get_shared(dev, "phy");
250*5ab43d0fSKunihiko Hayashi 		if (IS_ERR(priv->rst))
251*5ab43d0fSKunihiko Hayashi 			return PTR_ERR(priv->rst);
252*5ab43d0fSKunihiko Hayashi 	} else {
253*5ab43d0fSKunihiko Hayashi 		priv->clk_parent_gio = devm_clk_get(dev, "gio");
254*5ab43d0fSKunihiko Hayashi 		if (IS_ERR(priv->clk_parent_gio))
255*5ab43d0fSKunihiko Hayashi 			return PTR_ERR(priv->clk_parent_gio);
256*5ab43d0fSKunihiko Hayashi 
257*5ab43d0fSKunihiko Hayashi 		priv->rst_parent_gio =
258*5ab43d0fSKunihiko Hayashi 			devm_reset_control_get_shared(dev, "gio");
259*5ab43d0fSKunihiko Hayashi 		if (IS_ERR(priv->rst_parent_gio))
260*5ab43d0fSKunihiko Hayashi 			return PTR_ERR(priv->rst_parent_gio);
261*5ab43d0fSKunihiko Hayashi 	}
262*5ab43d0fSKunihiko Hayashi 
263*5ab43d0fSKunihiko Hayashi 	priv->clk_parent = devm_clk_get(dev, "link");
264*5ab43d0fSKunihiko Hayashi 	if (IS_ERR(priv->clk_parent))
265*5ab43d0fSKunihiko Hayashi 		return PTR_ERR(priv->clk_parent);
266*5ab43d0fSKunihiko Hayashi 
267*5ab43d0fSKunihiko Hayashi 	priv->rst_parent = devm_reset_control_get_shared(dev, "link");
268*5ab43d0fSKunihiko Hayashi 	if (IS_ERR(priv->rst_parent))
269*5ab43d0fSKunihiko Hayashi 		return PTR_ERR(priv->rst_parent);
270*5ab43d0fSKunihiko Hayashi 
271*5ab43d0fSKunihiko Hayashi 	priv->vbus = devm_regulator_get_optional(dev, "vbus");
272*5ab43d0fSKunihiko Hayashi 	if (IS_ERR(priv->vbus)) {
273*5ab43d0fSKunihiko Hayashi 		if (PTR_ERR(priv->vbus) == -EPROBE_DEFER)
274*5ab43d0fSKunihiko Hayashi 			return PTR_ERR(priv->vbus);
275*5ab43d0fSKunihiko Hayashi 		priv->vbus = NULL;
276*5ab43d0fSKunihiko Hayashi 	}
277*5ab43d0fSKunihiko Hayashi 
278*5ab43d0fSKunihiko Hayashi 	phy = devm_phy_create(dev, dev->of_node, &uniphier_u3ssphy_ops);
279*5ab43d0fSKunihiko Hayashi 	if (IS_ERR(phy))
280*5ab43d0fSKunihiko Hayashi 		return PTR_ERR(phy);
281*5ab43d0fSKunihiko Hayashi 
282*5ab43d0fSKunihiko Hayashi 	phy_set_drvdata(phy, priv);
283*5ab43d0fSKunihiko Hayashi 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
284*5ab43d0fSKunihiko Hayashi 
285*5ab43d0fSKunihiko Hayashi 	return PTR_ERR_OR_ZERO(phy_provider);
286*5ab43d0fSKunihiko Hayashi }
287*5ab43d0fSKunihiko Hayashi 
288*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_pro4_data = {
289*5ab43d0fSKunihiko Hayashi 	.is_legacy = true,
290*5ab43d0fSKunihiko Hayashi };
291*5ab43d0fSKunihiko Hayashi 
292*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_pxs2_data = {
293*5ab43d0fSKunihiko Hayashi 	.is_legacy = false,
294*5ab43d0fSKunihiko Hayashi 	.nparams = 7,
295*5ab43d0fSKunihiko Hayashi 	.param = {
296*5ab43d0fSKunihiko Hayashi 		{ CDR_CPD_TRIM, 10 },
297*5ab43d0fSKunihiko Hayashi 		{ CDR_CPF_TRIM, 3 },
298*5ab43d0fSKunihiko Hayashi 		{ TX_PLL_TRIM, 5 },
299*5ab43d0fSKunihiko Hayashi 		{ BGAP_TRIM, 9 },
300*5ab43d0fSKunihiko Hayashi 		{ CDR_TRIM, 2 },
301*5ab43d0fSKunihiko Hayashi 		{ VCOPLL_CTRL, 7 },
302*5ab43d0fSKunihiko Hayashi 		{ VCOPLL_CM, 1 },
303*5ab43d0fSKunihiko Hayashi 	},
304*5ab43d0fSKunihiko Hayashi };
305*5ab43d0fSKunihiko Hayashi 
306*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_ld20_data = {
307*5ab43d0fSKunihiko Hayashi 	.is_legacy = false,
308*5ab43d0fSKunihiko Hayashi 	.nparams = 3,
309*5ab43d0fSKunihiko Hayashi 	.param = {
310*5ab43d0fSKunihiko Hayashi 		{ CDR_CPD_TRIM, 6 },
311*5ab43d0fSKunihiko Hayashi 		{ CDR_TRIM, 2 },
312*5ab43d0fSKunihiko Hayashi 		{ VCO_CTRL, 5 },
313*5ab43d0fSKunihiko Hayashi 	},
314*5ab43d0fSKunihiko Hayashi };
315*5ab43d0fSKunihiko Hayashi 
316*5ab43d0fSKunihiko Hayashi static const struct of_device_id uniphier_u3ssphy_match[] = {
317*5ab43d0fSKunihiko Hayashi 	{
318*5ab43d0fSKunihiko Hayashi 		.compatible = "socionext,uniphier-pro4-usb3-ssphy",
319*5ab43d0fSKunihiko Hayashi 		.data = &uniphier_pro4_data,
320*5ab43d0fSKunihiko Hayashi 	},
321*5ab43d0fSKunihiko Hayashi 	{
322*5ab43d0fSKunihiko Hayashi 		.compatible = "socionext,uniphier-pxs2-usb3-ssphy",
323*5ab43d0fSKunihiko Hayashi 		.data = &uniphier_pxs2_data,
324*5ab43d0fSKunihiko Hayashi 	},
325*5ab43d0fSKunihiko Hayashi 	{
326*5ab43d0fSKunihiko Hayashi 		.compatible = "socionext,uniphier-ld20-usb3-ssphy",
327*5ab43d0fSKunihiko Hayashi 		.data = &uniphier_ld20_data,
328*5ab43d0fSKunihiko Hayashi 	},
329*5ab43d0fSKunihiko Hayashi 	{
330*5ab43d0fSKunihiko Hayashi 		.compatible = "socionext,uniphier-pxs3-usb3-ssphy",
331*5ab43d0fSKunihiko Hayashi 		.data = &uniphier_ld20_data,
332*5ab43d0fSKunihiko Hayashi 	},
333*5ab43d0fSKunihiko Hayashi 	{ /* sentinel */ }
334*5ab43d0fSKunihiko Hayashi };
335*5ab43d0fSKunihiko Hayashi MODULE_DEVICE_TABLE(of, uniphier_u3ssphy_match);
336*5ab43d0fSKunihiko Hayashi 
337*5ab43d0fSKunihiko Hayashi static struct platform_driver uniphier_u3ssphy_driver = {
338*5ab43d0fSKunihiko Hayashi 	.probe = uniphier_u3ssphy_probe,
339*5ab43d0fSKunihiko Hayashi 	.driver	= {
340*5ab43d0fSKunihiko Hayashi 		.name = "uniphier-usb3-ssphy",
341*5ab43d0fSKunihiko Hayashi 		.of_match_table	= uniphier_u3ssphy_match,
342*5ab43d0fSKunihiko Hayashi 	},
343*5ab43d0fSKunihiko Hayashi };
344*5ab43d0fSKunihiko Hayashi 
345*5ab43d0fSKunihiko Hayashi module_platform_driver(uniphier_u3ssphy_driver);
346*5ab43d0fSKunihiko Hayashi 
347*5ab43d0fSKunihiko Hayashi MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
348*5ab43d0fSKunihiko Hayashi MODULE_DESCRIPTION("UniPhier SS-PHY driver for USB3 controller");
349*5ab43d0fSKunihiko Hayashi MODULE_LICENSE("GPL v2");
350