blob: 2db22943a662d1adb9d411d976f048c4484f3ab1 [file] [log] [blame]
Rishabh Bhatnagare9a05bb2018-12-10 11:09:45 -08001// SPDX-License-Identifier: GPL-2.0-only
Hemant Kumar5a5e9242018-08-08 10:38:50 -07002/*
Jordan Crouse0d7f6462019-02-06 08:43:27 -07003 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Hemant Kumar5a5e9242018-08-08 10:38:50 -07004 */
5
6#include <linux/module.h>
7#include <linux/kernel.h>
8#include <linux/err.h>
9#include <linux/slab.h>
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/io.h>
Jack Pham44b4bac2018-09-24 12:07:36 -070013#include <linux/mutex.h>
Hemant Kumar5a5e9242018-08-08 10:38:50 -070014#include <linux/of.h>
15#include <linux/platform_device.h>
16#include <linux/power_supply.h>
17#include <linux/regulator/consumer.h>
18#include <linux/regulator/driver.h>
19#include <linux/regulator/machine.h>
20#include <linux/usb/phy.h>
21#include <linux/reset.h>
22
23#define USB2_PHY_USB_PHY_UTMI_CTRL0 (0x3c)
Jack Pham44b4bac2018-09-24 12:07:36 -070024#define OPMODE_MASK (0x3 << 3)
25#define OPMODE_NONDRIVING (0x1 << 3)
Hemant Kumar5a5e9242018-08-08 10:38:50 -070026#define SLEEPM BIT(0)
27
28#define USB2_PHY_USB_PHY_UTMI_CTRL5 (0x50)
29#define ATERESET BIT(0)
30#define POR BIT(1)
31
32#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
33#define VATESTENB_MASK (0x3 << 0)
34#define RETENABLEN BIT(3)
35#define FSEL_MASK (0x7 << 4)
36#define FSEL_DEFAULT (0x3 << 4)
37
38#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58)
39#define VBUSVLDEXTSEL0 BIT(4)
40#define PLLBTUNE BIT(5)
41
42#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2 (0x5c)
43#define VREGBYPASS BIT(0)
44
45#define USB2_PHY_USB_PHY_HS_PHY_CTRL1 (0x60)
46#define VBUSVLDEXT0 BIT(0)
47
48#define USB2_PHY_USB_PHY_HS_PHY_CTRL2 (0x64)
49#define USB2_SUSPEND_N BIT(2)
50#define USB2_SUSPEND_N_SEL BIT(3)
51
52#define USB2_PHY_USB_PHY_HS_PHY_TEST0 (0x80)
53#define TESTDATAIN_MASK (0xff << 0)
54
55#define USB2_PHY_USB_PHY_HS_PHY_TEST1 (0x84)
56#define TESTDATAOUTSEL BIT(4)
57#define TOGGLE_2WR BIT(6)
58
59#define USB2_PHY_USB_PHY_CFG0 (0x94)
Jack Pham44b4bac2018-09-24 12:07:36 -070060#define UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN BIT(0)
Hemant Kumar5a5e9242018-08-08 10:38:50 -070061#define UTMI_PHY_CMN_CTRL_OVERRIDE_EN BIT(1)
62
63#define USB2_PHY_USB_PHY_REFCLK_CTRL (0xa0)
64#define REFCLK_SEL_MASK (0x3 << 0)
65#define REFCLK_SEL_DEFAULT (0x2 << 0)
66
67#define USB2PHY_USB_PHY_RTUNE_SEL (0xb4)
68#define RTUNE_SEL BIT(0)
69
70#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
71#define USB_HSPHY_3P3_VOL_MAX 3300000 /* uV */
72#define USB_HSPHY_3P3_HPM_LOAD 16000 /* uA */
73#define USB_HSPHY_3P3_VOL_FSHOST 3150000 /* uV */
74
75#define USB_HSPHY_1P8_VOL_MIN 1704000 /* uV */
76#define USB_HSPHY_1P8_VOL_MAX 1800000 /* uV */
77#define USB_HSPHY_1P8_HPM_LOAD 19000 /* uA */
78
79struct msm_hsphy {
80 struct usb_phy phy;
81 void __iomem *base;
82
83 struct clk *ref_clk_src;
84 struct clk *cfg_ahb_clk;
85 struct reset_control *phy_reset;
86
87 struct regulator *vdd;
88 struct regulator *vdda33;
89 struct regulator *vdda18;
90 int vdd_levels[3]; /* none, low, high */
91
92 bool clocks_enabled;
93 bool power_enabled;
94 bool suspended;
95 bool cable_connected;
Jack Pham44b4bac2018-09-24 12:07:36 -070096 bool dpdm_enable;
Hemant Kumar5a5e9242018-08-08 10:38:50 -070097
98 int *param_override_seq;
99 int param_override_seq_cnt;
100
101 void __iomem *phy_rcal_reg;
102 u32 rcal_mask;
103
Jack Pham44b4bac2018-09-24 12:07:36 -0700104 struct mutex phy_lock;
105 struct regulator_desc dpdm_rdesc;
106 struct regulator_dev *dpdm_rdev;
107
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700108 /* emulation targets specific */
109 void __iomem *emu_phy_base;
110 int *emu_init_seq;
111 int emu_init_seq_len;
112 int *emu_dcm_reset_seq;
113 int emu_dcm_reset_seq_len;
114};
115
116static void msm_hsphy_enable_clocks(struct msm_hsphy *phy, bool on)
117{
118 dev_dbg(phy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
119 __func__, phy->clocks_enabled, on);
120
121 if (!phy->clocks_enabled && on) {
122 clk_prepare_enable(phy->ref_clk_src);
123
124 if (phy->cfg_ahb_clk)
125 clk_prepare_enable(phy->cfg_ahb_clk);
126
127 phy->clocks_enabled = true;
128 }
129
130 if (phy->clocks_enabled && !on) {
131 if (phy->cfg_ahb_clk)
132 clk_disable_unprepare(phy->cfg_ahb_clk);
133
134 clk_disable_unprepare(phy->ref_clk_src);
135 phy->clocks_enabled = false;
136 }
137
138}
139static int msm_hsphy_config_vdd(struct msm_hsphy *phy, int high)
140{
141 int min, ret;
142
143 min = high ? 1 : 0; /* low or none? */
144 ret = regulator_set_voltage(phy->vdd, phy->vdd_levels[min],
145 phy->vdd_levels[2]);
146 if (ret) {
147 dev_err(phy->phy.dev, "unable to set voltage for hsusb vdd\n");
148 return ret;
149 }
150
151 dev_dbg(phy->phy.dev, "%s: min_vol:%d max_vol:%d\n", __func__,
152 phy->vdd_levels[min], phy->vdd_levels[2]);
153
154 return ret;
155}
156
157static int msm_hsphy_enable_power(struct msm_hsphy *phy, bool on)
158{
159 int ret = 0;
160
161 dev_dbg(phy->phy.dev, "%s turn %s regulators. power_enabled:%d\n",
162 __func__, on ? "on" : "off", phy->power_enabled);
163
164 if (phy->power_enabled == on) {
165 dev_dbg(phy->phy.dev, "PHYs' regulators are already ON.\n");
166 return 0;
167 }
168
169 if (!on)
170 goto disable_vdda33;
171
172 ret = msm_hsphy_config_vdd(phy, true);
173 if (ret) {
174 dev_err(phy->phy.dev, "Unable to config VDD:%d\n",
175 ret);
176 goto err_vdd;
177 }
178
179 ret = regulator_enable(phy->vdd);
180 if (ret) {
181 dev_err(phy->phy.dev, "Unable to enable VDD\n");
182 goto unconfig_vdd;
183 }
184
185 ret = regulator_set_load(phy->vdda18, USB_HSPHY_1P8_HPM_LOAD);
186 if (ret < 0) {
187 dev_err(phy->phy.dev, "Unable to set HPM of vdda18:%d\n", ret);
188 goto disable_vdd;
189 }
190
191 ret = regulator_set_voltage(phy->vdda18, USB_HSPHY_1P8_VOL_MIN,
192 USB_HSPHY_1P8_VOL_MAX);
193 if (ret) {
194 dev_err(phy->phy.dev,
195 "Unable to set voltage for vdda18:%d\n", ret);
196 goto put_vdda18_lpm;
197 }
198
199 ret = regulator_enable(phy->vdda18);
200 if (ret) {
201 dev_err(phy->phy.dev, "Unable to enable vdda18:%d\n", ret);
202 goto unset_vdda18;
203 }
204
205 ret = regulator_set_load(phy->vdda33, USB_HSPHY_3P3_HPM_LOAD);
206 if (ret < 0) {
207 dev_err(phy->phy.dev, "Unable to set HPM of vdda33:%d\n", ret);
208 goto disable_vdda18;
209 }
210
211 ret = regulator_set_voltage(phy->vdda33, USB_HSPHY_3P3_VOL_MIN,
212 USB_HSPHY_3P3_VOL_MAX);
213 if (ret) {
214 dev_err(phy->phy.dev,
215 "Unable to set voltage for vdda33:%d\n", ret);
216 goto put_vdda33_lpm;
217 }
218
219 ret = regulator_enable(phy->vdda33);
220 if (ret) {
221 dev_err(phy->phy.dev, "Unable to enable vdda33:%d\n", ret);
222 goto unset_vdd33;
223 }
224
225 phy->power_enabled = true;
226
227 pr_debug("%s(): HSUSB PHY's regulators are turned ON.\n", __func__);
228 return ret;
229
230disable_vdda33:
231 ret = regulator_disable(phy->vdda33);
232 if (ret)
233 dev_err(phy->phy.dev, "Unable to disable vdda33:%d\n", ret);
234
235unset_vdd33:
236 ret = regulator_set_voltage(phy->vdda33, 0, USB_HSPHY_3P3_VOL_MAX);
237 if (ret)
238 dev_err(phy->phy.dev,
239 "Unable to set (0) voltage for vdda33:%d\n", ret);
240
241put_vdda33_lpm:
242 ret = regulator_set_load(phy->vdda33, 0);
243 if (ret < 0)
244 dev_err(phy->phy.dev, "Unable to set (0) HPM of vdda33\n");
245
246disable_vdda18:
247 ret = regulator_disable(phy->vdda18);
248 if (ret)
249 dev_err(phy->phy.dev, "Unable to disable vdda18:%d\n", ret);
250
251unset_vdda18:
252 ret = regulator_set_voltage(phy->vdda18, 0, USB_HSPHY_1P8_VOL_MAX);
253 if (ret)
254 dev_err(phy->phy.dev,
255 "Unable to set (0) voltage for vdda18:%d\n", ret);
256
257put_vdda18_lpm:
258 ret = regulator_set_load(phy->vdda18, 0);
259 if (ret < 0)
260 dev_err(phy->phy.dev, "Unable to set LPM of vdda18\n");
261
262disable_vdd:
263 ret = regulator_disable(phy->vdd);
264 if (ret)
265 dev_err(phy->phy.dev, "Unable to disable vdd:%d\n",
266 ret);
267
268unconfig_vdd:
269 ret = msm_hsphy_config_vdd(phy, false);
270 if (ret)
271 dev_err(phy->phy.dev, "Unable unconfig VDD:%d\n",
272 ret);
273err_vdd:
274 phy->power_enabled = false;
275 dev_dbg(phy->phy.dev, "HSUSB PHY's regulators are turned OFF.\n");
276 return ret;
277}
278
279static void msm_usb_write_readback(void __iomem *base, u32 offset,
280 const u32 mask, u32 val)
281{
282 u32 write_val, tmp = readl_relaxed(base + offset);
283
284 tmp &= ~mask; /* retain other bits */
285 write_val = tmp | val;
286
287 writel_relaxed(write_val, base + offset);
288
289 /* Read back to see if val was written */
290 tmp = readl_relaxed(base + offset);
291 tmp &= mask; /* clear other bits */
292
293 if (tmp != val)
294 pr_err("%s: write: %x to QSCRATCH: %x FAILED\n",
295 __func__, val, offset);
296}
297
298static void msm_hsphy_reset(struct msm_hsphy *phy)
299{
300 int ret;
301
302 ret = reset_control_assert(phy->phy_reset);
303 if (ret)
304 dev_err(phy->phy.dev, "%s: phy_reset assert failed\n",
305 __func__);
306 usleep_range(100, 150);
307
308 ret = reset_control_deassert(phy->phy_reset);
309 if (ret)
310 dev_err(phy->phy.dev, "%s: phy_reset deassert failed\n",
311 __func__);
312}
313
314static void hsusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt,
315 unsigned long delay)
316{
317 int i;
318
319 pr_debug("Seq count:%d\n", cnt);
320 for (i = 0; i < cnt; i = i+2) {
321 pr_debug("write 0x%02x to 0x%02x\n", seq[i], seq[i+1]);
322 writel_relaxed(seq[i], base + seq[i+1]);
323 if (delay)
324 usleep_range(delay, (delay + 2000));
325 }
326}
327
328static int msm_hsphy_emu_init(struct usb_phy *uphy)
329{
330 struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
331 int ret;
332
333 dev_dbg(uphy->dev, "%s\n", __func__);
334
335 ret = msm_hsphy_enable_power(phy, true);
336 if (ret)
337 return ret;
338
339 msm_hsphy_enable_clocks(phy, true);
340 msm_hsphy_reset(phy);
341
342 if (phy->emu_init_seq) {
343 hsusb_phy_write_seq(phy->base,
344 phy->emu_init_seq,
345 phy->emu_init_seq_len, 10000);
346
347 /* Wait for 5ms as per QUSB2 RUMI sequence */
348 usleep_range(5000, 7000);
349
350 if (phy->emu_dcm_reset_seq)
351 hsusb_phy_write_seq(phy->emu_phy_base,
352 phy->emu_dcm_reset_seq,
353 phy->emu_dcm_reset_seq_len, 10000);
354 }
355
356 return 0;
357}
358
359static int msm_hsphy_init(struct usb_phy *uphy)
360{
361 struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
362 int ret;
363 u32 rcal_code = 0;
364
365 dev_dbg(uphy->dev, "%s\n", __func__);
366
367 ret = msm_hsphy_enable_power(phy, true);
368 if (ret)
369 return ret;
370
371 msm_hsphy_enable_clocks(phy, true);
372 msm_hsphy_reset(phy);
373
374 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0,
375 UTMI_PHY_CMN_CTRL_OVERRIDE_EN, UTMI_PHY_CMN_CTRL_OVERRIDE_EN);
376
377 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL5,
378 POR, POR);
379
380 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
381 FSEL_MASK, 0);
382
383 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
384 PLLBTUNE, PLLBTUNE);
385
386 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_REFCLK_CTRL,
387 REFCLK_SEL_MASK, REFCLK_SEL_DEFAULT);
388
389 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1,
390 VBUSVLDEXTSEL0, VBUSVLDEXTSEL0);
391
392 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL1,
393 VBUSVLDEXT0, VBUSVLDEXT0);
394
395 /* set parameter ovrride if needed */
396 if (phy->param_override_seq)
397 hsusb_phy_write_seq(phy->base, phy->param_override_seq,
398 phy->param_override_seq_cnt, 0);
399
400 if (phy->phy_rcal_reg) {
401 rcal_code = readl_relaxed(phy->phy_rcal_reg) & phy->rcal_mask;
402
Jordan Crouse0d7f6462019-02-06 08:43:27 -0700403 dev_dbg(uphy->dev, "rcal_mask:%08x reg:%pK code:%08x\n",
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700404 phy->rcal_mask, phy->phy_rcal_reg, rcal_code);
405 }
406
407 /* Use external resistor for tuning if efuse is not programmed */
408 if (!rcal_code)
409 msm_usb_write_readback(phy->base, USB2PHY_USB_PHY_RTUNE_SEL,
410 RTUNE_SEL, RTUNE_SEL);
411
412 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
413 VREGBYPASS, VREGBYPASS);
414
415 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL5,
416 ATERESET, ATERESET);
417
418 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_TEST1,
419 TESTDATAOUTSEL, TESTDATAOUTSEL);
420
421 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_TEST1,
422 TOGGLE_2WR, TOGGLE_2WR);
423
424 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0,
425 VATESTENB_MASK, 0);
426
427 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_TEST0,
428 TESTDATAIN_MASK, 0);
429
430 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
431 USB2_SUSPEND_N_SEL, USB2_SUSPEND_N_SEL);
432
433 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
434 USB2_SUSPEND_N, USB2_SUSPEND_N);
435
436 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0,
437 SLEEPM, SLEEPM);
438
439 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL5,
440 POR, 0);
441
442 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
443 USB2_SUSPEND_N_SEL, 0);
444
445 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0,
446 UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 0);
447
448 return 0;
449}
450
451static int msm_hsphy_set_suspend(struct usb_phy *uphy, int suspend)
452{
453 struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
454
455 if (phy->suspended && suspend) {
456 dev_dbg(uphy->dev, "%s: USB PHY is already suspended\n",
457 __func__);
458 return 0;
459 }
460
461 if (suspend) { /* Bus suspend */
462 if (phy->cable_connected ||
463 (phy->phy.flags & PHY_HOST_MODE)) {
464 msm_hsphy_enable_clocks(phy, false);
465 } else {/* Cable disconnect */
Jack Pham44b4bac2018-09-24 12:07:36 -0700466 mutex_lock(&phy->phy_lock);
467 if (!phy->dpdm_enable) {
468 msm_hsphy_enable_clocks(phy, false);
469 msm_hsphy_enable_power(phy, false);
470 } else {
471 dev_dbg(uphy->dev, "dpdm reg still active. Keep clocks/ldo ON\n");
472 }
473 mutex_unlock(&phy->phy_lock);
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700474 }
475 phy->suspended = true;
476 } else { /* Bus resume and cable connect */
477 msm_hsphy_enable_clocks(phy, true);
478 phy->suspended = false;
479 }
480
481 return 0;
482}
483
484static int msm_hsphy_notify_connect(struct usb_phy *uphy,
485 enum usb_device_speed speed)
486{
487 struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
488
489 phy->cable_connected = true;
490
491 return 0;
492}
493
494static int msm_hsphy_notify_disconnect(struct usb_phy *uphy,
495 enum usb_device_speed speed)
496{
497 struct msm_hsphy *phy = container_of(uphy, struct msm_hsphy, phy);
498
499 phy->cable_connected = false;
500
501 return 0;
502}
503
Jack Pham44b4bac2018-09-24 12:07:36 -0700504static int msm_hsphy_dpdm_regulator_enable(struct regulator_dev *rdev)
505{
506 int ret = 0;
507 struct msm_hsphy *phy = rdev_get_drvdata(rdev);
508
509 dev_dbg(phy->phy.dev, "%s dpdm_enable:%d\n",
510 __func__, phy->dpdm_enable);
511
512 mutex_lock(&phy->phy_lock);
513 if (!phy->dpdm_enable) {
514 ret = msm_hsphy_enable_power(phy, true);
515 if (ret) {
516 mutex_unlock(&phy->phy_lock);
517 return ret;
518 }
519
520 msm_hsphy_enable_clocks(phy, true);
521 msm_hsphy_reset(phy);
522
523 /*
524 * For PMIC charger detection, place PHY in UTMI non-driving
525 * mode which leaves Dp and Dm lines in high-Z state.
526 */
527 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL2,
528 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
529 USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
530 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_UTMI_CTRL0,
531 OPMODE_MASK, OPMODE_NONDRIVING);
532 msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_CFG0,
533 UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN,
534 UTMI_PHY_DATAPATH_CTRL_OVERRIDE_EN);
535
536 phy->dpdm_enable = true;
537 }
538 mutex_unlock(&phy->phy_lock);
539
540 return ret;
541}
542
543static int msm_hsphy_dpdm_regulator_disable(struct regulator_dev *rdev)
544{
545 int ret = 0;
546 struct msm_hsphy *phy = rdev_get_drvdata(rdev);
547
548 dev_dbg(phy->phy.dev, "%s dpdm_enable:%d\n",
549 __func__, phy->dpdm_enable);
550
551 mutex_lock(&phy->phy_lock);
552 if (phy->dpdm_enable) {
553 if (!phy->cable_connected) {
554 msm_hsphy_enable_clocks(phy, false);
555 ret = msm_hsphy_enable_power(phy, false);
556 if (ret < 0) {
557 mutex_unlock(&phy->phy_lock);
558 return ret;
559 }
560 }
561 phy->dpdm_enable = false;
562 }
563 mutex_unlock(&phy->phy_lock);
564
565 return ret;
566}
567
568static int msm_hsphy_dpdm_regulator_is_enabled(struct regulator_dev *rdev)
569{
570 struct msm_hsphy *phy = rdev_get_drvdata(rdev);
571
572 dev_dbg(phy->phy.dev, "%s dpdm_enable:%d\n",
573 __func__, phy->dpdm_enable);
574
575 return phy->dpdm_enable;
576}
577
578static struct regulator_ops msm_hsphy_dpdm_regulator_ops = {
579 .enable = msm_hsphy_dpdm_regulator_enable,
580 .disable = msm_hsphy_dpdm_regulator_disable,
581 .is_enabled = msm_hsphy_dpdm_regulator_is_enabled,
582};
583
584static int msm_hsphy_regulator_init(struct msm_hsphy *phy)
585{
586 struct device *dev = phy->phy.dev;
587 struct regulator_config cfg = {};
588 struct regulator_init_data *init_data;
589
590 init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
591 if (!init_data)
592 return -ENOMEM;
593
594 init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS;
595 phy->dpdm_rdesc.owner = THIS_MODULE;
596 phy->dpdm_rdesc.type = REGULATOR_VOLTAGE;
597 phy->dpdm_rdesc.ops = &msm_hsphy_dpdm_regulator_ops;
598 phy->dpdm_rdesc.name = kbasename(dev->of_node->full_name);
599
600 cfg.dev = dev;
601 cfg.init_data = init_data;
602 cfg.driver_data = phy;
603 cfg.of_node = dev->of_node;
604
605 phy->dpdm_rdev = devm_regulator_register(dev, &phy->dpdm_rdesc, &cfg);
606 if (IS_ERR(phy->dpdm_rdev))
607 return PTR_ERR(phy->dpdm_rdev);
608
609 return 0;
610}
611
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700612static int msm_hsphy_probe(struct platform_device *pdev)
613{
614 struct msm_hsphy *phy;
615 struct device *dev = &pdev->dev;
616 struct resource *res;
617 int ret = 0, size = 0;
618
619
620 phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
621 if (!phy) {
622 ret = -ENOMEM;
623 goto err_ret;
624 }
625
626 phy->phy.dev = dev;
627 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
628 "hsusb_phy_base");
629 if (!res) {
630 dev_err(dev, "missing memory base resource\n");
631 ret = -ENODEV;
632 goto err_ret;
633 }
634
635 phy->base = devm_ioremap_resource(dev, res);
636 if (IS_ERR(phy->base)) {
637 dev_err(dev, "ioremap failed\n");
638 ret = -ENODEV;
639 goto err_ret;
640 }
641
642 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
643 "phy_rcal_reg");
644 if (res) {
645 phy->phy_rcal_reg = devm_ioremap_nocache(dev,
646 res->start, resource_size(res));
647 if (IS_ERR(phy->phy_rcal_reg)) {
648 dev_err(dev, "couldn't ioremap phy_rcal_reg\n");
649 phy->phy_rcal_reg = NULL;
650 }
651 if (of_property_read_u32(dev->of_node,
652 "qcom,rcal-mask", &phy->rcal_mask)) {
653 dev_err(dev, "unable to read phy rcal mask\n");
654 phy->phy_rcal_reg = NULL;
655 }
Jordan Crouse0d7f6462019-02-06 08:43:27 -0700656 dev_dbg(dev, "rcal_mask:%08x reg:%pK\n", phy->rcal_mask,
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700657 phy->phy_rcal_reg);
658 }
659
660 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
661 "emu_phy_base");
662 if (res) {
663 phy->emu_phy_base = devm_ioremap_resource(dev, res);
664 if (IS_ERR(phy->emu_phy_base)) {
665 dev_dbg(dev, "couldn't ioremap emu_phy_base\n");
666 phy->emu_phy_base = NULL;
667 }
668 }
669
670 /* ref_clk_src is needed irrespective of SE_CLK or DIFF_CLK usage */
671 phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
672 if (IS_ERR(phy->ref_clk_src)) {
673 dev_dbg(dev, "clk get failed for ref_clk_src\n");
674 ret = PTR_ERR(phy->ref_clk_src);
675 return ret;
676 }
677
678 if (of_property_match_string(pdev->dev.of_node,
679 "clock-names", "cfg_ahb_clk") >= 0) {
680 phy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk");
681 if (IS_ERR(phy->cfg_ahb_clk)) {
682 ret = PTR_ERR(phy->cfg_ahb_clk);
683 if (ret != -EPROBE_DEFER)
684 dev_err(dev,
685 "clk get failed for cfg_ahb_clk ret %d\n", ret);
686 return ret;
687 }
688 }
689
690 phy->phy_reset = devm_reset_control_get(dev, "phy_reset");
691 if (IS_ERR(phy->phy_reset))
692 return PTR_ERR(phy->phy_reset);
693
694 of_get_property(dev->of_node, "qcom,emu-init-seq", &size);
695 if (size) {
696 phy->emu_init_seq = devm_kzalloc(dev,
697 size, GFP_KERNEL);
698 if (phy->emu_init_seq) {
699 phy->emu_init_seq_len =
700 (size / sizeof(*phy->emu_init_seq));
701 if (phy->emu_init_seq_len % 2) {
702 dev_err(dev, "invalid emu_init_seq_len\n");
703 return -EINVAL;
704 }
705
706 of_property_read_u32_array(dev->of_node,
707 "qcom,emu-init-seq",
708 phy->emu_init_seq,
709 phy->emu_init_seq_len);
710 } else {
711 dev_dbg(dev,
712 "error allocating memory for emu_init_seq\n");
713 }
714 }
715
716 size = 0;
717 of_get_property(dev->of_node, "qcom,emu-dcm-reset-seq", &size);
718 if (size) {
719 phy->emu_dcm_reset_seq = devm_kzalloc(dev,
720 size, GFP_KERNEL);
721 if (phy->emu_dcm_reset_seq) {
722 phy->emu_dcm_reset_seq_len =
723 (size / sizeof(*phy->emu_dcm_reset_seq));
724 if (phy->emu_dcm_reset_seq_len % 2) {
725 dev_err(dev, "invalid emu_dcm_reset_seq_len\n");
726 return -EINVAL;
727 }
728
729 of_property_read_u32_array(dev->of_node,
730 "qcom,emu-dcm-reset-seq",
731 phy->emu_dcm_reset_seq,
732 phy->emu_dcm_reset_seq_len);
733 } else {
734 dev_dbg(dev,
735 "error allocating memory for emu_dcm_reset_seq\n");
736 }
737 }
738
739 phy->param_override_seq_cnt = of_property_count_elems_of_size(
740 dev->of_node,
741 "qcom,param-override-seq",
742 sizeof(*phy->param_override_seq));
743 if (phy->param_override_seq_cnt > 0) {
744 phy->param_override_seq = devm_kcalloc(dev,
745 phy->param_override_seq_cnt,
746 sizeof(*phy->param_override_seq),
747 GFP_KERNEL);
748 if (!phy->param_override_seq)
749 return -ENOMEM;
750
751 if (phy->param_override_seq_cnt % 2) {
752 dev_err(dev, "invalid param_override_seq_len\n");
753 return -EINVAL;
754 }
755
756 ret = of_property_read_u32_array(dev->of_node,
757 "qcom,param-override-seq",
758 phy->param_override_seq,
759 phy->param_override_seq_cnt);
760 if (ret) {
761 dev_err(dev, "qcom,param-override-seq read failed %d\n",
762 ret);
763 return ret;
764 }
765 }
766
767 ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level",
768 (u32 *) phy->vdd_levels,
769 ARRAY_SIZE(phy->vdd_levels));
770 if (ret) {
771 dev_err(dev, "error reading qcom,vdd-voltage-level property\n");
772 goto err_ret;
773 }
774
775
776 phy->vdd = devm_regulator_get(dev, "vdd");
777 if (IS_ERR(phy->vdd)) {
778 dev_err(dev, "unable to get vdd supply\n");
779 ret = PTR_ERR(phy->vdd);
780 goto err_ret;
781 }
782
783 phy->vdda33 = devm_regulator_get(dev, "vdda33");
784 if (IS_ERR(phy->vdda33)) {
785 dev_err(dev, "unable to get vdda33 supply\n");
786 ret = PTR_ERR(phy->vdda33);
787 goto err_ret;
788 }
789
790 phy->vdda18 = devm_regulator_get(dev, "vdda18");
791 if (IS_ERR(phy->vdda18)) {
792 dev_err(dev, "unable to get vdda18 supply\n");
793 ret = PTR_ERR(phy->vdda18);
794 goto err_ret;
795 }
796
Jack Pham44b4bac2018-09-24 12:07:36 -0700797 mutex_init(&phy->phy_lock);
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700798 platform_set_drvdata(pdev, phy);
799
800 if (phy->emu_init_seq)
801 phy->phy.init = msm_hsphy_emu_init;
802 else
803 phy->phy.init = msm_hsphy_init;
804 phy->phy.set_suspend = msm_hsphy_set_suspend;
805 phy->phy.notify_connect = msm_hsphy_notify_connect;
806 phy->phy.notify_disconnect = msm_hsphy_notify_disconnect;
807 phy->phy.type = USB_PHY_TYPE_USB2;
808
809 ret = usb_add_phy_dev(&phy->phy);
810 if (ret)
811 return ret;
812
Jack Pham44b4bac2018-09-24 12:07:36 -0700813 ret = msm_hsphy_regulator_init(phy);
814 if (ret) {
815 usb_remove_phy(&phy->phy);
816 return ret;
817 }
818
Hemant Kumar5a5e9242018-08-08 10:38:50 -0700819 return 0;
820
821err_ret:
822 return ret;
823}
824
825static int msm_hsphy_remove(struct platform_device *pdev)
826{
827 struct msm_hsphy *phy = platform_get_drvdata(pdev);
828
829 if (!phy)
830 return 0;
831
832 usb_remove_phy(&phy->phy);
833 clk_disable_unprepare(phy->ref_clk_src);
834
835 msm_hsphy_enable_clocks(phy, false);
836 msm_hsphy_enable_power(phy, false);
837 return 0;
838}
839
840static const struct of_device_id msm_usb_id_table[] = {
841 {
842 .compatible = "qcom,usb-hsphy-snps-femto",
843 },
844 { },
845};
846MODULE_DEVICE_TABLE(of, msm_usb_id_table);
847
848static struct platform_driver msm_hsphy_driver = {
849 .probe = msm_hsphy_probe,
850 .remove = msm_hsphy_remove,
851 .driver = {
852 .name = "msm-usb-hsphy",
853 .of_match_table = of_match_ptr(msm_usb_id_table),
854 },
855};
856
857module_platform_driver(msm_hsphy_driver);
858
859MODULE_DESCRIPTION("MSM USB HS PHY driver");
860MODULE_LICENSE("GPL v2");