blob: 1f80cde6169ac1665e81730736813ed0e4d76d39 [file] [log] [blame]
Mayank Rana3cb43a32016-08-02 12:10:20 -07001/*
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -07002 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
Mayank Rana3cb43a32016-08-02 12:10:20 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/err.h>
17#include <linux/slab.h>
18#include <linux/clk.h>
Mayank Rana3cb43a32016-08-02 12:10:20 -070019#include <linux/delay.h>
20#include <linux/io.h>
21#include <linux/of.h>
22#include <linux/platform_device.h>
23#include <linux/power_supply.h>
24#include <linux/regulator/consumer.h>
25#include <linux/regulator/driver.h>
26#include <linux/regulator/machine.h>
27#include <linux/usb/phy.h>
Amit Nischal4d278212016-06-06 17:54:34 +053028#include <linux/reset.h>
Mayank Rana3cb43a32016-08-02 12:10:20 -070029
Mayank Rana9c6b12d2017-06-22 16:23:26 -070030/* QUSB2PHY_PWR_CTRL1 register related bits */
Mayank Rana3cb43a32016-08-02 12:10:20 -070031#define PWR_CTRL1_POWR_DOWN BIT(0)
32
Mayank Rana9c6b12d2017-06-22 16:23:26 -070033/* QUSB2PHY_PLL_COMMON_STATUS_ONE register related bits */
Mayank Rana3cb43a32016-08-02 12:10:20 -070034#define CORE_READY_STATUS BIT(0)
35
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -070036/* Get TUNE value from efuse bit-mask */
37#define TUNE_VAL_MASK(val, pos, mask) ((val >> pos) & mask)
Mayank Rana3cb43a32016-08-02 12:10:20 -070038
Mayank Rana9c6b12d2017-06-22 16:23:26 -070039/* QUSB2PHY_INTR_CTRL register related bits */
Mayank Rana3cb43a32016-08-02 12:10:20 -070040#define DMSE_INTR_HIGH_SEL BIT(4)
41#define DPSE_INTR_HIGH_SEL BIT(3)
42#define CHG_DET_INTR_EN BIT(2)
43#define DMSE_INTR_EN BIT(1)
44#define DPSE_INTR_EN BIT(0)
45
Mayank Rana9c6b12d2017-06-22 16:23:26 -070046/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register related bits */
Mayank Ranab7f212e2017-04-06 17:54:35 -070047#define CORE_PLL_RATE BIT(0)
48#define CORE_PLL_RATE_MUX BIT(1)
49#define CORE_PLL_EN BIT(2)
50#define CORE_PLL_EN_MUX BIT(3)
51#define CORE_PLL_EN_FROM_RESET BIT(4)
52#define CORE_RESET BIT(5)
53#define CORE_RESET_MUX BIT(6)
54
Mayank Rana3cb43a32016-08-02 12:10:20 -070055#define QUSB2PHY_1P8_VOL_MIN 1800000 /* uV */
56#define QUSB2PHY_1P8_VOL_MAX 1800000 /* uV */
57#define QUSB2PHY_1P8_HPM_LOAD 30000 /* uA */
58
59#define QUSB2PHY_3P3_VOL_MIN 3075000 /* uV */
60#define QUSB2PHY_3P3_VOL_MAX 3200000 /* uV */
61#define QUSB2PHY_3P3_HPM_LOAD 30000 /* uA */
62
63#define LINESTATE_DP BIT(0)
64#define LINESTATE_DM BIT(1)
65
Mayank Rana73450a02017-09-21 15:13:34 -070066/* eud related registers */
67#define EUD_SW_ATTACH_DET 0x1018
68#define EUD_INT1_EN_MASK 0x0024
69
70/* EUD interrupt mask bits */
71#define EUD_INT_RX BIT(0)
72#define EUD_INT_TX BIT(1)
73#define EUD_INT_VBUS BIT(2)
74#define EUD_INT_CHGR BIT(3)
75#define EUD_INT_SAFE_MODE BIT(4)
76
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -070077unsigned int phy_tune1;
78module_param(phy_tune1, uint, 0644);
79MODULE_PARM_DESC(phy_tune1, "QUSB PHY v2 TUNE1");
Mayank Rana3cb43a32016-08-02 12:10:20 -070080
Mayank Rana9c6b12d2017-06-22 16:23:26 -070081enum qusb_phy_reg {
82 PORT_TUNE1,
83 PLL_COMMON_STATUS_ONE,
84 PWR_CTRL1,
85 INTR_CTRL,
86 PLL_CORE_INPUT_OVERRIDE,
87 TEST1,
88 USB2_PHY_REG_MAX,
89};
90
Mayank Rana3cb43a32016-08-02 12:10:20 -070091struct qusb_phy {
92 struct usb_phy phy;
Hemant Kumar164cc1b2017-04-27 19:39:58 -070093 struct mutex lock;
Mayank Rana3cb43a32016-08-02 12:10:20 -070094 void __iomem *base;
Mayank Rana73450a02017-09-21 15:13:34 -070095 void __iomem *eud_base;
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -070096 void __iomem *efuse_reg;
Mayank Rana3cb43a32016-08-02 12:10:20 -070097
98 struct clk *ref_clk_src;
99 struct clk *ref_clk;
100 struct clk *cfg_ahb_clk;
Amit Nischal4d278212016-06-06 17:54:34 +0530101 struct reset_control *phy_reset;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700102
103 struct regulator *vdd;
104 struct regulator *vdda33;
105 struct regulator *vdda18;
106 int vdd_levels[3]; /* none, low, high */
107 int init_seq_len;
108 int *qusb_phy_init_seq;
109 int host_init_seq_len;
110 int *qusb_phy_host_init_seq;
111
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700112 unsigned int *phy_reg;
113 int qusb_phy_reg_offset_cnt;
114
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700115 u32 tune_val;
116 int efuse_bit_pos;
117 int efuse_num_of_bits;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700118
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700119 int power_enabled_ref;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700120 bool clocks_enabled;
121 bool cable_connected;
122 bool suspended;
Mayank Ranadadae592017-07-21 09:03:32 -0700123 bool dpdm_enable;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700124
125 struct regulator_desc dpdm_rdesc;
126 struct regulator_dev *dpdm_rdev;
127
128 /* emulation targets specific */
129 void __iomem *emu_phy_base;
130 bool emulation;
131 int *emu_init_seq;
132 int emu_init_seq_len;
133 int *phy_pll_reset_seq;
134 int phy_pll_reset_seq_len;
135 int *emu_dcm_reset_seq;
136 int emu_dcm_reset_seq_len;
137};
138
139static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
140{
141 dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
142 __func__, qphy->clocks_enabled, on);
143
144 if (!qphy->clocks_enabled && on) {
145 clk_prepare_enable(qphy->ref_clk_src);
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700146 if (qphy->ref_clk)
147 clk_prepare_enable(qphy->ref_clk);
148
149 if (qphy->cfg_ahb_clk)
150 clk_prepare_enable(qphy->cfg_ahb_clk);
151
Mayank Rana3cb43a32016-08-02 12:10:20 -0700152 qphy->clocks_enabled = true;
153 }
154
155 if (qphy->clocks_enabled && !on) {
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700156 if (qphy->cfg_ahb_clk)
157 clk_disable_unprepare(qphy->cfg_ahb_clk);
158
159 if (qphy->ref_clk)
160 clk_disable_unprepare(qphy->ref_clk);
161
Mayank Rana3cb43a32016-08-02 12:10:20 -0700162 clk_disable_unprepare(qphy->ref_clk_src);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700163 qphy->clocks_enabled = false;
164 }
165
166 dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d\n", __func__,
167 qphy->clocks_enabled);
168}
169
170static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high)
171{
172 int min, ret;
173
174 min = high ? 1 : 0; /* low or none? */
175 ret = regulator_set_voltage(qphy->vdd, qphy->vdd_levels[min],
176 qphy->vdd_levels[2]);
177 if (ret) {
178 dev_err(qphy->phy.dev, "unable to set voltage for qusb vdd\n");
179 return ret;
180 }
181
182 dev_dbg(qphy->phy.dev, "min_vol:%d max_vol:%d\n",
183 qphy->vdd_levels[min], qphy->vdd_levels[2]);
184 return ret;
185}
186
Hemant Kumar7dc63722017-04-27 17:51:11 -0700187static int qusb_phy_enable_power(struct qusb_phy *qphy, bool on)
Mayank Rana3cb43a32016-08-02 12:10:20 -0700188{
189 int ret = 0;
190
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700191 mutex_lock(&qphy->lock);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700192
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700193 dev_dbg(qphy->phy.dev,
194 "%s:req to turn %s regulators. power_enabled_ref:%d\n",
195 __func__, on ? "on" : "off", qphy->power_enabled_ref);
196
197 if (on && ++qphy->power_enabled_ref > 1) {
198 dev_dbg(qphy->phy.dev, "PHYs' regulators are already on\n");
199 goto done;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700200 }
201
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700202 if (!on) {
203 if (on == qphy->power_enabled_ref) {
204 dev_dbg(qphy->phy.dev,
205 "PHYs' regulators are already off\n");
206 goto done;
207 }
208
209 qphy->power_enabled_ref--;
210 if (!qphy->power_enabled_ref)
211 goto disable_vdda33;
212
213 dev_dbg(qphy->phy.dev, "Skip turning off PHYs' regulators\n");
214 goto done;
215 }
Mayank Rana3cb43a32016-08-02 12:10:20 -0700216
Hemant Kumar7dc63722017-04-27 17:51:11 -0700217 ret = qusb_phy_config_vdd(qphy, true);
218 if (ret) {
219 dev_err(qphy->phy.dev, "Unable to config VDD:%d\n",
220 ret);
221 goto err_vdd;
222 }
Mayank Rana3cb43a32016-08-02 12:10:20 -0700223
Hemant Kumar7dc63722017-04-27 17:51:11 -0700224 ret = regulator_enable(qphy->vdd);
225 if (ret) {
226 dev_err(qphy->phy.dev, "Unable to enable VDD\n");
227 goto unconfig_vdd;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700228 }
229
230 ret = regulator_set_load(qphy->vdda18, QUSB2PHY_1P8_HPM_LOAD);
231 if (ret < 0) {
232 dev_err(qphy->phy.dev, "Unable to set HPM of vdda18:%d\n", ret);
233 goto disable_vdd;
234 }
235
236 ret = regulator_set_voltage(qphy->vdda18, QUSB2PHY_1P8_VOL_MIN,
237 QUSB2PHY_1P8_VOL_MAX);
238 if (ret) {
239 dev_err(qphy->phy.dev,
240 "Unable to set voltage for vdda18:%d\n", ret);
241 goto put_vdda18_lpm;
242 }
243
244 ret = regulator_enable(qphy->vdda18);
245 if (ret) {
246 dev_err(qphy->phy.dev, "Unable to enable vdda18:%d\n", ret);
247 goto unset_vdda18;
248 }
249
250 ret = regulator_set_load(qphy->vdda33, QUSB2PHY_3P3_HPM_LOAD);
251 if (ret < 0) {
252 dev_err(qphy->phy.dev, "Unable to set HPM of vdda33:%d\n", ret);
253 goto disable_vdda18;
254 }
255
256 ret = regulator_set_voltage(qphy->vdda33, QUSB2PHY_3P3_VOL_MIN,
257 QUSB2PHY_3P3_VOL_MAX);
258 if (ret) {
259 dev_err(qphy->phy.dev,
260 "Unable to set voltage for vdda33:%d\n", ret);
261 goto put_vdda33_lpm;
262 }
263
264 ret = regulator_enable(qphy->vdda33);
265 if (ret) {
266 dev_err(qphy->phy.dev, "Unable to enable vdda33:%d\n", ret);
267 goto unset_vdd33;
268 }
269
Mayank Rana3cb43a32016-08-02 12:10:20 -0700270 pr_debug("%s(): QUSB PHY's regulators are turned ON.\n", __func__);
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700271
272 mutex_unlock(&qphy->lock);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700273 return ret;
274
275disable_vdda33:
276 ret = regulator_disable(qphy->vdda33);
277 if (ret)
278 dev_err(qphy->phy.dev, "Unable to disable vdda33:%d\n", ret);
279
280unset_vdd33:
281 ret = regulator_set_voltage(qphy->vdda33, 0, QUSB2PHY_3P3_VOL_MAX);
282 if (ret)
283 dev_err(qphy->phy.dev,
284 "Unable to set (0) voltage for vdda33:%d\n", ret);
285
286put_vdda33_lpm:
287 ret = regulator_set_load(qphy->vdda33, 0);
288 if (ret < 0)
289 dev_err(qphy->phy.dev, "Unable to set (0) HPM of vdda33\n");
290
291disable_vdda18:
292 ret = regulator_disable(qphy->vdda18);
293 if (ret)
294 dev_err(qphy->phy.dev, "Unable to disable vdda18:%d\n", ret);
295
296unset_vdda18:
297 ret = regulator_set_voltage(qphy->vdda18, 0, QUSB2PHY_1P8_VOL_MAX);
298 if (ret)
299 dev_err(qphy->phy.dev,
300 "Unable to set (0) voltage for vdda18:%d\n", ret);
301
302put_vdda18_lpm:
303 ret = regulator_set_load(qphy->vdda18, 0);
304 if (ret < 0)
305 dev_err(qphy->phy.dev, "Unable to set LPM of vdda18\n");
306
307disable_vdd:
Hemant Kumar7dc63722017-04-27 17:51:11 -0700308 ret = regulator_disable(qphy->vdd);
309 if (ret)
310 dev_err(qphy->phy.dev, "Unable to disable vdd:%d\n",
311 ret);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700312
313unconfig_vdd:
Hemant Kumar7dc63722017-04-27 17:51:11 -0700314 ret = qusb_phy_config_vdd(qphy, false);
315 if (ret)
316 dev_err(qphy->phy.dev, "Unable unconfig VDD:%d\n",
317 ret);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700318err_vdd:
Mayank Rana3cb43a32016-08-02 12:10:20 -0700319 dev_dbg(qphy->phy.dev, "QUSB PHY's regulators are turned OFF.\n");
Hemant Kumar164cc1b2017-04-27 19:39:58 -0700320
321 /* in case of error in turning on regulators */
322 if (qphy->power_enabled_ref)
323 qphy->power_enabled_ref--;
324done:
325 mutex_unlock(&qphy->lock);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700326 return ret;
327}
328
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700329static void qusb_phy_get_tune1_param(struct qusb_phy *qphy)
Mayank Rana3cb43a32016-08-02 12:10:20 -0700330{
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700331 u8 reg;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700332 u32 bit_mask = 1;
333
334 pr_debug("%s(): num_of_bits:%d bit_pos:%d\n", __func__,
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700335 qphy->efuse_num_of_bits,
336 qphy->efuse_bit_pos);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700337
338 /* get bit mask based on number of bits to use with efuse reg */
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700339 bit_mask = (bit_mask << qphy->efuse_num_of_bits) - 1;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700340
341 /*
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700342 * if efuse reg is updated (i.e non-zero) then use it to program
343 * tune parameters
Mayank Rana3cb43a32016-08-02 12:10:20 -0700344 */
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700345 qphy->tune_val = readl_relaxed(qphy->efuse_reg);
346 pr_debug("%s(): bit_mask:%d efuse based tune1 value:%d\n",
347 __func__, bit_mask, qphy->tune_val);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700348
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700349 qphy->tune_val = TUNE_VAL_MASK(qphy->tune_val,
350 qphy->efuse_bit_pos, bit_mask);
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700351 reg = readb_relaxed(qphy->base + qphy->phy_reg[PORT_TUNE1]);
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700352 if (qphy->tune_val) {
353 reg = reg & 0x0f;
354 reg |= (qphy->tune_val << 4);
355 }
Mayank Rana3cb43a32016-08-02 12:10:20 -0700356
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700357 qphy->tune_val = reg;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700358}
359
360static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt,
361 unsigned long delay)
362{
363 int i;
364
365 pr_debug("Seq count:%d\n", cnt);
366 for (i = 0; i < cnt; i = i+2) {
367 pr_debug("write 0x%02x to 0x%02x\n", seq[i], seq[i+1]);
368 writel_relaxed(seq[i], base + seq[i+1]);
369 if (delay)
370 usleep_range(delay, (delay + 2000));
371 }
372}
373
Mayank Ranab7f212e2017-04-06 17:54:35 -0700374static void qusb_phy_reset(struct qusb_phy *qphy)
375{
376 int ret;
377
378 ret = reset_control_assert(qphy->phy_reset);
379 if (ret)
380 dev_err(qphy->phy.dev, "%s: phy_reset assert failed\n",
381 __func__);
382 usleep_range(100, 150);
383
384 ret = reset_control_deassert(qphy->phy_reset);
385 if (ret)
386 dev_err(qphy->phy.dev, "%s: phy_reset deassert failed\n",
387 __func__);
388}
389
Mayank Rana3cb43a32016-08-02 12:10:20 -0700390static void qusb_phy_host_init(struct usb_phy *phy)
391{
392 u8 reg;
393 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
394
395 dev_dbg(phy->dev, "%s\n", __func__);
396
Mayank Ranab7f212e2017-04-06 17:54:35 -0700397 qusb_phy_reset(qphy);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700398 qusb_phy_write_seq(qphy->base, qphy->qusb_phy_host_init_seq,
399 qphy->host_init_seq_len, 0);
400
401 /* Ensure above write is completed before turning ON ref clk */
402 wmb();
403
404 /* Require to get phy pll lock successfully */
405 usleep_range(150, 160);
406
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700407 reg = readb_relaxed(qphy->base + qphy->phy_reg[PLL_COMMON_STATUS_ONE]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700408 dev_dbg(phy->dev, "QUSB2PHY_PLL_COMMON_STATUS_ONE:%x\n", reg);
409 if (!(reg & CORE_READY_STATUS)) {
410 dev_err(phy->dev, "QUSB PHY PLL LOCK fails:%x\n", reg);
411 WARN_ON(1);
412 }
413}
414
415static int qusb_phy_init(struct usb_phy *phy)
416{
417 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
418 int ret;
419 u8 reg;
420
421 dev_dbg(phy->dev, "%s\n", __func__);
422
Hemant Kumar7dc63722017-04-27 17:51:11 -0700423 ret = qusb_phy_enable_power(qphy, true);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700424 if (ret)
425 return ret;
426
427 qusb_phy_enable_clocks(qphy, true);
428
Mayank Ranab7f212e2017-04-06 17:54:35 -0700429 qusb_phy_reset(qphy);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700430 if (qphy->emulation) {
431 if (qphy->emu_init_seq)
Mayank Rana147f41d2016-08-12 10:07:45 -0700432 qusb_phy_write_seq(qphy->emu_phy_base + 0x8000,
433 qphy->emu_init_seq,
434 qphy->emu_init_seq_len, 10000);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700435
436 if (qphy->qusb_phy_init_seq)
437 qusb_phy_write_seq(qphy->base, qphy->qusb_phy_init_seq,
438 qphy->init_seq_len, 0);
439
440 /* Wait for 5ms as per QUSB2 RUMI sequence */
441 usleep_range(5000, 7000);
442
443 if (qphy->phy_pll_reset_seq)
444 qusb_phy_write_seq(qphy->base, qphy->phy_pll_reset_seq,
445 qphy->phy_pll_reset_seq_len, 10000);
446
447 if (qphy->emu_dcm_reset_seq)
448 qusb_phy_write_seq(qphy->emu_phy_base,
449 qphy->emu_dcm_reset_seq,
450 qphy->emu_dcm_reset_seq_len, 10000);
451
452 return 0;
453 }
454
455 /* Disable the PHY */
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700456 writel_relaxed(readl_relaxed(qphy->base + qphy->phy_reg[PWR_CTRL1]) |
Mayank Rana3cb43a32016-08-02 12:10:20 -0700457 PWR_CTRL1_POWR_DOWN,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700458 qphy->base + qphy->phy_reg[PWR_CTRL1]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700459
460 if (qphy->qusb_phy_init_seq)
461 qusb_phy_write_seq(qphy->base, qphy->qusb_phy_init_seq,
462 qphy->init_seq_len, 0);
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700463 if (qphy->efuse_reg) {
464 if (!qphy->tune_val)
465 qusb_phy_get_tune1_param(qphy);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700466
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700467 pr_debug("%s(): Programming TUNE1 parameter as:%x\n", __func__,
468 qphy->tune_val);
469 writel_relaxed(qphy->tune_val,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700470 qphy->base + qphy->phy_reg[PORT_TUNE1]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700471 }
472
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700473 /* If phy_tune1 modparam set, override tune1 value */
474 if (phy_tune1) {
475 pr_debug("%s(): (modparam) TUNE1 val:0x%02x\n",
476 __func__, phy_tune1);
477 writel_relaxed(phy_tune1,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700478 qphy->base + qphy->phy_reg[PORT_TUNE1]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700479 }
480
481 /* ensure above writes are completed before re-enabling PHY */
482 wmb();
483
484 /* Enable the PHY */
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700485 writel_relaxed(readl_relaxed(qphy->base + qphy->phy_reg[PWR_CTRL1]) &
Mayank Rana3cb43a32016-08-02 12:10:20 -0700486 ~PWR_CTRL1_POWR_DOWN,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700487 qphy->base + qphy->phy_reg[PWR_CTRL1]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700488
489 /* Ensure above write is completed before turning ON ref clk */
490 wmb();
491
492 /* Require to get phy pll lock successfully */
493 usleep_range(150, 160);
494
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700495 reg = readb_relaxed(qphy->base + qphy->phy_reg[PLL_COMMON_STATUS_ONE]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700496 dev_dbg(phy->dev, "QUSB2PHY_PLL_COMMON_STATUS_ONE:%x\n", reg);
497 if (!(reg & CORE_READY_STATUS)) {
498 dev_err(phy->dev, "QUSB PHY PLL LOCK fails:%x\n", reg);
499 WARN_ON(1);
500 }
501 return 0;
502}
503
504static void qusb_phy_shutdown(struct usb_phy *phy)
505{
506 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
507
508 dev_dbg(phy->dev, "%s\n", __func__);
509
Vamsi Krishna Samavedam246d8442017-10-17 21:15:55 -0700510 qusb_phy_enable_power(qphy, false);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700511
Mayank Rana3cb43a32016-08-02 12:10:20 -0700512}
513
514static u32 qusb_phy_get_linestate(struct qusb_phy *qphy)
515{
516 u32 linestate = 0;
517
518 if (qphy->cable_connected) {
519 if (qphy->phy.flags & PHY_HSFS_MODE)
520 linestate |= LINESTATE_DP;
521 else if (qphy->phy.flags & PHY_LS_MODE)
522 linestate |= LINESTATE_DM;
523 }
524 return linestate;
525}
526
527/**
528 * Performs QUSB2 PHY suspend/resume functionality.
529 *
530 * @uphy - usb phy pointer.
531 * @suspend - to enable suspend or not. 1 - suspend, 0 - resume
532 *
533 */
534static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
535{
536 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
537 u32 linestate = 0, intr_mask = 0;
538
539 if (qphy->suspended && suspend) {
540 dev_dbg(phy->dev, "%s: USB PHY is already suspended\n",
541 __func__);
542 return 0;
543 }
544
545 if (suspend) {
546 /* Bus suspend case */
547 if (qphy->cable_connected ||
548 (qphy->phy.flags & PHY_HOST_MODE)) {
549 /* Disable all interrupts */
550 writel_relaxed(0x00,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700551 qphy->base + qphy->phy_reg[INTR_CTRL]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700552
553 linestate = qusb_phy_get_linestate(qphy);
554 /*
555 * D+/D- interrupts are level-triggered, but we are
556 * only interested if the line state changes, so enable
557 * the high/low trigger based on current state. In
558 * other words, enable the triggers _opposite_ of what
559 * the current D+/D- levels are.
560 * e.g. if currently D+ high, D- low (HS 'J'/Suspend),
561 * configure the mask to trigger on D+ low OR D- high
562 */
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700563 intr_mask = DPSE_INTR_EN | DMSE_INTR_EN;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700564 if (!(linestate & LINESTATE_DP)) /* D+ low */
565 intr_mask |= DPSE_INTR_HIGH_SEL;
566 if (!(linestate & LINESTATE_DM)) /* D- low */
567 intr_mask |= DMSE_INTR_HIGH_SEL;
568
569 writel_relaxed(intr_mask,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700570 qphy->base + qphy->phy_reg[INTR_CTRL]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700571
Mayank Ranab7f212e2017-04-06 17:54:35 -0700572 /* hold core PLL into reset */
573 writel_relaxed(CORE_PLL_EN_FROM_RESET |
574 CORE_RESET | CORE_RESET_MUX,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700575 qphy->base +
576 qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
Mayank Ranab7f212e2017-04-06 17:54:35 -0700577
Vijayavardhan Vennapusa46a01442017-07-06 10:52:30 +0530578 if (linestate & (LINESTATE_DP | LINESTATE_DM)) {
579 /* enable phy auto-resume */
580 writel_relaxed(0x91,
581 qphy->base + qphy->phy_reg[TEST1]);
582 /* flush the previous write before next write */
583 wmb();
584 writel_relaxed(0x90,
585 qphy->base + qphy->phy_reg[TEST1]);
586 }
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700587
Mayank Rana3cb43a32016-08-02 12:10:20 -0700588 dev_dbg(phy->dev, "%s: intr_mask = %x\n",
589 __func__, intr_mask);
590
591 /* Makes sure that above write goes through */
592 wmb();
593 qusb_phy_enable_clocks(qphy, false);
594 } else { /* Cable disconnect case */
595 /* Disable all interrupts */
596 writel_relaxed(0x00,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700597 qphy->base + qphy->phy_reg[INTR_CTRL]);
Mayank Ranab7f212e2017-04-06 17:54:35 -0700598 qusb_phy_reset(qphy);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700599 qusb_phy_enable_clocks(qphy, false);
Hemant Kumar7dc63722017-04-27 17:51:11 -0700600 qusb_phy_enable_power(qphy, false);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700601 }
602 qphy->suspended = true;
603 } else {
604 /* Bus resume case */
605 if (qphy->cable_connected ||
606 (qphy->phy.flags & PHY_HOST_MODE)) {
607 qusb_phy_enable_clocks(qphy, true);
608 /* Clear all interrupts on resume */
609 writel_relaxed(0x00,
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700610 qphy->base + qphy->phy_reg[INTR_CTRL]);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700611
Mayank Ranab7f212e2017-04-06 17:54:35 -0700612 /* bring core PLL out of reset */
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700613 writel_relaxed(CORE_PLL_EN_FROM_RESET, qphy->base +
614 qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
Mayank Ranab7f212e2017-04-06 17:54:35 -0700615
Mayank Rana3cb43a32016-08-02 12:10:20 -0700616 /* Makes sure that above write goes through */
617 wmb();
618 } else { /* Cable connect case */
Mayank Rana3cb43a32016-08-02 12:10:20 -0700619 qusb_phy_enable_clocks(qphy, true);
620 }
621 qphy->suspended = false;
622 }
623
624 return 0;
625}
626
627static int qusb_phy_notify_connect(struct usb_phy *phy,
628 enum usb_device_speed speed)
629{
630 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
631
632 qphy->cable_connected = true;
633
634 if (qphy->qusb_phy_host_init_seq && qphy->phy.flags & PHY_HOST_MODE)
635 qusb_phy_host_init(phy);
636
637 dev_dbg(phy->dev, "QUSB PHY: connect notification cable_connected=%d\n",
638 qphy->cable_connected);
639 return 0;
640}
641
642static int qusb_phy_notify_disconnect(struct usb_phy *phy,
643 enum usb_device_speed speed)
644{
645 struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
646
647 qphy->cable_connected = false;
648
649 dev_dbg(phy->dev, "QUSB PHY: connect notification cable_connected=%d\n",
650 qphy->cable_connected);
651 return 0;
652}
653
654static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev)
655{
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700656 int ret = 0;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700657 struct qusb_phy *qphy = rdev_get_drvdata(rdev);
658
Mayank Ranadadae592017-07-21 09:03:32 -0700659 dev_dbg(qphy->phy.dev, "%s dpdm_enable:%d\n",
660 __func__, qphy->dpdm_enable);
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700661
Mayank Ranadadae592017-07-21 09:03:32 -0700662 if (!qphy->dpdm_enable) {
Hemant Kumar7dc63722017-04-27 17:51:11 -0700663 ret = qusb_phy_enable_power(qphy, true);
Mayank Ranadadae592017-07-21 09:03:32 -0700664 if (ret < 0) {
665 dev_dbg(qphy->phy.dev,
666 "dpdm regulator enable failed:%d\n", ret);
667 return ret;
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700668 }
Mayank Ranadadae592017-07-21 09:03:32 -0700669 qphy->dpdm_enable = true;
Mayank Rana73450a02017-09-21 15:13:34 -0700670
671 if (qphy->eud_base) {
672 if (qphy->cfg_ahb_clk)
673 clk_prepare_enable(qphy->cfg_ahb_clk);
674 writel_relaxed(BIT(0),
675 qphy->eud_base + EUD_SW_ATTACH_DET);
676 /* to flush above write before next write */
677 wmb();
678
679 writel_relaxed(EUD_INT_VBUS | EUD_INT_CHGR,
680 qphy->eud_base + EUD_INT1_EN_MASK);
681 /* to flush above write before turning off clk */
682 wmb();
683 if (qphy->cfg_ahb_clk)
684 clk_disable_unprepare(qphy->cfg_ahb_clk);
685 }
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700686 }
687
688 return ret;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700689}
690
691static int qusb_phy_dpdm_regulator_disable(struct regulator_dev *rdev)
692{
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700693 int ret = 0;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700694 struct qusb_phy *qphy = rdev_get_drvdata(rdev);
695
Mayank Ranadadae592017-07-21 09:03:32 -0700696 dev_dbg(qphy->phy.dev, "%s dpdm_enable:%d\n",
697 __func__, qphy->dpdm_enable);
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700698
Mayank Ranadadae592017-07-21 09:03:32 -0700699 if (qphy->dpdm_enable) {
Mayank Rana73450a02017-09-21 15:13:34 -0700700 if (qphy->eud_base) {
701 if (qphy->cfg_ahb_clk)
702 clk_prepare_enable(qphy->cfg_ahb_clk);
703 writel_relaxed(0, qphy->eud_base + EUD_SW_ATTACH_DET);
704 /* to flush above write before turning off clk */
705 wmb();
706 if (qphy->cfg_ahb_clk)
707 clk_disable_unprepare(qphy->cfg_ahb_clk);
708 }
709
Hemant Kumar7dc63722017-04-27 17:51:11 -0700710 ret = qusb_phy_enable_power(qphy, false);
Mayank Ranadadae592017-07-21 09:03:32 -0700711 if (ret < 0) {
712 dev_dbg(qphy->phy.dev,
713 "dpdm regulator disable failed:%d\n", ret);
714 return ret;
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700715 }
Mayank Ranadadae592017-07-21 09:03:32 -0700716 qphy->dpdm_enable = false;
Mayank Ranaa69fe6c2016-08-09 18:04:58 -0700717 }
718
719 return ret;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700720}
721
722static int qusb_phy_dpdm_regulator_is_enabled(struct regulator_dev *rdev)
723{
724 struct qusb_phy *qphy = rdev_get_drvdata(rdev);
725
Mayank Ranadadae592017-07-21 09:03:32 -0700726 dev_dbg(qphy->phy.dev, "%s qphy->dpdm_enable = %d\n", __func__,
727 qphy->dpdm_enable);
728 return qphy->dpdm_enable;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700729}
730
731static struct regulator_ops qusb_phy_dpdm_regulator_ops = {
732 .enable = qusb_phy_dpdm_regulator_enable,
733 .disable = qusb_phy_dpdm_regulator_disable,
734 .is_enabled = qusb_phy_dpdm_regulator_is_enabled,
735};
736
737static int qusb_phy_regulator_init(struct qusb_phy *qphy)
738{
739 struct device *dev = qphy->phy.dev;
740 struct regulator_config cfg = {};
741 struct regulator_init_data *init_data;
742
743 init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
744 if (!init_data)
745 return -ENOMEM;
746
747 init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS;
748 qphy->dpdm_rdesc.owner = THIS_MODULE;
749 qphy->dpdm_rdesc.type = REGULATOR_VOLTAGE;
750 qphy->dpdm_rdesc.ops = &qusb_phy_dpdm_regulator_ops;
751 qphy->dpdm_rdesc.name = kbasename(dev->of_node->full_name);
752
753 cfg.dev = dev;
754 cfg.init_data = init_data;
755 cfg.driver_data = qphy;
756 cfg.of_node = dev->of_node;
757
758 qphy->dpdm_rdev = devm_regulator_register(dev, &qphy->dpdm_rdesc, &cfg);
759 if (IS_ERR(qphy->dpdm_rdev))
760 return PTR_ERR(qphy->dpdm_rdev);
761
762 return 0;
763}
764
765static int qusb_phy_probe(struct platform_device *pdev)
766{
767 struct qusb_phy *qphy;
768 struct device *dev = &pdev->dev;
769 struct resource *res;
770 int ret = 0, size = 0;
771
772 qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
773 if (!qphy)
774 return -ENOMEM;
775
776 qphy->phy.dev = dev;
777 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
778 "qusb_phy_base");
779 qphy->base = devm_ioremap_resource(dev, res);
780 if (IS_ERR(qphy->base))
781 return PTR_ERR(qphy->base);
782
783 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
784 "emu_phy_base");
785 if (res) {
786 qphy->emu_phy_base = devm_ioremap_resource(dev, res);
787 if (IS_ERR(qphy->emu_phy_base)) {
788 dev_dbg(dev, "couldn't ioremap emu_phy_base\n");
789 qphy->emu_phy_base = NULL;
790 }
791 }
792
793 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700794 "efuse_addr");
Mayank Rana3cb43a32016-08-02 12:10:20 -0700795 if (res) {
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700796 qphy->efuse_reg = devm_ioremap_nocache(dev, res->start,
Mayank Rana3cb43a32016-08-02 12:10:20 -0700797 resource_size(res));
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700798 if (!IS_ERR_OR_NULL(qphy->efuse_reg)) {
Mayank Rana3cb43a32016-08-02 12:10:20 -0700799 ret = of_property_read_u32(dev->of_node,
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700800 "qcom,efuse-bit-pos",
801 &qphy->efuse_bit_pos);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700802 if (!ret) {
803 ret = of_property_read_u32(dev->of_node,
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700804 "qcom,efuse-num-bits",
805 &qphy->efuse_num_of_bits);
Mayank Rana3cb43a32016-08-02 12:10:20 -0700806 }
807
808 if (ret) {
809 dev_err(dev,
Vamsi Krishna Samavedamf4da1dc2016-08-25 13:57:21 -0700810 "DT Value for efuse is invalid.\n");
Mayank Rana3cb43a32016-08-02 12:10:20 -0700811 return -EINVAL;
812 }
813 }
814 }
815
Mayank Rana73450a02017-09-21 15:13:34 -0700816 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
817 "eud_base");
818 if (res) {
819 qphy->eud_base = devm_ioremap(dev, res->start,
820 resource_size(res));
821 if (IS_ERR(qphy->eud_base)) {
822 dev_dbg(dev, "couldn't ioremap eud_base\n");
823 qphy->eud_base = NULL;
824 }
825 }
826
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700827 /* ref_clk_src is needed irrespective of SE_CLK or DIFF_CLK usage */
Mayank Rana3cb43a32016-08-02 12:10:20 -0700828 qphy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700829 if (IS_ERR(qphy->ref_clk_src)) {
Mayank Rana3cb43a32016-08-02 12:10:20 -0700830 dev_dbg(dev, "clk get failed for ref_clk_src\n");
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700831 ret = PTR_ERR(qphy->ref_clk_src);
832 return ret;
833 }
Mayank Rana3cb43a32016-08-02 12:10:20 -0700834
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700835 /* ref_clk is needed only for DIFF_CLK case, hence make it optional. */
836 if (of_property_match_string(pdev->dev.of_node,
837 "clock-names", "ref_clk") >= 0) {
838 qphy->ref_clk = devm_clk_get(dev, "ref_clk");
839 if (IS_ERR(qphy->ref_clk)) {
840 ret = PTR_ERR(qphy->ref_clk);
841 if (ret != -EPROBE_DEFER)
842 dev_dbg(dev,
843 "clk get failed for ref_clk\n");
844 return ret;
845 }
846
Mayank Rana3cb43a32016-08-02 12:10:20 -0700847 clk_set_rate(qphy->ref_clk, 19200000);
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -0700848 }
Mayank Rana3cb43a32016-08-02 12:10:20 -0700849
850 if (of_property_match_string(pdev->dev.of_node,
851 "clock-names", "cfg_ahb_clk") >= 0) {
852 qphy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk");
853 if (IS_ERR(qphy->cfg_ahb_clk)) {
854 ret = PTR_ERR(qphy->cfg_ahb_clk);
855 if (ret != -EPROBE_DEFER)
856 dev_err(dev,
857 "clk get failed for cfg_ahb_clk ret %d\n", ret);
858 return ret;
859 }
860 }
861
Amit Nischal4d278212016-06-06 17:54:34 +0530862 qphy->phy_reset = devm_reset_control_get(dev, "phy_reset");
Mayank Rana3cb43a32016-08-02 12:10:20 -0700863 if (IS_ERR(qphy->phy_reset))
864 return PTR_ERR(qphy->phy_reset);
865
866 qphy->emulation = of_property_read_bool(dev->of_node,
867 "qcom,emulation");
868
869 of_get_property(dev->of_node, "qcom,emu-init-seq", &size);
870 if (size) {
871 qphy->emu_init_seq = devm_kzalloc(dev,
872 size, GFP_KERNEL);
873 if (qphy->emu_init_seq) {
874 qphy->emu_init_seq_len =
875 (size / sizeof(*qphy->emu_init_seq));
876 if (qphy->emu_init_seq_len % 2) {
877 dev_err(dev, "invalid emu_init_seq_len\n");
878 return -EINVAL;
879 }
880
881 of_property_read_u32_array(dev->of_node,
Mayank Rana147f41d2016-08-12 10:07:45 -0700882 "qcom,emu-init-seq",
Mayank Rana3cb43a32016-08-02 12:10:20 -0700883 qphy->emu_init_seq,
884 qphy->emu_init_seq_len);
885 } else {
886 dev_dbg(dev,
887 "error allocating memory for emu_init_seq\n");
888 }
889 }
890
Mayank Rana147f41d2016-08-12 10:07:45 -0700891 size = 0;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700892 of_get_property(dev->of_node, "qcom,phy-pll-reset-seq", &size);
893 if (size) {
894 qphy->phy_pll_reset_seq = devm_kzalloc(dev,
895 size, GFP_KERNEL);
896 if (qphy->phy_pll_reset_seq) {
897 qphy->phy_pll_reset_seq_len =
898 (size / sizeof(*qphy->phy_pll_reset_seq));
899 if (qphy->phy_pll_reset_seq_len % 2) {
900 dev_err(dev, "invalid phy_pll_reset_seq_len\n");
901 return -EINVAL;
902 }
903
904 of_property_read_u32_array(dev->of_node,
905 "qcom,phy-pll-reset-seq",
906 qphy->phy_pll_reset_seq,
907 qphy->phy_pll_reset_seq_len);
908 } else {
909 dev_dbg(dev,
910 "error allocating memory for phy_pll_reset_seq\n");
911 }
912 }
913
Mayank Rana147f41d2016-08-12 10:07:45 -0700914 size = 0;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700915 of_get_property(dev->of_node, "qcom,emu-dcm-reset-seq", &size);
916 if (size) {
917 qphy->emu_dcm_reset_seq = devm_kzalloc(dev,
918 size, GFP_KERNEL);
919 if (qphy->emu_dcm_reset_seq) {
920 qphy->emu_dcm_reset_seq_len =
921 (size / sizeof(*qphy->emu_dcm_reset_seq));
922 if (qphy->emu_dcm_reset_seq_len % 2) {
923 dev_err(dev, "invalid emu_dcm_reset_seq_len\n");
924 return -EINVAL;
925 }
926
927 of_property_read_u32_array(dev->of_node,
928 "qcom,emu-dcm-reset-seq",
929 qphy->emu_dcm_reset_seq,
930 qphy->emu_dcm_reset_seq_len);
931 } else {
932 dev_dbg(dev,
933 "error allocating memory for emu_dcm_reset_seq\n");
934 }
935 }
936
Mayank Rana147f41d2016-08-12 10:07:45 -0700937 size = 0;
Mayank Rana9c6b12d2017-06-22 16:23:26 -0700938 of_get_property(dev->of_node, "qcom,qusb-phy-reg-offset", &size);
939 if (size) {
940 qphy->phy_reg = devm_kzalloc(dev, size, GFP_KERNEL);
941 if (qphy->phy_reg) {
942 qphy->qusb_phy_reg_offset_cnt =
943 size / sizeof(*qphy->phy_reg);
944 if (qphy->qusb_phy_reg_offset_cnt > USB2_PHY_REG_MAX) {
945 dev_err(dev, "invalid reg offset count\n");
946 return -EINVAL;
947 }
948
949 of_property_read_u32_array(dev->of_node,
950 "qcom,qusb-phy-reg-offset",
951 qphy->phy_reg,
952 qphy->qusb_phy_reg_offset_cnt);
953 } else {
954 dev_err(dev, "err mem alloc for qusb_phy_reg_offset\n");
955 return -ENOMEM;
956 }
957 } else {
958 dev_err(dev, "err provide qcom,qmp-phy-reg-offset\n");
959 return -EINVAL;
960 }
961
962 size = 0;
Mayank Rana3cb43a32016-08-02 12:10:20 -0700963 of_get_property(dev->of_node, "qcom,qusb-phy-init-seq", &size);
964 if (size) {
965 qphy->qusb_phy_init_seq = devm_kzalloc(dev,
966 size, GFP_KERNEL);
967 if (qphy->qusb_phy_init_seq) {
968 qphy->init_seq_len =
969 (size / sizeof(*qphy->qusb_phy_init_seq));
970 if (qphy->init_seq_len % 2) {
971 dev_err(dev, "invalid init_seq_len\n");
972 return -EINVAL;
973 }
974
975 of_property_read_u32_array(dev->of_node,
976 "qcom,qusb-phy-init-seq",
977 qphy->qusb_phy_init_seq,
978 qphy->init_seq_len);
979 } else {
980 dev_err(dev,
981 "error allocating memory for phy_init_seq\n");
982 }
983 }
984
985 qphy->host_init_seq_len = of_property_count_elems_of_size(dev->of_node,
986 "qcom,qusb-phy-host-init-seq",
987 sizeof(*qphy->qusb_phy_host_init_seq));
988 if (qphy->host_init_seq_len > 0) {
989 qphy->qusb_phy_host_init_seq = devm_kcalloc(dev,
990 qphy->host_init_seq_len,
991 sizeof(*qphy->qusb_phy_host_init_seq),
992 GFP_KERNEL);
993 if (qphy->qusb_phy_host_init_seq)
994 of_property_read_u32_array(dev->of_node,
995 "qcom,qusb-phy-host-init-seq",
996 qphy->qusb_phy_host_init_seq,
997 qphy->host_init_seq_len);
998 else
999 return -ENOMEM;
1000 }
1001
1002 ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level",
1003 (u32 *) qphy->vdd_levels,
1004 ARRAY_SIZE(qphy->vdd_levels));
1005 if (ret) {
1006 dev_err(dev, "error reading qcom,vdd-voltage-level property\n");
1007 return ret;
1008 }
1009
1010 qphy->vdd = devm_regulator_get(dev, "vdd");
1011 if (IS_ERR(qphy->vdd)) {
1012 dev_err(dev, "unable to get vdd supply\n");
1013 return PTR_ERR(qphy->vdd);
1014 }
1015
1016 qphy->vdda33 = devm_regulator_get(dev, "vdda33");
1017 if (IS_ERR(qphy->vdda33)) {
1018 dev_err(dev, "unable to get vdda33 supply\n");
1019 return PTR_ERR(qphy->vdda33);
1020 }
1021
1022 qphy->vdda18 = devm_regulator_get(dev, "vdda18");
1023 if (IS_ERR(qphy->vdda18)) {
1024 dev_err(dev, "unable to get vdda18 supply\n");
1025 return PTR_ERR(qphy->vdda18);
1026 }
1027
Hemant Kumar164cc1b2017-04-27 19:39:58 -07001028 mutex_init(&qphy->lock);
Mayank Rana3cb43a32016-08-02 12:10:20 -07001029 platform_set_drvdata(pdev, qphy);
1030
1031 qphy->phy.label = "msm-qusb-phy-v2";
1032 qphy->phy.init = qusb_phy_init;
1033 qphy->phy.set_suspend = qusb_phy_set_suspend;
1034 qphy->phy.shutdown = qusb_phy_shutdown;
1035 qphy->phy.type = USB_PHY_TYPE_USB2;
1036 qphy->phy.notify_connect = qusb_phy_notify_connect;
1037 qphy->phy.notify_disconnect = qusb_phy_notify_disconnect;
1038
1039 ret = usb_add_phy_dev(&qphy->phy);
1040 if (ret)
1041 return ret;
1042
Vamsi Krishna Samavedam42e2a0d2017-10-16 13:55:54 -07001043 /* ldo24 is turned on and eud is pet irrespective of cable
1044 * cable connection status by boot sw. Assume usb cable is not
1045 * connected and perform detach pet. If usb cable is connected,
1046 * eud hw will be pet in the dpdm callback.
1047 */
1048 if (qphy->eud_base) {
1049 if (qphy->cfg_ahb_clk)
1050 clk_prepare_enable(qphy->cfg_ahb_clk);
1051
1052 writel_relaxed(0, qphy->eud_base + EUD_SW_ATTACH_DET);
1053
1054 if (qphy->cfg_ahb_clk)
1055 clk_disable_unprepare(qphy->cfg_ahb_clk);
1056 }
1057
Mayank Rana3cb43a32016-08-02 12:10:20 -07001058 ret = qusb_phy_regulator_init(qphy);
1059 if (ret)
1060 usb_remove_phy(&qphy->phy);
1061
1062 return ret;
1063}
1064
1065static int qusb_phy_remove(struct platform_device *pdev)
1066{
1067 struct qusb_phy *qphy = platform_get_drvdata(pdev);
1068
1069 usb_remove_phy(&qphy->phy);
Devdutt Patnaik1c03dfd2017-03-19 23:38:43 -07001070 qusb_phy_enable_clocks(qphy, false);
Hemant Kumar7dc63722017-04-27 17:51:11 -07001071 qusb_phy_enable_power(qphy, false);
Mayank Rana3cb43a32016-08-02 12:10:20 -07001072
1073 return 0;
1074}
1075
1076static const struct of_device_id qusb_phy_id_table[] = {
1077 { .compatible = "qcom,qusb2phy-v2", },
1078 { },
1079};
1080MODULE_DEVICE_TABLE(of, qusb_phy_id_table);
1081
1082static struct platform_driver qusb_phy_driver = {
1083 .probe = qusb_phy_probe,
1084 .remove = qusb_phy_remove,
1085 .driver = {
1086 .name = "msm-qusb-phy-v2",
1087 .of_match_table = of_match_ptr(qusb_phy_id_table),
1088 },
1089};
1090
1091module_platform_driver(qusb_phy_driver);
1092
1093MODULE_DESCRIPTION("MSM QUSB2 PHY v2 driver");
1094MODULE_LICENSE("GPL v2");