xref: /linux/drivers/phy/renesas/phy-rzg3e-usb3.c (revision 0623fdf30b1105c22f58baeeca954c803bdf5f8b)
1*ee5f1a3fSBiju Das // SPDX-License-Identifier: GPL-2.0
2*ee5f1a3fSBiju Das /*
3*ee5f1a3fSBiju Das  * Renesas RZ/G3E USB3.0 PHY driver
4*ee5f1a3fSBiju Das  *
5*ee5f1a3fSBiju Das  * Copyright (C) 2025 Renesas Electronics Corporation
6*ee5f1a3fSBiju Das  */
7*ee5f1a3fSBiju Das 
8*ee5f1a3fSBiju Das #include <linux/bitfield.h>
9*ee5f1a3fSBiju Das #include <linux/delay.h>
10*ee5f1a3fSBiju Das #include <linux/io.h>
11*ee5f1a3fSBiju Das #include <linux/iopoll.h>
12*ee5f1a3fSBiju Das #include <linux/module.h>
13*ee5f1a3fSBiju Das #include <linux/of.h>
14*ee5f1a3fSBiju Das #include <linux/phy/phy.h>
15*ee5f1a3fSBiju Das #include <linux/platform_device.h>
16*ee5f1a3fSBiju Das #include <linux/pm_runtime.h>
17*ee5f1a3fSBiju Das #include <linux/reset.h>
18*ee5f1a3fSBiju Das 
19*ee5f1a3fSBiju Das #define USB3_TEST_RESET				0x0000
20*ee5f1a3fSBiju Das #define USB3_TEST_UTMICTRL2			0x0b04
21*ee5f1a3fSBiju Das #define USB3_TEST_PRMCTRL5_R			0x0c10
22*ee5f1a3fSBiju Das #define USB3_TEST_PRMCTRL6_R			0x0c14
23*ee5f1a3fSBiju Das 
24*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL			0x1000
25*ee5f1a3fSBiju Das #define USB3_TEST_CLKCTRL			0x1004
26*ee5f1a3fSBiju Das #define USB3_TEST_RAMCTRL			0x100c
27*ee5f1a3fSBiju Das #define USB3_TEST_CREGCTRL			0x1010
28*ee5f1a3fSBiju Das #define USB3_TEST_LANECONFIG0			0x1030
29*ee5f1a3fSBiju Das 
30*ee5f1a3fSBiju Das #define USB3_TEST_RESET_PORTRESET0_CTRL		BIT(9)
31*ee5f1a3fSBiju Das #define USB3_TEST_RESET_SIDDQ			BIT(3)
32*ee5f1a3fSBiju Das #define USB3_TEST_RESET_PHY_RESET		BIT(2)
33*ee5f1a3fSBiju Das #define USB3_TEST_RESET_PORTRESET0		BIT(1)
34*ee5f1a3fSBiju Das #define USB3_TEST_RESET_RELEASE_OVERRIDE	(0)
35*ee5f1a3fSBiju Das 
36*ee5f1a3fSBiju Das #define USB3_TEST_UTMICTRL2_CTRL_MASK		GENMASK(9, 8)
37*ee5f1a3fSBiju Das #define USB3_TEST_UTMICTRL2_MODE_MASK		GENMASK(1, 0)
38*ee5f1a3fSBiju Das 
39*ee5f1a3fSBiju Das #define USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK	GENMASK(2, 1)
40*ee5f1a3fSBiju Das 
41*ee5f1a3fSBiju Das #define USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK	GENMASK(2, 0)
42*ee5f1a3fSBiju Das 
43*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_HARDRESET_ODEN	BIT(9)
44*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_PIPERESET_ODEN	BIT(8)
45*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_HARDRESET		BIT(1)
46*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_PIPERESET		BIT(0)
47*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_ASSERT	\
48*ee5f1a3fSBiju Das 	(USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \
49*ee5f1a3fSBiju Das 	 USB3_TEST_RSTCTRL_HARDRESET | USB3_TEST_RSTCTRL_PIPERESET)
50*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_RELEASE_HARDRESET	\
51*ee5f1a3fSBiju Das 	(USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN | \
52*ee5f1a3fSBiju Das 	 USB3_TEST_RSTCTRL_PIPERESET)
53*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_DEASSERT	\
54*ee5f1a3fSBiju Das 	(USB3_TEST_RSTCTRL_HARDRESET_ODEN | USB3_TEST_RSTCTRL_PIPERESET_ODEN)
55*ee5f1a3fSBiju Das #define USB3_TEST_RSTCTRL_RELEASE_OVERRIDE	(0)
56*ee5f1a3fSBiju Das 
57*ee5f1a3fSBiju Das #define USB3_TEST_CLKCTRL_MPLLA_SSC_EN		BIT(2)
58*ee5f1a3fSBiju Das 
59*ee5f1a3fSBiju Das #define USB3_TEST_RAMCTRL_SRAM_INIT_DONE	BIT(2)
60*ee5f1a3fSBiju Das #define USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE	BIT(0)
61*ee5f1a3fSBiju Das 
62*ee5f1a3fSBiju Das #define USB3_TEST_CREGCTRL_PARA_SEL		BIT(8)
63*ee5f1a3fSBiju Das 
64*ee5f1a3fSBiju Das #define USB3_TEST_LANECONFIG0_DEFAULT		(0xd)
65*ee5f1a3fSBiju Das 
66*ee5f1a3fSBiju Das struct rz_usb3 {
67*ee5f1a3fSBiju Das 	void __iomem *base;
68*ee5f1a3fSBiju Das 	struct reset_control *rstc;
69*ee5f1a3fSBiju Das 	bool skip_reinit;
70*ee5f1a3fSBiju Das };
71*ee5f1a3fSBiju Das 
rzg3e_phy_usb2test_phy_init(void __iomem * base)72*ee5f1a3fSBiju Das static void rzg3e_phy_usb2test_phy_init(void __iomem *base)
73*ee5f1a3fSBiju Das {
74*ee5f1a3fSBiju Das 	u32 val;
75*ee5f1a3fSBiju Das 
76*ee5f1a3fSBiju Das 	val = readl(base + USB3_TEST_UTMICTRL2);
77*ee5f1a3fSBiju Das 	val |= USB3_TEST_UTMICTRL2_CTRL_MASK | USB3_TEST_UTMICTRL2_MODE_MASK;
78*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_UTMICTRL2);
79*ee5f1a3fSBiju Das 
80*ee5f1a3fSBiju Das 	val = readl(base + USB3_TEST_PRMCTRL5_R);
81*ee5f1a3fSBiju Das 	val &= ~USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK;
82*ee5f1a3fSBiju Das 	val |= FIELD_PREP(USB3_TEST_PRMCTRL5_R_TXPREEMPAMPTUNE0_MASK, 2);
83*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_PRMCTRL5_R);
84*ee5f1a3fSBiju Das 
85*ee5f1a3fSBiju Das 	val = readl(base + USB3_TEST_PRMCTRL6_R);
86*ee5f1a3fSBiju Das 	val &= ~USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK;
87*ee5f1a3fSBiju Das 	val |= FIELD_PREP(USB3_TEST_PRMCTRL6_R_OTGTUNE0_MASK, 7);
88*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_PRMCTRL6_R);
89*ee5f1a3fSBiju Das 
90*ee5f1a3fSBiju Das 	val = readl(base + USB3_TEST_RESET);
91*ee5f1a3fSBiju Das 	val &= ~USB3_TEST_RESET_SIDDQ;
92*ee5f1a3fSBiju Das 	val |= USB3_TEST_RESET_PORTRESET0_CTRL | USB3_TEST_RESET_PHY_RESET |
93*ee5f1a3fSBiju Das 	       USB3_TEST_RESET_PORTRESET0;
94*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_RESET);
95*ee5f1a3fSBiju Das 	fsleep(10);
96*ee5f1a3fSBiju Das 
97*ee5f1a3fSBiju Das 	val &= ~(USB3_TEST_RESET_PHY_RESET | USB3_TEST_RESET_PORTRESET0);
98*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_RESET);
99*ee5f1a3fSBiju Das 	fsleep(10);
100*ee5f1a3fSBiju Das 
101*ee5f1a3fSBiju Das 	val = readl(base + USB3_TEST_UTMICTRL2);
102*ee5f1a3fSBiju Das 	val &= ~USB3_TEST_UTMICTRL2_CTRL_MASK;
103*ee5f1a3fSBiju Das 	writel(val, base + USB3_TEST_UTMICTRL2);
104*ee5f1a3fSBiju Das 
105*ee5f1a3fSBiju Das 	writel(USB3_TEST_RESET_RELEASE_OVERRIDE, base + USB3_TEST_RESET);
106*ee5f1a3fSBiju Das }
107*ee5f1a3fSBiju Das 
rzg3e_phy_usb3test_phy_init(void __iomem * base)108*ee5f1a3fSBiju Das static int rzg3e_phy_usb3test_phy_init(void __iomem *base)
109*ee5f1a3fSBiju Das {
110*ee5f1a3fSBiju Das 	int ret;
111*ee5f1a3fSBiju Das 	u32 val;
112*ee5f1a3fSBiju Das 
113*ee5f1a3fSBiju Das 	writel(USB3_TEST_CREGCTRL_PARA_SEL, base + USB3_TEST_CREGCTRL);
114*ee5f1a3fSBiju Das 	writel(USB3_TEST_RSTCTRL_ASSERT, base + USB3_TEST_RSTCTRL);
115*ee5f1a3fSBiju Das 	fsleep(20);
116*ee5f1a3fSBiju Das 
117*ee5f1a3fSBiju Das 	writel(USB3_TEST_CLKCTRL_MPLLA_SSC_EN, base + USB3_TEST_CLKCTRL);
118*ee5f1a3fSBiju Das 	writel(USB3_TEST_LANECONFIG0_DEFAULT, base + USB3_TEST_LANECONFIG0);
119*ee5f1a3fSBiju Das 	writel(USB3_TEST_RSTCTRL_RELEASE_HARDRESET, base + USB3_TEST_RSTCTRL);
120*ee5f1a3fSBiju Das 
121*ee5f1a3fSBiju Das 	ret = readl_poll_timeout_atomic(base + USB3_TEST_RAMCTRL, val,
122*ee5f1a3fSBiju Das 					val & USB3_TEST_RAMCTRL_SRAM_INIT_DONE, 1, 10000);
123*ee5f1a3fSBiju Das 	if (ret)
124*ee5f1a3fSBiju Das 		return ret;
125*ee5f1a3fSBiju Das 
126*ee5f1a3fSBiju Das 	writel(USB3_TEST_RSTCTRL_DEASSERT, base + USB3_TEST_RSTCTRL);
127*ee5f1a3fSBiju Das 	writel(USB3_TEST_RAMCTRL_SRAM_EXT_LD_DONE, base + USB3_TEST_RAMCTRL);
128*ee5f1a3fSBiju Das 	writel(USB3_TEST_RSTCTRL_RELEASE_OVERRIDE, base + USB3_TEST_RSTCTRL);
129*ee5f1a3fSBiju Das 
130*ee5f1a3fSBiju Das 	return 0;
131*ee5f1a3fSBiju Das }
132*ee5f1a3fSBiju Das 
rzg3e_phy_usb3_init_helper(void __iomem * base)133*ee5f1a3fSBiju Das static int rzg3e_phy_usb3_init_helper(void __iomem *base)
134*ee5f1a3fSBiju Das {
135*ee5f1a3fSBiju Das 	rzg3e_phy_usb2test_phy_init(base);
136*ee5f1a3fSBiju Das 
137*ee5f1a3fSBiju Das 	return rzg3e_phy_usb3test_phy_init(base);
138*ee5f1a3fSBiju Das }
139*ee5f1a3fSBiju Das 
rzg3e_phy_usb3_init(struct phy * p)140*ee5f1a3fSBiju Das static int rzg3e_phy_usb3_init(struct phy *p)
141*ee5f1a3fSBiju Das {
142*ee5f1a3fSBiju Das 	struct rz_usb3 *r = phy_get_drvdata(p);
143*ee5f1a3fSBiju Das 	int ret = 0;
144*ee5f1a3fSBiju Das 
145*ee5f1a3fSBiju Das 	if (!r->skip_reinit)
146*ee5f1a3fSBiju Das 		ret = rzg3e_phy_usb3_init_helper(r->base);
147*ee5f1a3fSBiju Das 
148*ee5f1a3fSBiju Das 	return ret;
149*ee5f1a3fSBiju Das }
150*ee5f1a3fSBiju Das 
151*ee5f1a3fSBiju Das static const struct phy_ops rzg3e_phy_usb3_ops = {
152*ee5f1a3fSBiju Das 	.init = rzg3e_phy_usb3_init,
153*ee5f1a3fSBiju Das 	.owner = THIS_MODULE,
154*ee5f1a3fSBiju Das };
155*ee5f1a3fSBiju Das 
rzg3e_phy_usb3_probe(struct platform_device * pdev)156*ee5f1a3fSBiju Das static int rzg3e_phy_usb3_probe(struct platform_device *pdev)
157*ee5f1a3fSBiju Das {
158*ee5f1a3fSBiju Das 	struct device *dev = &pdev->dev;
159*ee5f1a3fSBiju Das 	struct phy_provider *provider;
160*ee5f1a3fSBiju Das 	struct rz_usb3 *r;
161*ee5f1a3fSBiju Das 	struct phy *phy;
162*ee5f1a3fSBiju Das 	int ret;
163*ee5f1a3fSBiju Das 
164*ee5f1a3fSBiju Das 	r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
165*ee5f1a3fSBiju Das 	if (!r)
166*ee5f1a3fSBiju Das 		return -ENOMEM;
167*ee5f1a3fSBiju Das 
168*ee5f1a3fSBiju Das 	r->base = devm_platform_ioremap_resource(pdev, 0);
169*ee5f1a3fSBiju Das 	if (IS_ERR(r->base))
170*ee5f1a3fSBiju Das 		return PTR_ERR(r->base);
171*ee5f1a3fSBiju Das 
172*ee5f1a3fSBiju Das 	r->rstc = devm_reset_control_get_shared_deasserted(dev, NULL);
173*ee5f1a3fSBiju Das 	if (IS_ERR(r->rstc))
174*ee5f1a3fSBiju Das 		return dev_err_probe(dev, PTR_ERR(r->rstc), "failed to get deasserted reset\n");
175*ee5f1a3fSBiju Das 
176*ee5f1a3fSBiju Das 	/*
177*ee5f1a3fSBiju Das 	 * devm_phy_create() will call pm_runtime_enable(&phy->dev);
178*ee5f1a3fSBiju Das 	 * And then, phy-core will manage runtime pm for this device.
179*ee5f1a3fSBiju Das 	 */
180*ee5f1a3fSBiju Das 	ret = devm_pm_runtime_enable(dev);
181*ee5f1a3fSBiju Das 	if (ret < 0)
182*ee5f1a3fSBiju Das 		return ret;
183*ee5f1a3fSBiju Das 
184*ee5f1a3fSBiju Das 	phy = devm_phy_create(dev, NULL, &rzg3e_phy_usb3_ops);
185*ee5f1a3fSBiju Das 	if (IS_ERR(phy))
186*ee5f1a3fSBiju Das 		return dev_err_probe(dev, PTR_ERR(phy), "failed to create USB3 PHY\n");
187*ee5f1a3fSBiju Das 
188*ee5f1a3fSBiju Das 	platform_set_drvdata(pdev, r);
189*ee5f1a3fSBiju Das 	phy_set_drvdata(phy, r);
190*ee5f1a3fSBiju Das 
191*ee5f1a3fSBiju Das 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
192*ee5f1a3fSBiju Das 	if (IS_ERR(provider))
193*ee5f1a3fSBiju Das 		return dev_err_probe(dev, PTR_ERR(provider), "failed to register PHY provider\n");
194*ee5f1a3fSBiju Das 
195*ee5f1a3fSBiju Das 	return 0;
196*ee5f1a3fSBiju Das }
197*ee5f1a3fSBiju Das 
rzg3e_phy_usb3_suspend(struct device * dev)198*ee5f1a3fSBiju Das static int rzg3e_phy_usb3_suspend(struct device *dev)
199*ee5f1a3fSBiju Das {
200*ee5f1a3fSBiju Das 	struct rz_usb3 *r = dev_get_drvdata(dev);
201*ee5f1a3fSBiju Das 
202*ee5f1a3fSBiju Das 	pm_runtime_put(dev);
203*ee5f1a3fSBiju Das 	reset_control_assert(r->rstc);
204*ee5f1a3fSBiju Das 	r->skip_reinit = false;
205*ee5f1a3fSBiju Das 
206*ee5f1a3fSBiju Das 	return 0;
207*ee5f1a3fSBiju Das }
208*ee5f1a3fSBiju Das 
rzg3e_phy_usb3_resume(struct device * dev)209*ee5f1a3fSBiju Das static int rzg3e_phy_usb3_resume(struct device *dev)
210*ee5f1a3fSBiju Das {
211*ee5f1a3fSBiju Das 	struct rz_usb3 *r = dev_get_drvdata(dev);
212*ee5f1a3fSBiju Das 	int ret;
213*ee5f1a3fSBiju Das 
214*ee5f1a3fSBiju Das 	ret = reset_control_deassert(r->rstc);
215*ee5f1a3fSBiju Das 	if (ret)
216*ee5f1a3fSBiju Das 		return ret;
217*ee5f1a3fSBiju Das 
218*ee5f1a3fSBiju Das 	ret = pm_runtime_resume_and_get(dev);
219*ee5f1a3fSBiju Das 	if (ret)
220*ee5f1a3fSBiju Das 		goto reset_assert;
221*ee5f1a3fSBiju Das 
222*ee5f1a3fSBiju Das 	ret = rzg3e_phy_usb3_init_helper(r->base);
223*ee5f1a3fSBiju Das 	if (ret)
224*ee5f1a3fSBiju Das 		goto pm_put;
225*ee5f1a3fSBiju Das 
226*ee5f1a3fSBiju Das 	r->skip_reinit = true;
227*ee5f1a3fSBiju Das 
228*ee5f1a3fSBiju Das 	return 0;
229*ee5f1a3fSBiju Das 
230*ee5f1a3fSBiju Das pm_put:
231*ee5f1a3fSBiju Das 	pm_runtime_put(dev);
232*ee5f1a3fSBiju Das reset_assert:
233*ee5f1a3fSBiju Das 	reset_control_assert(r->rstc);
234*ee5f1a3fSBiju Das 	return ret;
235*ee5f1a3fSBiju Das }
236*ee5f1a3fSBiju Das 
237*ee5f1a3fSBiju Das static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
238*ee5f1a3fSBiju Das 	NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
239*ee5f1a3fSBiju Das };
240*ee5f1a3fSBiju Das 
241*ee5f1a3fSBiju Das static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
242*ee5f1a3fSBiju Das 	{ .compatible = "renesas,r9a09g047-usb3-phy" },
243*ee5f1a3fSBiju Das 	{ /* Sentinel */ }
244*ee5f1a3fSBiju Das };
245*ee5f1a3fSBiju Das 
246*ee5f1a3fSBiju Das MODULE_DEVICE_TABLE(of, rzg3e_phy_usb3_match_table);
247*ee5f1a3fSBiju Das static struct platform_driver rzg3e_phy_usb3_driver = {
248*ee5f1a3fSBiju Das 	.driver = {
249*ee5f1a3fSBiju Das 		.name = "phy_rzg3e_usb3",
250*ee5f1a3fSBiju Das 		.of_match_table = rzg3e_phy_usb3_match_table,
251*ee5f1a3fSBiju Das 		.pm = pm_sleep_ptr(&rzg3e_phy_usb3_pm),
252*ee5f1a3fSBiju Das 	},
253*ee5f1a3fSBiju Das 	.probe	= rzg3e_phy_usb3_probe,
254*ee5f1a3fSBiju Das };
255*ee5f1a3fSBiju Das module_platform_driver(rzg3e_phy_usb3_driver);
256*ee5f1a3fSBiju Das 
257*ee5f1a3fSBiju Das MODULE_LICENSE("GPL");
258*ee5f1a3fSBiju Das MODULE_DESCRIPTION("Renesas RZ/G3E USB3.0 PHY Driver");
259*ee5f1a3fSBiju Das MODULE_AUTHOR("biju.das.jz@bp.renesas.com>");
260