1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2014-2023, The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/clk.h>
7 #include <linux/delay.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/phy/phy.h>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
16 #include <linux/slab.h>
17
18 #define USB2PHY_PORT_UTMI_CTRL1 0x40
19
20 #define USB2PHY_PORT_UTMI_CTRL2 0x44
21 #define UTMI_ULPI_SEL BIT(7)
22 #define UTMI_TEST_MUX_SEL BIT(6)
23
24 #define HS_PHY_CTRL_REG 0x10
25 #define UTMI_OTG_VBUS_VALID BIT(20)
26 #define SW_SESSVLD_SEL BIT(28)
27
28 #define USB_PHY_UTMI_CTRL0 0x3c
29
30 #define USB_PHY_UTMI_CTRL5 0x50
31 #define POR_EN BIT(1)
32
33 #define USB_PHY_HS_PHY_CTRL_COMMON0 0x54
34 #define COMMONONN BIT(7)
35 #define FSEL BIT(4)
36 #define RETENABLEN BIT(3)
37 #define FREQ_24MHZ (BIT(6) | BIT(4))
38
39 #define USB_PHY_HS_PHY_CTRL2 0x64
40 #define USB2_SUSPEND_N_SEL BIT(3)
41 #define USB2_SUSPEND_N BIT(2)
42 #define USB2_UTMI_CLK_EN BIT(1)
43
44 #define USB_PHY_CFG0 0x94
45 #define UTMI_PHY_OVERRIDE_EN BIT(1)
46
47 #define USB_PHY_REFCLK_CTRL 0xa0
48 #define CLKCORE BIT(1)
49
50 #define USB2PHY_PORT_POWERDOWN 0xa4
51 #define POWER_UP BIT(0)
52 #define POWER_DOWN 0
53
54 #define USB_PHY_FSEL_SEL 0xb8
55 #define FREQ_SEL BIT(0)
56
57 #define USB2PHY_USB_PHY_M31_XCFGI_1 0xbc
58 #define USB2_0_TX_ENABLE BIT(2)
59
60 #define USB2PHY_USB_PHY_M31_XCFGI_4 0xc8
61 #define HSTX_SLEW_RATE_400PS GENMASK(2, 0)
62 #define PLL_CHARGING_PUMP_CURRENT_35UA GENMASK(4, 3)
63 #define ODT_VALUE_38_02_OHM GENMASK(7, 6)
64
65 #define USB2PHY_USB_PHY_M31_XCFGI_5 0xcc
66 #define HSTX_PRE_EMPHASIS_LEVEL_0_55MA BIT(0)
67
68 #define USB2PHY_USB_PHY_M31_XCFGI_9 0xdc
69 #define HSTX_CURRENT_17_1MA_385MV BIT(1)
70
71 #define USB2PHY_USB_PHY_M31_XCFGI_11 0xe4
72 #define XCFG_COARSE_TUNE_NUM BIT(1)
73 #define XCFG_FINE_TUNE_NUM BIT(3)
74
75 struct m31_phy_regs {
76 u32 off;
77 u32 val;
78 u32 delay;
79 };
80
81 struct m31_priv_data {
82 bool ulpi_mode;
83 const struct m31_phy_regs *regs;
84 unsigned int nregs;
85 };
86
87 static const struct m31_phy_regs m31_ipq5018_regs[] = {
88 {
89 .off = USB_PHY_CFG0,
90 .val = UTMI_PHY_OVERRIDE_EN
91 },
92 {
93 .off = USB_PHY_UTMI_CTRL5,
94 .val = POR_EN,
95 .delay = 15
96 },
97 {
98 .off = USB_PHY_FSEL_SEL,
99 .val = FREQ_SEL
100 },
101 {
102 .off = USB_PHY_HS_PHY_CTRL_COMMON0,
103 .val = COMMONONN | FSEL | RETENABLEN
104 },
105 {
106 .off = USB_PHY_REFCLK_CTRL,
107 .val = CLKCORE
108 },
109 {
110 .off = USB_PHY_UTMI_CTRL5,
111 .val = POR_EN
112 },
113 {
114 .off = USB_PHY_HS_PHY_CTRL2,
115 .val = USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN
116 },
117 {
118 .off = USB_PHY_UTMI_CTRL5,
119 .val = 0x0
120 },
121 {
122 .off = USB_PHY_HS_PHY_CTRL2,
123 .val = USB2_SUSPEND_N | USB2_UTMI_CLK_EN
124 },
125 {
126 .off = USB_PHY_CFG0,
127 .val = 0x0
128 },
129 };
130
131 static struct m31_phy_regs m31_ipq5332_regs[] = {
132 {
133 USB_PHY_CFG0,
134 UTMI_PHY_OVERRIDE_EN,
135 0
136 },
137 {
138 USB_PHY_UTMI_CTRL5,
139 POR_EN,
140 15
141 },
142 {
143 USB_PHY_FSEL_SEL,
144 FREQ_SEL,
145 0
146 },
147 {
148 USB_PHY_HS_PHY_CTRL_COMMON0,
149 COMMONONN | FREQ_24MHZ | RETENABLEN,
150 0
151 },
152 {
153 USB_PHY_UTMI_CTRL5,
154 POR_EN,
155 0
156 },
157 {
158 USB_PHY_HS_PHY_CTRL2,
159 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN,
160 0
161 },
162 {
163 USB2PHY_USB_PHY_M31_XCFGI_11,
164 XCFG_COARSE_TUNE_NUM | XCFG_FINE_TUNE_NUM,
165 0
166 },
167 {
168 USB2PHY_USB_PHY_M31_XCFGI_4,
169 HSTX_SLEW_RATE_400PS | PLL_CHARGING_PUMP_CURRENT_35UA | ODT_VALUE_38_02_OHM,
170 0
171 },
172 {
173 USB2PHY_USB_PHY_M31_XCFGI_1,
174 USB2_0_TX_ENABLE,
175 0
176 },
177 {
178 USB2PHY_USB_PHY_M31_XCFGI_5,
179 HSTX_PRE_EMPHASIS_LEVEL_0_55MA,
180 4
181 },
182 {
183 USB2PHY_USB_PHY_M31_XCFGI_9,
184 HSTX_CURRENT_17_1MA_385MV,
185 },
186 {
187 USB_PHY_UTMI_CTRL5,
188 0x0,
189 0
190 },
191 {
192 USB_PHY_HS_PHY_CTRL2,
193 USB2_SUSPEND_N | USB2_UTMI_CLK_EN,
194 0
195 },
196 };
197
198 struct m31usb_phy {
199 struct phy *phy;
200 void __iomem *base;
201 const struct m31_phy_regs *regs;
202 int nregs;
203
204 struct regulator *vreg;
205 struct clk *clk;
206 struct reset_control *reset;
207
208 bool ulpi_mode;
209 };
210
m31usb_phy_init(struct phy * phy)211 static int m31usb_phy_init(struct phy *phy)
212 {
213 struct m31usb_phy *qphy = phy_get_drvdata(phy);
214 const struct m31_phy_regs *regs = qphy->regs;
215 int i, ret;
216
217 ret = regulator_enable(qphy->vreg);
218 if (ret) {
219 dev_err(&phy->dev, "failed to enable regulator, %d\n", ret);
220 return ret;
221 }
222
223 ret = clk_prepare_enable(qphy->clk);
224 if (ret) {
225 regulator_disable(qphy->vreg);
226 dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
227 return ret;
228 }
229
230 /* Perform phy reset */
231 reset_control_assert(qphy->reset);
232 udelay(5);
233 reset_control_deassert(qphy->reset);
234
235 /* configure for ULPI mode if requested */
236 if (qphy->ulpi_mode)
237 writel(0x0, qphy->base + USB2PHY_PORT_UTMI_CTRL2);
238
239 /* Enable the PHY */
240 writel(POWER_UP, qphy->base + USB2PHY_PORT_POWERDOWN);
241
242 /* Turn on phy ref clock */
243 for (i = 0; i < qphy->nregs; i++) {
244 writel(regs[i].val, qphy->base + regs[i].off);
245 if (regs[i].delay)
246 udelay(regs[i].delay);
247 }
248
249 return 0;
250 }
251
m31usb_phy_shutdown(struct phy * phy)252 static int m31usb_phy_shutdown(struct phy *phy)
253 {
254 struct m31usb_phy *qphy = phy_get_drvdata(phy);
255
256 /* Disable the PHY */
257 writel_relaxed(POWER_DOWN, qphy->base + USB2PHY_PORT_POWERDOWN);
258
259 clk_disable_unprepare(qphy->clk);
260
261 regulator_disable(qphy->vreg);
262
263 return 0;
264 }
265
266 static const struct phy_ops m31usb_phy_gen_ops = {
267 .power_on = m31usb_phy_init,
268 .power_off = m31usb_phy_shutdown,
269 .owner = THIS_MODULE,
270 };
271
m31usb_phy_probe(struct platform_device * pdev)272 static int m31usb_phy_probe(struct platform_device *pdev)
273 {
274 struct phy_provider *phy_provider;
275 const struct m31_priv_data *data;
276 struct device *dev = &pdev->dev;
277 struct m31usb_phy *qphy;
278
279 qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
280 if (!qphy)
281 return -ENOMEM;
282
283 qphy->base = devm_platform_ioremap_resource(pdev, 0);
284 if (IS_ERR(qphy->base))
285 return PTR_ERR(qphy->base);
286
287 qphy->reset = devm_reset_control_get_exclusive_by_index(dev, 0);
288 if (IS_ERR(qphy->reset))
289 return PTR_ERR(qphy->reset);
290
291 qphy->clk = devm_clk_get(dev, NULL);
292 if (IS_ERR(qphy->clk))
293 return dev_err_probe(dev, PTR_ERR(qphy->clk),
294 "failed to get clk\n");
295
296 data = of_device_get_match_data(dev);
297 qphy->regs = data->regs;
298 qphy->nregs = data->nregs;
299 qphy->ulpi_mode = data->ulpi_mode;
300
301 qphy->phy = devm_phy_create(dev, NULL, &m31usb_phy_gen_ops);
302 if (IS_ERR(qphy->phy))
303 return dev_err_probe(dev, PTR_ERR(qphy->phy),
304 "failed to create phy\n");
305
306 qphy->vreg = devm_regulator_get(dev, "vdd");
307 if (IS_ERR(qphy->vreg))
308 return dev_err_probe(dev, PTR_ERR(qphy->vreg),
309 "failed to get vreg\n");
310
311 phy_set_drvdata(qphy->phy, qphy);
312
313 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
314
315 return PTR_ERR_OR_ZERO(phy_provider);
316 }
317
318 static const struct m31_priv_data m31_ipq5018_data = {
319 .ulpi_mode = false,
320 .regs = m31_ipq5018_regs,
321 .nregs = ARRAY_SIZE(m31_ipq5018_regs),
322 };
323
324 static const struct m31_priv_data m31_ipq5332_data = {
325 .ulpi_mode = false,
326 .regs = m31_ipq5332_regs,
327 .nregs = ARRAY_SIZE(m31_ipq5332_regs),
328 };
329
330 static const struct of_device_id m31usb_phy_id_table[] = {
331 { .compatible = "qcom,ipq5018-usb-hsphy", .data = &m31_ipq5018_data },
332 { .compatible = "qcom,ipq5332-usb-hsphy", .data = &m31_ipq5332_data },
333 { },
334 };
335 MODULE_DEVICE_TABLE(of, m31usb_phy_id_table);
336
337 static struct platform_driver m31usb_phy_driver = {
338 .probe = m31usb_phy_probe,
339 .driver = {
340 .name = "qcom-m31usb-phy",
341 .of_match_table = m31usb_phy_id_table,
342 },
343 };
344
345 module_platform_driver(m31usb_phy_driver);
346
347 MODULE_DESCRIPTION("USB2 Qualcomm M31 HSPHY driver");
348 MODULE_LICENSE("GPL");
349