1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Meson8, Meson8b and GXBB USB2 PHY driver
4  *
5  * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
6  * Copyright (C) 2018 BayLibre, SAS
7  *
8  * Author: Beniamino Galvani <b.galvani@gmail.com>
9  */
10 
11 #include <common.h>
12 #include <clk.h>
13 #include <dm.h>
14 #include <generic-phy.h>
15 #include <power/regulator.h>
16 #include <regmap.h>
17 #include <reset.h>
18 #include <linux/bitops.h>
19 
20 #define REG_CONFIG					0x00
21 	#define REG_CONFIG_CLK_EN			BIT(0)
22 	#define REG_CONFIG_CLK_SEL_MASK			GENMASK(3, 1)
23 	#define REG_CONFIG_CLK_DIV_MASK			GENMASK(10, 4)
24 	#define REG_CONFIG_CLK_32k_ALTSEL		BIT(15)
25 	#define REG_CONFIG_TEST_TRIG			BIT(31)
26 
27 #define REG_CTRL					0x04
28 	#define REG_CTRL_SOFT_PRST			BIT(0)
29 	#define REG_CTRL_SOFT_HRESET			BIT(1)
30 	#define REG_CTRL_SS_SCALEDOWN_MODE_MASK		GENMASK(3, 2)
31 	#define REG_CTRL_CLK_DET_RST			BIT(4)
32 	#define REG_CTRL_INTR_SEL			BIT(5)
33 	#define REG_CTRL_CLK_DETECTED			BIT(8)
34 	#define REG_CTRL_SOF_SENT_RCVD_TGL		BIT(9)
35 	#define REG_CTRL_SOF_TOGGLE_OUT			BIT(10)
36 	#define REG_CTRL_POWER_ON_RESET			BIT(15)
37 	#define REG_CTRL_SLEEPM				BIT(16)
38 	#define REG_CTRL_TX_BITSTUFF_ENN_H		BIT(17)
39 	#define REG_CTRL_TX_BITSTUFF_ENN		BIT(18)
40 	#define REG_CTRL_COMMON_ON			BIT(19)
41 	#define REG_CTRL_REF_CLK_SEL_MASK		GENMASK(21, 20)
42 	#define REG_CTRL_REF_CLK_SEL_SHIFT		20
43 	#define REG_CTRL_FSEL_MASK			GENMASK(24, 22)
44 	#define REG_CTRL_FSEL_SHIFT			22
45 	#define REG_CTRL_PORT_RESET			BIT(25)
46 	#define REG_CTRL_THREAD_ID_MASK			GENMASK(31, 26)
47 
48 /* bits [31:26], [24:21] and [15:3] seem to be read-only */
49 #define REG_ADP_BC					0x0c
50 	#define REG_ADP_BC_VBUS_VLD_EXT_SEL		BIT(0)
51 	#define REG_ADP_BC_VBUS_VLD_EXT			BIT(1)
52 	#define REG_ADP_BC_OTG_DISABLE			BIT(2)
53 	#define REG_ADP_BC_ID_PULLUP			BIT(3)
54 	#define REG_ADP_BC_DRV_VBUS			BIT(4)
55 	#define REG_ADP_BC_ADP_PRB_EN			BIT(5)
56 	#define REG_ADP_BC_ADP_DISCHARGE		BIT(6)
57 	#define REG_ADP_BC_ADP_CHARGE			BIT(7)
58 	#define REG_ADP_BC_SESS_END			BIT(8)
59 	#define REG_ADP_BC_DEVICE_SESS_VLD		BIT(9)
60 	#define REG_ADP_BC_B_VALID			BIT(10)
61 	#define REG_ADP_BC_A_VALID			BIT(11)
62 	#define REG_ADP_BC_ID_DIG			BIT(12)
63 	#define REG_ADP_BC_VBUS_VALID			BIT(13)
64 	#define REG_ADP_BC_ADP_PROBE			BIT(14)
65 	#define REG_ADP_BC_ADP_SENSE			BIT(15)
66 	#define REG_ADP_BC_ACA_ENABLE			BIT(16)
67 	#define REG_ADP_BC_DCD_ENABLE			BIT(17)
68 	#define REG_ADP_BC_VDAT_DET_EN_B		BIT(18)
69 	#define REG_ADP_BC_VDAT_SRC_EN_B		BIT(19)
70 	#define REG_ADP_BC_CHARGE_SEL			BIT(20)
71 	#define REG_ADP_BC_CHARGE_DETECT		BIT(21)
72 	#define REG_ADP_BC_ACA_PIN_RANGE_C		BIT(22)
73 	#define REG_ADP_BC_ACA_PIN_RANGE_B		BIT(23)
74 	#define REG_ADP_BC_ACA_PIN_RANGE_A		BIT(24)
75 	#define REG_ADP_BC_ACA_PIN_GND			BIT(25)
76 	#define REG_ADP_BC_ACA_PIN_FLOAT		BIT(26)
77 
78 #define RESET_COMPLETE_TIME				500
79 #define ACA_ENABLE_COMPLETE_TIME			50
80 
81 struct phy_meson_gxbb_usb2_priv {
82 	struct regmap *regmap;
83 	struct reset_ctl_bulk resets;
84 #if CONFIG_IS_ENABLED(DM_REGULATOR)
85 	struct udevice *phy_supply;
86 #endif
87 };
88 
phy_meson_gxbb_usb2_power_on(struct phy * phy)89 static int phy_meson_gxbb_usb2_power_on(struct phy *phy)
90 {
91 	struct udevice *dev = phy->dev;
92 	struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev);
93 	uint val;
94 
95 #if CONFIG_IS_ENABLED(DM_REGULATOR)
96 	if (priv->phy_supply) {
97 		int ret = regulator_set_enable(priv->phy_supply, true);
98 
99 		if (ret)
100 			return ret;
101 	}
102 #endif
103 
104 	regmap_update_bits(priv->regmap, REG_CONFIG,
105 			   REG_CONFIG_CLK_32k_ALTSEL,
106 			   REG_CONFIG_CLK_32k_ALTSEL);
107 	regmap_update_bits(priv->regmap, REG_CTRL,
108 			   REG_CTRL_REF_CLK_SEL_MASK,
109 			   0x2 << REG_CTRL_REF_CLK_SEL_SHIFT);
110 	regmap_update_bits(priv->regmap, REG_CTRL,
111 			   REG_CTRL_FSEL_MASK,
112 			   0x5 << REG_CTRL_FSEL_SHIFT);
113 
114 	/* reset the PHY */
115 	regmap_update_bits(priv->regmap, REG_CTRL,
116 			   REG_CTRL_POWER_ON_RESET,
117 			   REG_CTRL_POWER_ON_RESET);
118 	udelay(RESET_COMPLETE_TIME);
119 	regmap_update_bits(priv->regmap, REG_CTRL,
120 			   REG_CTRL_POWER_ON_RESET,
121 			   0);
122 	udelay(RESET_COMPLETE_TIME);
123 
124 	regmap_update_bits(priv->regmap, REG_CTRL,
125 			   REG_CTRL_SOF_TOGGLE_OUT,
126 			   REG_CTRL_SOF_TOGGLE_OUT);
127 
128 	/* Set host mode */
129 	regmap_update_bits(priv->regmap, REG_ADP_BC,
130 			   REG_ADP_BC_ACA_ENABLE,
131 			   REG_ADP_BC_ACA_ENABLE);
132 	udelay(ACA_ENABLE_COMPLETE_TIME);
133 
134 	regmap_read(priv->regmap, REG_ADP_BC, &val);
135 	if (val & REG_ADP_BC_ACA_PIN_FLOAT) {
136 		pr_err("Error powering on GXBB USB PHY\n");
137 		return -EINVAL;
138 	}
139 
140 	return 0;
141 }
142 
phy_meson_gxbb_usb2_power_off(struct phy * phy)143 static int phy_meson_gxbb_usb2_power_off(struct phy *phy)
144 {
145 #if CONFIG_IS_ENABLED(DM_REGULATOR)
146 	struct udevice *dev = phy->dev;
147 	struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev);
148 
149 	if (priv->phy_supply) {
150 		int ret = regulator_set_enable(priv->phy_supply, false);
151 
152 		if (ret)
153 			return ret;
154 	}
155 #endif
156 
157 	return 0;
158 }
159 
160 static struct phy_ops meson_gxbb_usb2_phy_ops = {
161 	.power_on = phy_meson_gxbb_usb2_power_on,
162 	.power_off = phy_meson_gxbb_usb2_power_off,
163 };
164 
meson_gxbb_usb2_phy_probe(struct udevice * dev)165 static int meson_gxbb_usb2_phy_probe(struct udevice *dev)
166 {
167 	struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev);
168 	struct clk clk_usb_general, clk_usb;
169 	int ret;
170 
171 	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
172 	if (ret)
173 		return ret;
174 
175 	ret = clk_get_by_name(dev, "usb_general", &clk_usb_general);
176 	if (ret)
177 		return ret;
178 
179 	ret = clk_enable(&clk_usb_general);
180 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
181 		pr_err("Failed to enable PHY general clock\n");
182 		return ret;
183 	}
184 
185 	ret = clk_get_by_name(dev, "usb", &clk_usb);
186 	if (ret)
187 		return ret;
188 
189 	ret = clk_enable(&clk_usb);
190 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
191 		pr_err("Failed to enable PHY clock\n");
192 		return ret;
193 	}
194 
195 #if CONFIG_IS_ENABLED(DM_REGULATOR)
196 	ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply);
197 	if (ret && ret != -ENOENT) {
198 		pr_err("Failed to get PHY regulator\n");
199 		return ret;
200 	}
201 #endif
202 	ret = reset_get_bulk(dev, &priv->resets);
203 	if (!ret) {
204 		ret = reset_deassert_bulk(&priv->resets);
205 		if (ret) {
206 			pr_err("Failed to deassert reset\n");
207 			return ret;
208 		}
209 	}
210 
211 	return 0;
212 }
213 
meson_gxbb_usb2_phy_remove(struct udevice * dev)214 static int meson_gxbb_usb2_phy_remove(struct udevice *dev)
215 {
216 	struct phy_meson_gxbb_usb2_priv *priv = dev_get_priv(dev);
217 
218 	return reset_release_bulk(&priv->resets);
219 }
220 
221 static const struct udevice_id meson_gxbb_usb2_phy_ids[] = {
222 	{ .compatible = "amlogic,meson8-usb2-phy" },
223 	{ .compatible = "amlogic,meson8b-usb2-phy" },
224 	{ .compatible = "amlogic,meson-gxbb-usb2-phy" },
225 	{ }
226 };
227 
228 U_BOOT_DRIVER(meson_gxbb_usb2_phy) = {
229 	.name = "meson_gxbb_usb2_phy",
230 	.id = UCLASS_PHY,
231 	.of_match = meson_gxbb_usb2_phy_ids,
232 	.probe = meson_gxbb_usb2_phy_probe,
233 	.remove = meson_gxbb_usb2_phy_remove,
234 	.ops = &meson_gxbb_usb2_phy_ops,
235 	.priv_auto	= sizeof(struct phy_meson_gxbb_usb2_priv),
236 };
237