xref: /linux/drivers/phy/phy-google-usb.c (revision 4dd10fbbeb9c33709edc89916e19c03c780a0751)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * phy-google-usb.c - Google USB PHY driver
4  *
5  * Copyright (C) 2025, Google LLC
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/cleanup.h>
10 #include <linux/clk.h>
11 #include <linux/io.h>
12 #include <linux/iopoll.h>
13 #include <linux/kernel.h>
14 #include <linux/mfd/syscon.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/of.h>
18 #include <linux/phy/phy.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/reset.h>
23 #include <linux/usb/typec_mux.h>
24 
25 /* USB_CFG_CSR */
26 #define USBCS_USB2PHY_CFG19_OFFSET 0x0
27 #define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
28 
29 #define USBCS_USB2PHY_CFG21_OFFSET 0x8
30 #define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
31 #define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
32 #define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
33 
34 /* USBDP_TOP */
35 #define USBCS_PHY_CFG1_OFFSET 0x28
36 #define USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN BIT(1)
37 #define USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE GENMASK(11, 10)
38 #define SRAM_BYPASS_MODE_BYPASS_FIRMWARE BIT(0)
39 #define SRAM_BYPASS_MODE_BYPASS_CONTEXT BIT(1)
40 #define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
41 
42 #define USBDP_TOP_CFG_REG_OFFSET 0x44
43 #define USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N BIT(0)
44 
45 #define PHY_POWER_CONFIG_REG1_OFFSET 0x48
46 #define PHY_POWER_CONFIG_REG1_PG_MODE_EN BIT(1)
47 #define PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG GENMASK(31, 14)
48 #define UPCS_PIPE_CONFIG_ISO_CPM BIT(5)
49 #define UPCS_PIPE_CONFIG_PG_MODE_STATIC BIT(6)
50 #define UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT BIT(9)
51 
52 /* USB3_TCA */
53 #define TCA_INTR_STS_OFFSET 0x8
54 #define TCA_INTR_STS_XA_ACT_EVT BIT(0)
55 #define TCA_TCPC_OFFSET 0x14
56 #define TCA_TCPC_MUX_CONTROL GENMASK(2, 0)
57 #define TCA_TCPC_MUX_CONTROL_USB_ONLY 0x1
58 #define TCA_TCPC_CONNECTOR_ORIENTATION BIT(3)
59 #define TCA_TCPC_VALID BIT(4)
60 #define TCA_CTRLSYNCMODE_CFG1_OFFSET 0x24
61 #define TCA_CTRLSYNCMODE_CFG1_XA_TIMEOUT_VAL GENMASK(19, 0)
62 #define TCA_CTRLSYNCMODE_CFG1_XA_TIMEOUT_VAL_100MS 0x1e85
63 #define TCA_PSTATE_0_OFFSET 0x50
64 #define TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS BIT(8)
65 
66 #define GPHY_TCA_DELAY_US 10
67 #define GPHY_TCA_TIMEOUT_US 110000
68 
69 enum google_usb_phy_id {
70 	GOOGLE_USB2_PHY,
71 	GOOGLE_USB3_PHY,
72 	GOOGLE_USB_PHY_NUM,
73 };
74 
75 struct google_usb_phy_instance {
76 	struct google_usb_phy *parent;
77 	unsigned int index;
78 	struct phy *phy;
79 	unsigned int num_clks;
80 	struct clk_bulk_data *clks;
81 	unsigned int num_rsts;
82 	struct reset_control_bulk_data *rsts;
83 };
84 
85 struct google_usb_phy_config {
86 	const char * const *clk_names;
87 	unsigned int num_clks;
88 	const char * const *rst_names;
89 	unsigned int num_rsts;
90 };
91 
92 static const char * const u2phy_clk_names[] = {
93 	"usb2",
94 	"usb2_apb",
95 };
96 
97 static const char * const u3phy_clk_names[] = {
98 	"usb3"
99 };
100 
101 static const char * const u2phy_rst_names[] = {
102 	"usb2",
103 	"usb2_apb",
104 };
105 
106 static const char * const u3phy_rst_names[] = {
107 	"usb3"
108 };
109 
110 static const struct google_usb_phy_config phy_configs[GOOGLE_USB_PHY_NUM] = {
111 	[GOOGLE_USB2_PHY] = {
112 		.clk_names = u2phy_clk_names,
113 		.num_clks = ARRAY_SIZE(u2phy_clk_names),
114 		.rst_names = u2phy_rst_names,
115 		.num_rsts = ARRAY_SIZE(u2phy_rst_names),
116 	},
117 	[GOOGLE_USB3_PHY] = {
118 		.clk_names = u3phy_clk_names,
119 		.num_clks = ARRAY_SIZE(u3phy_clk_names),
120 		.rst_names = u3phy_rst_names,
121 		.num_rsts = ARRAY_SIZE(u3phy_rst_names),
122 	},
123 };
124 
125 static inline void google_usb_phy_clk_disable(struct google_usb_phy_instance *inst)
126 {
127 	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
128 }
129 
130 DEFINE_FREE(inst_clk_disable, struct google_usb_phy_instance *,
131 	    if (_T) google_usb_phy_clk_disable(_T))
132 
133 static inline void google_usb_phy_rst_disable(struct google_usb_phy_instance *inst)
134 {
135 	reset_control_bulk_assert(inst->num_rsts, inst->rsts);
136 }
137 
138 DEFINE_FREE(inst_rst_disable, struct google_usb_phy_instance *,
139 	    if (_T) google_usb_phy_rst_disable(_T))
140 
141 /*
142  * combo_phy_state
143  *	COMBO_PHY_IDLE: The ComboPHY has been torn down and USB3 has not completed
144  *			bringup
145  *	COMBO_PHY_INIT_DONE: The ComboPHY bringup sequence is complete.
146  *	COMBO_PHY_TCA_READY: The PoR => NC transition is complete, and the TCA can be
147  *			     moved into USB.
148  */
149 enum combo_phy_state {
150 	COMBO_PHY_IDLE,
151 	COMBO_PHY_INIT_DONE,
152 	COMBO_PHY_TCA_READY,
153 };
154 
155 struct google_usb_phy {
156 	struct device *dev;
157 	struct regmap *usb_cfg_regmap;
158 	unsigned int usb2_cfg_offset;
159 	void __iomem *usbdp_top_base;
160 	void __iomem *usb3_tca_base;
161 	struct google_usb_phy_instance *insts;
162 	/*
163 	 * Protect phy registers from concurrent access, specifically via
164 	 * google_usb_set_orientation callback. phy_mutex also protects
165 	 * concurrent access to phy_state.
166 	 */
167 	struct mutex phy_mutex;
168 	struct typec_switch_dev *sw;
169 	enum typec_orientation orientation;
170 	enum combo_phy_state phy_state;
171 };
172 
173 static void set_vbus_valid(struct google_usb_phy *gphy)
174 {
175 	u32 reg;
176 
177 	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
178 	if (gphy->orientation == TYPEC_ORIENTATION_NONE)
179 		reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
180 	else
181 		reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
182 	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
183 }
184 
185 static void set_sram_bypass(struct google_usb_phy *gphy, u32 bypass)
186 {
187 	u32 reg;
188 
189 	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
190 	reg &= ~USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE;
191 	reg |= FIELD_PREP(USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE, bypass);
192 	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
193 }
194 
195 static void set_pmgt_ref_clk_req_n(struct google_usb_phy *gphy, bool resume)
196 {
197 	u32 reg;
198 
199 	reg = readl(gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
200 	if (resume)
201 		reg |= USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
202 	else
203 		reg &= ~USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
204 	writel(reg, gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
205 }
206 
207 static inline void disable_pmgt_ref_clk_req_n(struct google_usb_phy *gphy)
208 {
209 	set_pmgt_ref_clk_req_n(gphy, false);
210 }
211 
212 DEFINE_FREE(pmgt_ref_clk_req_n, struct google_usb_phy *, if (_T) disable_pmgt_ref_clk_req_n(_T))
213 
214 static int wait_tca_xa_ack(struct google_usb_phy *gphy)
215 {
216 	int ret;
217 	u32 reg;
218 
219 	ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET,
220 				 reg, !!(reg & TCA_INTR_STS_XA_ACT_EVT),
221 				 GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
222 	if (ret)
223 		dev_err(gphy->dev, "tca xa_ack timeout, ret=%d\n", ret);
224 
225 	return ret;
226 }
227 
228 static int program_tca_locked(struct google_usb_phy *gphy)
229 	   __must_hold(&gphy->phy_mutex)
230 {
231 	int ret;
232 	u32 reg;
233 
234 	reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
235 	writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
236 
237 	reg = readl(gphy->usb3_tca_base + TCA_TCPC_OFFSET);
238 	reg &= ~TCA_TCPC_MUX_CONTROL;
239 	reg |= FIELD_PREP(TCA_TCPC_MUX_CONTROL, TCA_TCPC_MUX_CONTROL_USB_ONLY);
240 	if (gphy->orientation == TYPEC_ORIENTATION_REVERSE)
241 		reg |= TCA_TCPC_CONNECTOR_ORIENTATION;
242 	else
243 		reg &= ~TCA_TCPC_CONNECTOR_ORIENTATION;
244 	reg |= TCA_TCPC_VALID;
245 	writel(reg, gphy->usb3_tca_base + TCA_TCPC_OFFSET);
246 
247 	ret = wait_tca_xa_ack(gphy);
248 	dev_dbg(gphy->dev, "TCA switch %s, mux %lu, orientation %s\n",
249 		ret ? "failed" : "success",
250 		FIELD_GET(TCA_TCPC_MUX_CONTROL, reg),
251 		FIELD_GET(TCA_TCPC_CONNECTOR_ORIENTATION, reg) ? "reverse" : "normal");
252 
253 	reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
254 	writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
255 
256 	return ret;
257 }
258 
259 static int google_usb_set_orientation(struct typec_switch_dev *sw,
260 				      enum typec_orientation orientation)
261 {
262 	struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
263 	int ret = 0;
264 
265 	dev_dbg(gphy->dev, "set orientation %d\n", orientation);
266 
267 	guard(mutex)(&gphy->phy_mutex);
268 
269 	gphy->orientation = orientation;
270 
271 	if (IS_ENABLED(CONFIG_PM)) {
272 		if (pm_runtime_get_if_active(gphy->dev) <= 0)
273 			return 0;
274 	}
275 
276 	set_vbus_valid(gphy);
277 
278 	if (gphy->phy_state == COMBO_PHY_TCA_READY && orientation != TYPEC_ORIENTATION_NONE)
279 		ret = program_tca_locked(gphy);
280 
281 	pm_runtime_put(gphy->dev);
282 
283 	return ret;
284 }
285 
286 static int google_usb2_phy_init(struct phy *_phy)
287 {
288 	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
289 	struct google_usb_phy *gphy = inst->parent;
290 	u32 reg;
291 	int ret;
292 
293 	dev_dbg(gphy->dev, "initializing usb2 phy\n");
294 
295 	guard(mutex)(&gphy->phy_mutex);
296 
297 	regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg);
298 	reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
299 	reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
300 	reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
301 	regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
302 
303 	regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, &reg);
304 	reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
305 	reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);
306 	regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, reg);
307 
308 	set_vbus_valid(gphy);
309 
310 	ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
311 	if (ret)
312 		return ret;
313 	struct google_usb_phy_instance *clk_dev __free(inst_clk_disable) = inst;
314 
315 	ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
316 	if (ret)
317 		return ret;
318 
319 	regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg);
320 	reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
321 	regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
322 
323 	retain_and_null_ptr(clk_dev);
324 
325 	return 0;
326 }
327 
328 static int google_usb2_phy_exit(struct phy *_phy)
329 {
330 	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
331 	struct google_usb_phy *gphy = inst->parent;
332 	u32 reg;
333 
334 	dev_dbg(gphy->dev, "exiting usb2 phy\n");
335 
336 	guard(mutex)(&gphy->phy_mutex);
337 
338 	regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, &reg);
339 	reg &= ~USBCS_USB2PHY_CFG21_PHY_ENABLE;
340 	regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
341 
342 	reset_control_bulk_assert(inst->num_rsts, inst->rsts);
343 	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
344 
345 	return 0;
346 }
347 
348 static const struct phy_ops google_usb2_phy_ops = {
349 	.init		= google_usb2_phy_init,
350 	.exit		= google_usb2_phy_exit,
351 };
352 
353 static int google_usb3_phy_init(struct phy *_phy)
354 {
355 	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
356 	struct google_usb_phy *gphy = inst->parent;
357 	int ret = 0;
358 	u32 reg;
359 
360 	dev_dbg(gphy->dev, "initializing usb3 phy\n");
361 
362 	guard(mutex)(&gphy->phy_mutex);
363 
364 	if (gphy->phy_state != COMBO_PHY_IDLE) {
365 		dev_warn(gphy->dev, "usb3 phy init called when combo phy state is not idle\n");
366 		return 0;
367 	}
368 
369 	reg = readl(gphy->usb3_tca_base + TCA_CTRLSYNCMODE_CFG1_OFFSET);
370 	reg &= ~TCA_CTRLSYNCMODE_CFG1_XA_TIMEOUT_VAL;
371 	reg |= FIELD_PREP(TCA_CTRLSYNCMODE_CFG1_XA_TIMEOUT_VAL,
372 			  TCA_CTRLSYNCMODE_CFG1_XA_TIMEOUT_VAL_100MS);
373 	writel(reg, gphy->usb3_tca_base + TCA_CTRLSYNCMODE_CFG1_OFFSET);
374 
375 	reg = readl(gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
376 	reg |= PHY_POWER_CONFIG_REG1_PG_MODE_EN;
377 	reg &= ~PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG;
378 	reg |= FIELD_PREP(PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG,
379 			  (UPCS_PIPE_CONFIG_ISO_CPM |
380 			   UPCS_PIPE_CONFIG_PG_MODE_STATIC |
381 			   UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT));
382 	writel(reg, gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
383 
384 	set_vbus_valid(gphy);
385 
386 	reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
387 	reg |= USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN;
388 	writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
389 
390 	set_sram_bypass(gphy, SRAM_BYPASS_MODE_BYPASS_FIRMWARE |
391 			SRAM_BYPASS_MODE_BYPASS_CONTEXT);
392 	set_pmgt_ref_clk_req_n(gphy, true);
393 	struct google_usb_phy *pmgt_ref_clk_req_dev __free(pmgt_ref_clk_req_n) = gphy;
394 
395 	ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
396 	if (ret)
397 		return ret;
398 	struct google_usb_phy_instance *clk_dev __free(inst_clk_disable) = inst;
399 
400 	ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
401 	if (ret)
402 		return ret;
403 	struct google_usb_phy_instance *rst_dev __free(inst_rst_disable) = inst;
404 
405 	ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_PSTATE_0_OFFSET,
406 				 reg, !(reg & TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS),
407 				 GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
408 	if (ret) {
409 		dev_err(gphy->dev, "wait for lane0 phystatus timed out\n");
410 		return ret;
411 	}
412 
413 	gphy->phy_state = COMBO_PHY_INIT_DONE;
414 
415 	retain_and_null_ptr(rst_dev);
416 	retain_and_null_ptr(clk_dev);
417 	retain_and_null_ptr(pmgt_ref_clk_req_dev);
418 
419 	return 0;
420 }
421 
422 static int google_usb3_phy_exit(struct phy *_phy)
423 {
424 	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
425 	struct google_usb_phy *gphy = inst->parent;
426 
427 	dev_dbg(gphy->dev, "exiting usb3 phy\n");
428 
429 	guard(mutex)(&gphy->phy_mutex);
430 
431 	reset_control_bulk_assert(inst->num_rsts, inst->rsts);
432 	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
433 	set_pmgt_ref_clk_req_n(gphy, false);
434 
435 	gphy->phy_state = COMBO_PHY_IDLE;
436 
437 	return 0;
438 }
439 
440 static int google_usb3_phy_power_on(struct phy *_phy)
441 {
442 	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
443 	struct google_usb_phy *gphy = inst->parent;
444 	int ret;
445 
446 	dev_dbg(gphy->dev, "power on usb3 phy\n");
447 
448 	guard(mutex)(&gphy->phy_mutex);
449 
450 	if (gphy->phy_state == COMBO_PHY_IDLE)
451 		return -EINVAL;
452 
453 	if (gphy->phy_state == COMBO_PHY_INIT_DONE) {
454 		/* Wait for PoR -> NC transitions*/
455 		ret = wait_tca_xa_ack(gphy);
456 		if (ret) {
457 			dev_err(gphy->dev, "PoR->NC transition timeout\n");
458 			return ret;
459 		}
460 		gphy->phy_state = COMBO_PHY_TCA_READY;
461 	}
462 
463 	if (gphy->orientation != TYPEC_ORIENTATION_NONE)
464 		return program_tca_locked(gphy);
465 
466 	return 0;
467 }
468 
469 static const struct phy_ops google_usb3_phy_ops = {
470 	.init		= google_usb3_phy_init,
471 	.exit		= google_usb3_phy_exit,
472 	.power_on	= google_usb3_phy_power_on,
473 };
474 
475 static struct phy *google_usb_phy_xlate(struct device *dev,
476 					const struct of_phandle_args *args)
477 {
478 	struct google_usb_phy *gphy = dev_get_drvdata(dev);
479 
480 	if (args->args[0] >= GOOGLE_USB_PHY_NUM) {
481 		dev_err(dev, "invalid PHY index requested from DT\n");
482 		return ERR_PTR(-ENODEV);
483 	}
484 	return gphy->insts[args->args[0]].phy;
485 }
486 
487 static int google_usb_phy_parse_clocks(struct google_usb_phy *gphy)
488 {
489 	struct device *dev = gphy->dev;
490 	int id, i, ret;
491 
492 	for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
493 		const struct google_usb_phy_config *cfg = &phy_configs[id];
494 		struct google_usb_phy_instance *inst = &gphy->insts[id];
495 
496 		inst->num_clks = cfg->num_clks;
497 		inst->clks = devm_kzalloc_objs(dev, *inst->clks, inst->num_clks);
498 		if (!inst->clks)
499 			return -ENOMEM;
500 
501 		for (i = 0; i < inst->num_clks; i++)
502 			inst->clks[i].id = cfg->clk_names[i];
503 
504 		ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
505 		if (ret)
506 			return dev_err_probe(dev, ret, "failed to get phy%d clks\n", id);
507 	}
508 
509 	return 0;
510 }
511 
512 static int google_usb_phy_parse_resets(struct google_usb_phy *gphy)
513 {
514 	struct device *dev = gphy->dev;
515 	int id, i, ret;
516 
517 	for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
518 		const struct google_usb_phy_config *cfg = &phy_configs[id];
519 		struct google_usb_phy_instance *inst = &gphy->insts[id];
520 
521 		inst->num_rsts = cfg->num_rsts;
522 		inst->rsts = devm_kzalloc_objs(dev, *inst->rsts, inst->num_rsts);
523 		if (!inst->rsts)
524 			return -ENOMEM;
525 
526 		for (i = 0; i < inst->num_rsts; i++)
527 			inst->rsts[i].id = cfg->rst_names[i];
528 		ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
529 		if (ret)
530 			return dev_err_probe(dev, ret, "failed to get phy%d resets\n", id);
531 	}
532 
533 	return 0;
534 }
535 
536 static int google_usb_phy_probe(struct platform_device *pdev)
537 {
538 	struct typec_switch_desc sw_desc = { };
539 	struct phy_provider *phy_provider;
540 	struct device *dev = &pdev->dev;
541 	struct google_usb_phy *gphy;
542 	u32 args[1];
543 	int ret;
544 
545 	gphy = devm_kzalloc_obj(dev, *gphy);
546 	if (!gphy)
547 		return -ENOMEM;
548 
549 	dev_set_drvdata(dev, gphy);
550 	gphy->dev = dev;
551 
552 	ret = devm_mutex_init(dev, &gphy->phy_mutex);
553 	if (ret)
554 		return ret;
555 
556 	gphy->usb_cfg_regmap =
557 		syscon_regmap_lookup_by_phandle_args(dev->of_node,
558 						     "google,usb-cfg-csr",
559 						     ARRAY_SIZE(args), args);
560 	if (IS_ERR(gphy->usb_cfg_regmap)) {
561 		return dev_err_probe(dev, PTR_ERR(gphy->usb_cfg_regmap),
562 				     "invalid usb cfg csr\n");
563 	}
564 
565 	gphy->usb2_cfg_offset = args[0];
566 
567 	gphy->usbdp_top_base = devm_platform_ioremap_resource_byname(pdev,
568 								     "usbdp_top");
569 	if (IS_ERR(gphy->usbdp_top_base))
570 		return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base),
571 				    "invalid usbdp top\n");
572 
573 	gphy->usb3_tca_base = devm_platform_ioremap_resource_byname(pdev,
574 								    "usb3_tca");
575 	if (IS_ERR(gphy->usb3_tca_base))
576 		return dev_err_probe(dev, PTR_ERR(gphy->usb3_tca_base),
577 				    "invalid usb3 tca\n");
578 
579 	gphy->insts = devm_kzalloc_objs(dev, *gphy->insts, GOOGLE_USB_PHY_NUM);
580 	if (!gphy->insts)
581 		return -ENOMEM;
582 
583 	gphy->insts[GOOGLE_USB2_PHY].phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
584 	gphy->insts[GOOGLE_USB2_PHY].index = GOOGLE_USB2_PHY;
585 	gphy->insts[GOOGLE_USB2_PHY].parent = gphy;
586 	if (IS_ERR(gphy->insts[GOOGLE_USB2_PHY].phy))
587 		return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB2_PHY].phy),
588 				     "failed to create usb2 phy instance\n");
589 	phy_set_drvdata(gphy->insts[GOOGLE_USB2_PHY].phy, &gphy->insts[GOOGLE_USB2_PHY]);
590 
591 	gphy->insts[GOOGLE_USB3_PHY].phy = devm_phy_create(dev, NULL, &google_usb3_phy_ops);
592 	gphy->insts[GOOGLE_USB3_PHY].index = GOOGLE_USB3_PHY;
593 	gphy->insts[GOOGLE_USB3_PHY].parent = gphy;
594 	if (IS_ERR(gphy->insts[GOOGLE_USB3_PHY].phy))
595 		return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB3_PHY].phy),
596 				     "failed to create usb3 phy instance\n");
597 	phy_set_drvdata(gphy->insts[GOOGLE_USB3_PHY].phy, &gphy->insts[GOOGLE_USB3_PHY]);
598 
599 	ret = google_usb_phy_parse_clocks(gphy);
600 	if (ret)
601 		return ret;
602 
603 	ret = google_usb_phy_parse_resets(gphy);
604 	if (ret)
605 		return ret;
606 
607 	phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
608 	if (IS_ERR(phy_provider))
609 		return dev_err_probe(dev, PTR_ERR(phy_provider),
610 				     "failed to register phy provider\n");
611 
612 	ret = devm_pm_runtime_enable(dev);
613 	if (ret)
614 		return ret;
615 
616 	sw_desc.fwnode = dev_fwnode(dev);
617 	sw_desc.drvdata = gphy;
618 	sw_desc.name = fwnode_get_name(dev_fwnode(dev));
619 	sw_desc.set = google_usb_set_orientation;
620 
621 	gphy->sw = typec_switch_register(dev, &sw_desc);
622 	if (IS_ERR(gphy->sw))
623 		return dev_err_probe(dev, PTR_ERR(gphy->sw),
624 				     "failed to register typec switch\n");
625 
626 	return 0;
627 }
628 
629 static void google_usb_phy_remove(struct platform_device *pdev)
630 {
631 	struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
632 
633 	typec_switch_unregister(gphy->sw);
634 }
635 
636 static const struct of_device_id google_usb_phy_of_match[] = {
637 	{
638 		.compatible = "google,lga-usb-phy",
639 	},
640 	{ }
641 };
642 MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
643 
644 static struct platform_driver google_usb_phy = {
645 	.probe	= google_usb_phy_probe,
646 	.remove = google_usb_phy_remove,
647 	.driver = {
648 		.name		= "google-usb-phy",
649 		.of_match_table	= google_usb_phy_of_match,
650 	}
651 };
652 
653 module_platform_driver(google_usb_phy);
654 MODULE_LICENSE("GPL");
655 MODULE_DESCRIPTION("Google USB phy driver");
656