1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2014-2023, The Linux Foundation. All rights reserved.
7 #include <linux/delay.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/phy/phy.h>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
16 #include <linux/slab.h>
18 #define USB2PHY_PORT_UTMI_CTRL1 0x40
20 #define USB2PHY_PORT_UTMI_CTRL2 0x44
21 #define UTMI_ULPI_SEL BIT(7)
22 #define UTMI_TEST_MUX_SEL BIT(6)
24 #define HS_PHY_CTRL_REG 0x10
25 #define UTMI_OTG_VBUS_VALID BIT(20)
26 #define SW_SESSVLD_SEL BIT(28)
28 #define USB_PHY_UTMI_CTRL0 0x3c
30 #define USB_PHY_UTMI_CTRL5 0x50
33 #define USB_PHY_HS_PHY_CTRL_COMMON0 0x54
34 #define COMMONONN BIT(7)
36 #define RETENABLEN BIT(3)
37 #define FREQ_24MHZ (BIT(6) | BIT(4))
39 #define USB_PHY_HS_PHY_CTRL2 0x64
40 #define USB2_SUSPEND_N_SEL BIT(3)
41 #define USB2_SUSPEND_N BIT(2)
42 #define USB2_UTMI_CLK_EN BIT(1)
44 #define USB_PHY_CFG0 0x94
45 #define UTMI_PHY_OVERRIDE_EN BIT(1)
47 #define USB_PHY_REFCLK_CTRL 0xa0
48 #define CLKCORE BIT(1)
50 #define USB2PHY_PORT_POWERDOWN 0xa4
51 #define POWER_UP BIT(0)
54 #define USB_PHY_FSEL_SEL 0xb8
55 #define FREQ_SEL BIT(0)
57 #define USB2PHY_USB_PHY_M31_XCFGI_1 0xbc
58 #define USB2_0_TX_ENABLE BIT(2)
60 #define USB2PHY_USB_PHY_M31_XCFGI_4 0xc8
61 #define HSTX_SLEW_RATE_565PS GENMASK(1, 0)
62 #define PLL_CHARGING_PUMP_CURRENT_35UA GENMASK(4, 3)
63 #define ODT_VALUE_38_02_OHM GENMASK(7, 6)
65 #define USB2PHY_USB_PHY_M31_XCFGI_5 0xcc
66 #define ODT_VALUE_45_02_OHM BIT(2)
67 #define HSTX_PRE_EMPHASIS_LEVEL_0_55MA BIT(0)
69 #define USB2PHY_USB_PHY_M31_XCFGI_11 0xe4
70 #define XCFG_COARSE_TUNE_NUM BIT(1)
71 #define XCFG_FINE_TUNE_NUM BIT(3)
79 struct m31_priv_data
{
81 const struct m31_phy_regs
*regs
;
85 static struct m31_phy_regs m31_ipq5332_regs
[] = {
102 USB_PHY_HS_PHY_CTRL_COMMON0
,
103 COMMONONN
| FREQ_24MHZ
| RETENABLEN
,
112 USB_PHY_HS_PHY_CTRL2
,
113 USB2_SUSPEND_N_SEL
| USB2_SUSPEND_N
| USB2_UTMI_CLK_EN
,
117 USB2PHY_USB_PHY_M31_XCFGI_11
,
118 XCFG_COARSE_TUNE_NUM
| XCFG_FINE_TUNE_NUM
,
122 USB2PHY_USB_PHY_M31_XCFGI_4
,
123 HSTX_SLEW_RATE_565PS
| PLL_CHARGING_PUMP_CURRENT_35UA
| ODT_VALUE_38_02_OHM
,
127 USB2PHY_USB_PHY_M31_XCFGI_1
,
132 USB2PHY_USB_PHY_M31_XCFGI_5
,
133 ODT_VALUE_45_02_OHM
| HSTX_PRE_EMPHASIS_LEVEL_0_55MA
,
142 USB_PHY_HS_PHY_CTRL2
,
143 USB2_SUSPEND_N
| USB2_UTMI_CLK_EN
,
151 const struct m31_phy_regs
*regs
;
154 struct regulator
*vreg
;
156 struct reset_control
*reset
;
161 static int m31usb_phy_init(struct phy
*phy
)
163 struct m31usb_phy
*qphy
= phy_get_drvdata(phy
);
164 const struct m31_phy_regs
*regs
= qphy
->regs
;
167 ret
= regulator_enable(qphy
->vreg
);
169 dev_err(&phy
->dev
, "failed to enable regulator, %d\n", ret
);
173 ret
= clk_prepare_enable(qphy
->clk
);
175 regulator_disable(qphy
->vreg
);
176 dev_err(&phy
->dev
, "failed to enable cfg ahb clock, %d\n", ret
);
180 /* Perform phy reset */
181 reset_control_assert(qphy
->reset
);
183 reset_control_deassert(qphy
->reset
);
185 /* configure for ULPI mode if requested */
187 writel(0x0, qphy
->base
+ USB2PHY_PORT_UTMI_CTRL2
);
190 writel(POWER_UP
, qphy
->base
+ USB2PHY_PORT_POWERDOWN
);
192 /* Turn on phy ref clock */
193 for (i
= 0; i
< qphy
->nregs
; i
++) {
194 writel(regs
[i
].val
, qphy
->base
+ regs
[i
].off
);
196 udelay(regs
[i
].delay
);
202 static int m31usb_phy_shutdown(struct phy
*phy
)
204 struct m31usb_phy
*qphy
= phy_get_drvdata(phy
);
206 /* Disable the PHY */
207 writel_relaxed(POWER_DOWN
, qphy
->base
+ USB2PHY_PORT_POWERDOWN
);
209 clk_disable_unprepare(qphy
->clk
);
211 regulator_disable(qphy
->vreg
);
216 static const struct phy_ops m31usb_phy_gen_ops
= {
217 .power_on
= m31usb_phy_init
,
218 .power_off
= m31usb_phy_shutdown
,
219 .owner
= THIS_MODULE
,
222 static int m31usb_phy_probe(struct platform_device
*pdev
)
224 struct phy_provider
*phy_provider
;
225 const struct m31_priv_data
*data
;
226 struct device
*dev
= &pdev
->dev
;
227 struct m31usb_phy
*qphy
;
229 qphy
= devm_kzalloc(dev
, sizeof(*qphy
), GFP_KERNEL
);
233 qphy
->base
= devm_platform_ioremap_resource(pdev
, 0);
234 if (IS_ERR(qphy
->base
))
235 return PTR_ERR(qphy
->base
);
237 qphy
->reset
= devm_reset_control_get_exclusive_by_index(dev
, 0);
238 if (IS_ERR(qphy
->reset
))
239 return PTR_ERR(qphy
->reset
);
241 qphy
->clk
= devm_clk_get(dev
, NULL
);
242 if (IS_ERR(qphy
->clk
))
243 return dev_err_probe(dev
, PTR_ERR(qphy
->clk
),
244 "failed to get clk\n");
246 data
= of_device_get_match_data(dev
);
247 qphy
->regs
= data
->regs
;
248 qphy
->nregs
= data
->nregs
;
249 qphy
->ulpi_mode
= data
->ulpi_mode
;
251 qphy
->phy
= devm_phy_create(dev
, NULL
, &m31usb_phy_gen_ops
);
252 if (IS_ERR(qphy
->phy
))
253 return dev_err_probe(dev
, PTR_ERR(qphy
->phy
),
254 "failed to create phy\n");
256 qphy
->vreg
= devm_regulator_get(dev
, "vdda-phy");
257 if (IS_ERR(qphy
->vreg
))
258 return dev_err_probe(dev
, PTR_ERR(qphy
->vreg
),
259 "failed to get vreg\n");
261 phy_set_drvdata(qphy
->phy
, qphy
);
263 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
264 if (!IS_ERR(phy_provider
))
265 dev_info(dev
, "Registered M31 USB phy\n");
267 return PTR_ERR_OR_ZERO(phy_provider
);
270 static const struct m31_priv_data m31_ipq5332_data
= {
272 .regs
= m31_ipq5332_regs
,
273 .nregs
= ARRAY_SIZE(m31_ipq5332_regs
),
276 static const struct of_device_id m31usb_phy_id_table
[] = {
277 { .compatible
= "qcom,ipq5332-usb-hsphy", .data
= &m31_ipq5332_data
},
280 MODULE_DEVICE_TABLE(of
, m31usb_phy_id_table
);
282 static struct platform_driver m31usb_phy_driver
= {
283 .probe
= m31usb_phy_probe
,
285 .name
= "qcom-m31usb-phy",
286 .of_match_table
= m31usb_phy_id_table
,
290 module_platform_driver(m31usb_phy_driver
);
292 MODULE_DESCRIPTION("USB2 Qualcomm M31 HSPHY driver");
293 MODULE_LICENSE("GPL");