1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek USB3.1 gen2 xsphy Driver
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
10 #include <dt-bindings/phy/phy.h>
11 #include <linux/clk.h>
12 #include <linux/delay.h>
14 #include <linux/iopoll.h>
15 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
21 #define SSUSB_SIFSLV_MISC 0x000
22 #define SSUSB_SIFSLV_U2FREQ 0x100
23 #define SSUSB_SIFSLV_U2PHY_COM 0x300
25 /* u3 phy shared banks */
26 #define SSPXTP_SIFSLV_DIG_GLB 0x000
27 #define SSPXTP_SIFSLV_PHYA_GLB 0x100
30 #define SSPXTP_SIFSLV_DIG_LN_TOP 0x000
31 #define SSPXTP_SIFSLV_DIG_LN_TX0 0x100
32 #define SSPXTP_SIFSLV_DIG_LN_RX0 0x200
33 #define SSPXTP_SIFSLV_DIG_LN_DAIF 0x300
34 #define SSPXTP_SIFSLV_PHYA_LN 0x400
36 #define XSP_U2FREQ_FMCR0 ((SSUSB_SIFSLV_U2FREQ) + 0x00)
37 #define P2F_RG_FREQDET_EN BIT(24)
38 #define P2F_RG_CYCLECNT GENMASK(23, 0)
39 #define P2F_RG_CYCLECNT_VAL(x) ((P2F_RG_CYCLECNT) & (x))
41 #define XSP_U2FREQ_MMONR0 ((SSUSB_SIFSLV_U2FREQ) + 0x0c)
43 #define XSP_U2FREQ_FMMONR1 ((SSUSB_SIFSLV_U2FREQ) + 0x10)
44 #define P2F_RG_FRCK_EN BIT(8)
45 #define P2F_USB_FM_VALID BIT(0)
47 #define XSP_USBPHYACR0 ((SSUSB_SIFSLV_U2PHY_COM) + 0x00)
48 #define P2A0_RG_INTR_EN BIT(5)
50 #define XSP_USBPHYACR1 ((SSUSB_SIFSLV_U2PHY_COM) + 0x04)
51 #define P2A1_RG_INTR_CAL GENMASK(23, 19)
52 #define P2A1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19)
53 #define P2A1_RG_VRT_SEL GENMASK(14, 12)
54 #define P2A1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
55 #define P2A1_RG_TERM_SEL GENMASK(10, 8)
56 #define P2A1_RG_TERM_SEL_VAL(x) ((0x7 & (x)) << 8)
58 #define XSP_USBPHYACR5 ((SSUSB_SIFSLV_U2PHY_COM) + 0x014)
59 #define P2A5_RG_HSTX_SRCAL_EN BIT(15)
60 #define P2A5_RG_HSTX_SRCTRL GENMASK(14, 12)
61 #define P2A5_RG_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
63 #define XSP_USBPHYACR6 ((SSUSB_SIFSLV_U2PHY_COM) + 0x018)
64 #define P2A6_RG_BC11_SW_EN BIT(23)
65 #define P2A6_RG_OTG_VBUSCMP_EN BIT(20)
67 #define XSP_U2PHYDTM1 ((SSUSB_SIFSLV_U2PHY_COM) + 0x06C)
68 #define P2D_FORCE_IDDIG BIT(9)
69 #define P2D_RG_VBUSVALID BIT(5)
70 #define P2D_RG_SESSEND BIT(4)
71 #define P2D_RG_AVALID BIT(2)
72 #define P2D_RG_IDDIG BIT(1)
74 #define SSPXTP_PHYA_GLB_00 ((SSPXTP_SIFSLV_PHYA_GLB) + 0x00)
75 #define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(21, 16)
76 #define RG_XTP_GLB_BIAS_INTR_CTRL_VAL(x) ((0x3f & (x)) << 16)
78 #define SSPXTP_PHYA_LN_04 ((SSPXTP_SIFSLV_PHYA_LN) + 0x04)
79 #define RG_XTP_LN0_TX_IMPSEL GENMASK(4, 0)
80 #define RG_XTP_LN0_TX_IMPSEL_VAL(x) (0x1f & (x))
82 #define SSPXTP_PHYA_LN_14 ((SSPXTP_SIFSLV_PHYA_LN) + 0x014)
83 #define RG_XTP_LN0_RX_IMPSEL GENMASK(4, 0)
84 #define RG_XTP_LN0_RX_IMPSEL_VAL(x) (0x1f & (x))
86 #define XSP_REF_CLK 26 /* MHZ */
87 #define XSP_SLEW_RATE_COEF 17
88 #define XSP_SR_COEF_DIVISOR 1000
89 #define XSP_FM_DET_CYCLE_CNT 1024
91 struct xsphy_instance
{
93 void __iomem
*port_base
;
94 struct clk
*ref_clk
; /* reference clock of anolog phy */
97 /* only for HQA test */
109 void __iomem
*glb_base
; /* only shared u3 sif */
110 struct xsphy_instance
**phys
;
112 int src_ref_clk
; /* MHZ, reference clock for slew rate calibrate */
113 int src_coef
; /* coefficient for slew rate calibrate */
116 static void u2_phy_slew_rate_calibrate(struct mtk_xsphy
*xsphy
,
117 struct xsphy_instance
*inst
)
119 void __iomem
*pbase
= inst
->port_base
;
124 /* use force value */
128 /* enable USB ring oscillator */
129 tmp
= readl(pbase
+ XSP_USBPHYACR5
);
130 tmp
|= P2A5_RG_HSTX_SRCAL_EN
;
131 writel(tmp
, pbase
+ XSP_USBPHYACR5
);
132 udelay(1); /* wait clock stable */
134 /* enable free run clock */
135 tmp
= readl(pbase
+ XSP_U2FREQ_FMMONR1
);
136 tmp
|= P2F_RG_FRCK_EN
;
137 writel(tmp
, pbase
+ XSP_U2FREQ_FMMONR1
);
139 /* set cycle count as 1024 */
140 tmp
= readl(pbase
+ XSP_U2FREQ_FMCR0
);
141 tmp
&= ~(P2F_RG_CYCLECNT
);
142 tmp
|= P2F_RG_CYCLECNT_VAL(XSP_FM_DET_CYCLE_CNT
);
143 writel(tmp
, pbase
+ XSP_U2FREQ_FMCR0
);
145 /* enable frequency meter */
146 tmp
= readl(pbase
+ XSP_U2FREQ_FMCR0
);
147 tmp
|= P2F_RG_FREQDET_EN
;
148 writel(tmp
, pbase
+ XSP_U2FREQ_FMCR0
);
150 /* ignore return value */
151 readl_poll_timeout(pbase
+ XSP_U2FREQ_FMMONR1
, tmp
,
152 (tmp
& P2F_USB_FM_VALID
), 10, 200);
154 fm_out
= readl(pbase
+ XSP_U2FREQ_MMONR0
);
156 /* disable frequency meter */
157 tmp
= readl(pbase
+ XSP_U2FREQ_FMCR0
);
158 tmp
&= ~P2F_RG_FREQDET_EN
;
159 writel(tmp
, pbase
+ XSP_U2FREQ_FMCR0
);
161 /* disable free run clock */
162 tmp
= readl(pbase
+ XSP_U2FREQ_FMMONR1
);
163 tmp
&= ~P2F_RG_FRCK_EN
;
164 writel(tmp
, pbase
+ XSP_U2FREQ_FMMONR1
);
167 /* (1024 / FM_OUT) x reference clock frequency x coefficient */
168 tmp
= xsphy
->src_ref_clk
* xsphy
->src_coef
;
169 tmp
= (tmp
* XSP_FM_DET_CYCLE_CNT
) / fm_out
;
170 calib_val
= DIV_ROUND_CLOSEST(tmp
, XSP_SR_COEF_DIVISOR
);
172 /* if FM detection fail, set default value */
175 dev_dbg(xsphy
->dev
, "phy.%d, fm_out:%d, calib:%d (clk:%d, coef:%d)\n",
176 inst
->index
, fm_out
, calib_val
,
177 xsphy
->src_ref_clk
, xsphy
->src_coef
);
179 /* set HS slew rate */
180 tmp
= readl(pbase
+ XSP_USBPHYACR5
);
181 tmp
&= ~P2A5_RG_HSTX_SRCTRL
;
182 tmp
|= P2A5_RG_HSTX_SRCTRL_VAL(calib_val
);
183 writel(tmp
, pbase
+ XSP_USBPHYACR5
);
185 /* disable USB ring oscillator */
186 tmp
= readl(pbase
+ XSP_USBPHYACR5
);
187 tmp
&= ~P2A5_RG_HSTX_SRCAL_EN
;
188 writel(tmp
, pbase
+ XSP_USBPHYACR5
);
191 static void u2_phy_instance_init(struct mtk_xsphy
*xsphy
,
192 struct xsphy_instance
*inst
)
194 void __iomem
*pbase
= inst
->port_base
;
197 /* DP/DM BC1.1 path Disable */
198 tmp
= readl(pbase
+ XSP_USBPHYACR6
);
199 tmp
&= ~P2A6_RG_BC11_SW_EN
;
200 writel(tmp
, pbase
+ XSP_USBPHYACR6
);
202 tmp
= readl(pbase
+ XSP_USBPHYACR0
);
203 tmp
|= P2A0_RG_INTR_EN
;
204 writel(tmp
, pbase
+ XSP_USBPHYACR0
);
207 static void u2_phy_instance_power_on(struct mtk_xsphy
*xsphy
,
208 struct xsphy_instance
*inst
)
210 void __iomem
*pbase
= inst
->port_base
;
211 u32 index
= inst
->index
;
214 tmp
= readl(pbase
+ XSP_USBPHYACR6
);
215 tmp
|= P2A6_RG_OTG_VBUSCMP_EN
;
216 writel(tmp
, pbase
+ XSP_USBPHYACR6
);
218 tmp
= readl(pbase
+ XSP_U2PHYDTM1
);
219 tmp
|= P2D_RG_VBUSVALID
| P2D_RG_AVALID
;
220 tmp
&= ~P2D_RG_SESSEND
;
221 writel(tmp
, pbase
+ XSP_U2PHYDTM1
);
223 dev_dbg(xsphy
->dev
, "%s(%d)\n", __func__
, index
);
226 static void u2_phy_instance_power_off(struct mtk_xsphy
*xsphy
,
227 struct xsphy_instance
*inst
)
229 void __iomem
*pbase
= inst
->port_base
;
230 u32 index
= inst
->index
;
233 tmp
= readl(pbase
+ XSP_USBPHYACR6
);
234 tmp
&= ~P2A6_RG_OTG_VBUSCMP_EN
;
235 writel(tmp
, pbase
+ XSP_USBPHYACR6
);
237 tmp
= readl(pbase
+ XSP_U2PHYDTM1
);
238 tmp
&= ~(P2D_RG_VBUSVALID
| P2D_RG_AVALID
);
239 tmp
|= P2D_RG_SESSEND
;
240 writel(tmp
, pbase
+ XSP_U2PHYDTM1
);
242 dev_dbg(xsphy
->dev
, "%s(%d)\n", __func__
, index
);
245 static void u2_phy_instance_set_mode(struct mtk_xsphy
*xsphy
,
246 struct xsphy_instance
*inst
,
251 tmp
= readl(inst
->port_base
+ XSP_U2PHYDTM1
);
253 case PHY_MODE_USB_DEVICE
:
254 tmp
|= P2D_FORCE_IDDIG
| P2D_RG_IDDIG
;
256 case PHY_MODE_USB_HOST
:
257 tmp
|= P2D_FORCE_IDDIG
;
258 tmp
&= ~P2D_RG_IDDIG
;
260 case PHY_MODE_USB_OTG
:
261 tmp
&= ~(P2D_FORCE_IDDIG
| P2D_RG_IDDIG
);
266 writel(tmp
, inst
->port_base
+ XSP_U2PHYDTM1
);
269 static void phy_parse_property(struct mtk_xsphy
*xsphy
,
270 struct xsphy_instance
*inst
)
272 struct device
*dev
= &inst
->phy
->dev
;
274 switch (inst
->type
) {
276 device_property_read_u32(dev
, "mediatek,efuse-intr",
278 device_property_read_u32(dev
, "mediatek,eye-src",
280 device_property_read_u32(dev
, "mediatek,eye-vrt",
282 device_property_read_u32(dev
, "mediatek,eye-term",
284 dev_dbg(dev
, "intr:%d, src:%d, vrt:%d, term:%d\n",
285 inst
->efuse_intr
, inst
->eye_src
,
286 inst
->eye_vrt
, inst
->eye_term
);
289 device_property_read_u32(dev
, "mediatek,efuse-intr",
291 device_property_read_u32(dev
, "mediatek,efuse-tx-imp",
292 &inst
->efuse_tx_imp
);
293 device_property_read_u32(dev
, "mediatek,efuse-rx-imp",
294 &inst
->efuse_rx_imp
);
295 dev_dbg(dev
, "intr:%d, tx-imp:%d, rx-imp:%d\n",
296 inst
->efuse_intr
, inst
->efuse_tx_imp
,
300 dev_err(xsphy
->dev
, "incompatible phy type\n");
305 static void u2_phy_props_set(struct mtk_xsphy
*xsphy
,
306 struct xsphy_instance
*inst
)
308 void __iomem
*pbase
= inst
->port_base
;
311 if (inst
->efuse_intr
) {
312 tmp
= readl(pbase
+ XSP_USBPHYACR1
);
313 tmp
&= ~P2A1_RG_INTR_CAL
;
314 tmp
|= P2A1_RG_INTR_CAL_VAL(inst
->efuse_intr
);
315 writel(tmp
, pbase
+ XSP_USBPHYACR1
);
319 tmp
= readl(pbase
+ XSP_USBPHYACR5
);
320 tmp
&= ~P2A5_RG_HSTX_SRCTRL
;
321 tmp
|= P2A5_RG_HSTX_SRCTRL_VAL(inst
->eye_src
);
322 writel(tmp
, pbase
+ XSP_USBPHYACR5
);
326 tmp
= readl(pbase
+ XSP_USBPHYACR1
);
327 tmp
&= ~P2A1_RG_VRT_SEL
;
328 tmp
|= P2A1_RG_VRT_SEL_VAL(inst
->eye_vrt
);
329 writel(tmp
, pbase
+ XSP_USBPHYACR1
);
332 if (inst
->eye_term
) {
333 tmp
= readl(pbase
+ XSP_USBPHYACR1
);
334 tmp
&= ~P2A1_RG_TERM_SEL
;
335 tmp
|= P2A1_RG_TERM_SEL_VAL(inst
->eye_term
);
336 writel(tmp
, pbase
+ XSP_USBPHYACR1
);
340 static void u3_phy_props_set(struct mtk_xsphy
*xsphy
,
341 struct xsphy_instance
*inst
)
343 void __iomem
*pbase
= inst
->port_base
;
346 if (inst
->efuse_intr
) {
347 tmp
= readl(xsphy
->glb_base
+ SSPXTP_PHYA_GLB_00
);
348 tmp
&= ~RG_XTP_GLB_BIAS_INTR_CTRL
;
349 tmp
|= RG_XTP_GLB_BIAS_INTR_CTRL_VAL(inst
->efuse_intr
);
350 writel(tmp
, xsphy
->glb_base
+ SSPXTP_PHYA_GLB_00
);
353 if (inst
->efuse_tx_imp
) {
354 tmp
= readl(pbase
+ SSPXTP_PHYA_LN_04
);
355 tmp
&= ~RG_XTP_LN0_TX_IMPSEL
;
356 tmp
|= RG_XTP_LN0_TX_IMPSEL_VAL(inst
->efuse_tx_imp
);
357 writel(tmp
, pbase
+ SSPXTP_PHYA_LN_04
);
360 if (inst
->efuse_rx_imp
) {
361 tmp
= readl(pbase
+ SSPXTP_PHYA_LN_14
);
362 tmp
&= ~RG_XTP_LN0_RX_IMPSEL
;
363 tmp
|= RG_XTP_LN0_RX_IMPSEL_VAL(inst
->efuse_rx_imp
);
364 writel(tmp
, pbase
+ SSPXTP_PHYA_LN_14
);
368 static int mtk_phy_init(struct phy
*phy
)
370 struct xsphy_instance
*inst
= phy_get_drvdata(phy
);
371 struct mtk_xsphy
*xsphy
= dev_get_drvdata(phy
->dev
.parent
);
374 ret
= clk_prepare_enable(inst
->ref_clk
);
376 dev_err(xsphy
->dev
, "failed to enable ref_clk\n");
380 switch (inst
->type
) {
382 u2_phy_instance_init(xsphy
, inst
);
383 u2_phy_props_set(xsphy
, inst
);
386 u3_phy_props_set(xsphy
, inst
);
389 dev_err(xsphy
->dev
, "incompatible phy type\n");
390 clk_disable_unprepare(inst
->ref_clk
);
397 static int mtk_phy_power_on(struct phy
*phy
)
399 struct xsphy_instance
*inst
= phy_get_drvdata(phy
);
400 struct mtk_xsphy
*xsphy
= dev_get_drvdata(phy
->dev
.parent
);
402 if (inst
->type
== PHY_TYPE_USB2
) {
403 u2_phy_instance_power_on(xsphy
, inst
);
404 u2_phy_slew_rate_calibrate(xsphy
, inst
);
410 static int mtk_phy_power_off(struct phy
*phy
)
412 struct xsphy_instance
*inst
= phy_get_drvdata(phy
);
413 struct mtk_xsphy
*xsphy
= dev_get_drvdata(phy
->dev
.parent
);
415 if (inst
->type
== PHY_TYPE_USB2
)
416 u2_phy_instance_power_off(xsphy
, inst
);
421 static int mtk_phy_exit(struct phy
*phy
)
423 struct xsphy_instance
*inst
= phy_get_drvdata(phy
);
425 clk_disable_unprepare(inst
->ref_clk
);
429 static int mtk_phy_set_mode(struct phy
*phy
, enum phy_mode mode
, int submode
)
431 struct xsphy_instance
*inst
= phy_get_drvdata(phy
);
432 struct mtk_xsphy
*xsphy
= dev_get_drvdata(phy
->dev
.parent
);
434 if (inst
->type
== PHY_TYPE_USB2
)
435 u2_phy_instance_set_mode(xsphy
, inst
, mode
);
440 static struct phy
*mtk_phy_xlate(struct device
*dev
,
441 struct of_phandle_args
*args
)
443 struct mtk_xsphy
*xsphy
= dev_get_drvdata(dev
);
444 struct xsphy_instance
*inst
= NULL
;
445 struct device_node
*phy_np
= args
->np
;
448 if (args
->args_count
!= 1) {
449 dev_err(dev
, "invalid number of cells in 'phy' property\n");
450 return ERR_PTR(-EINVAL
);
453 for (index
= 0; index
< xsphy
->nphys
; index
++)
454 if (phy_np
== xsphy
->phys
[index
]->phy
->dev
.of_node
) {
455 inst
= xsphy
->phys
[index
];
460 dev_err(dev
, "failed to find appropriate phy\n");
461 return ERR_PTR(-EINVAL
);
464 inst
->type
= args
->args
[0];
465 if (!(inst
->type
== PHY_TYPE_USB2
||
466 inst
->type
== PHY_TYPE_USB3
)) {
467 dev_err(dev
, "unsupported phy type: %d\n", inst
->type
);
468 return ERR_PTR(-EINVAL
);
471 phy_parse_property(xsphy
, inst
);
476 static const struct phy_ops mtk_xsphy_ops
= {
477 .init
= mtk_phy_init
,
478 .exit
= mtk_phy_exit
,
479 .power_on
= mtk_phy_power_on
,
480 .power_off
= mtk_phy_power_off
,
481 .set_mode
= mtk_phy_set_mode
,
482 .owner
= THIS_MODULE
,
485 static const struct of_device_id mtk_xsphy_id_table
[] = {
486 { .compatible
= "mediatek,xsphy", },
489 MODULE_DEVICE_TABLE(of
, mtk_xsphy_id_table
);
491 static int mtk_xsphy_probe(struct platform_device
*pdev
)
493 struct device
*dev
= &pdev
->dev
;
494 struct device_node
*np
= dev
->of_node
;
495 struct device_node
*child_np
;
496 struct phy_provider
*provider
;
497 struct resource
*glb_res
;
498 struct mtk_xsphy
*xsphy
;
502 xsphy
= devm_kzalloc(dev
, sizeof(*xsphy
), GFP_KERNEL
);
506 xsphy
->nphys
= of_get_child_count(np
);
507 xsphy
->phys
= devm_kcalloc(dev
, xsphy
->nphys
,
508 sizeof(*xsphy
->phys
), GFP_KERNEL
);
513 platform_set_drvdata(pdev
, xsphy
);
515 glb_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
516 /* optional, may not exist if no u3 phys */
518 /* get banks shared by multiple u3 phys */
519 xsphy
->glb_base
= devm_ioremap_resource(dev
, glb_res
);
520 if (IS_ERR(xsphy
->glb_base
)) {
521 dev_err(dev
, "failed to remap glb regs\n");
522 return PTR_ERR(xsphy
->glb_base
);
526 xsphy
->src_ref_clk
= XSP_REF_CLK
;
527 xsphy
->src_coef
= XSP_SLEW_RATE_COEF
;
528 /* update parameters of slew rate calibrate if exist */
529 device_property_read_u32(dev
, "mediatek,src-ref-clk-mhz",
530 &xsphy
->src_ref_clk
);
531 device_property_read_u32(dev
, "mediatek,src-coef", &xsphy
->src_coef
);
534 for_each_child_of_node(np
, child_np
) {
535 struct xsphy_instance
*inst
;
538 inst
= devm_kzalloc(dev
, sizeof(*inst
), GFP_KERNEL
);
544 xsphy
->phys
[port
] = inst
;
546 phy
= devm_phy_create(dev
, child_np
, &mtk_xsphy_ops
);
548 dev_err(dev
, "failed to create phy\n");
549 retval
= PTR_ERR(phy
);
553 retval
= of_address_to_resource(child_np
, 0, &res
);
555 dev_err(dev
, "failed to get address resource(id-%d)\n",
560 inst
->port_base
= devm_ioremap_resource(&phy
->dev
, &res
);
561 if (IS_ERR(inst
->port_base
)) {
562 dev_err(dev
, "failed to remap phy regs\n");
563 retval
= PTR_ERR(inst
->port_base
);
569 phy_set_drvdata(phy
, inst
);
572 inst
->ref_clk
= devm_clk_get(&phy
->dev
, "ref");
573 if (IS_ERR(inst
->ref_clk
)) {
574 dev_err(dev
, "failed to get ref_clk(id-%d)\n", port
);
575 retval
= PTR_ERR(inst
->ref_clk
);
580 provider
= devm_of_phy_provider_register(dev
, mtk_phy_xlate
);
581 return PTR_ERR_OR_ZERO(provider
);
584 of_node_put(child_np
);
588 static struct platform_driver mtk_xsphy_driver
= {
589 .probe
= mtk_xsphy_probe
,
592 .of_match_table
= mtk_xsphy_id_table
,
596 module_platform_driver(mtk_xsphy_driver
);
598 MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
599 MODULE_DESCRIPTION("MediaTek USB XS-PHY driver");
600 MODULE_LICENSE("GPL v2");