forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/phy/amlogic/phy-meson8b-usb2.c
....@@ -1,14 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Meson8, Meson8b and GXBB USB2 PHY driver
34 *
45 * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
10
- * You should have received a copy of the GNU General Public License
11
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
126 */
137
148 #include <linux/clk.h>
....@@ -16,6 +10,8 @@
1610 #include <linux/io.h>
1711 #include <linux/module.h>
1812 #include <linux/of_device.h>
13
+#include <linux/property.h>
14
+#include <linux/regmap.h>
1915 #include <linux/reset.h>
2016 #include <linux/phy/phy.h>
2117 #include <linux/platform_device.h>
....@@ -82,6 +78,17 @@
8278 #define REG_ADP_BC_ACA_PIN_FLOAT BIT(26)
8379
8480 #define REG_DBG_UART 0x10
81
+ #define REG_DBG_UART_BYPASS_SEL BIT(0)
82
+ #define REG_DBG_UART_BYPASS_DM_EN BIT(1)
83
+ #define REG_DBG_UART_BYPASS_DP_EN BIT(2)
84
+ #define REG_DBG_UART_BYPASS_DM_DATA BIT(3)
85
+ #define REG_DBG_UART_BYPASS_DP_DATA BIT(4)
86
+ #define REG_DBG_UART_FSV_MINUS BIT(5)
87
+ #define REG_DBG_UART_FSV_PLUS BIT(6)
88
+ #define REG_DBG_UART_FSV_BURN_IN_TEST BIT(7)
89
+ #define REG_DBG_UART_LOOPBACK_EN_B BIT(8)
90
+ #define REG_DBG_UART_SET_IDDQ BIT(9)
91
+ #define REG_DBG_UART_ATE_RESET BIT(10)
8592
8693 #define REG_TEST 0x14
8794 #define REG_TEST_DATA_IN_MASK GENMASK(3, 0)
....@@ -110,35 +117,30 @@
110117 #define RESET_COMPLETE_TIME 500
111118 #define ACA_ENABLE_COMPLETE_TIME 50
112119
113
-struct phy_meson8b_usb2_priv {
114
- void __iomem *regs;
115
- enum usb_dr_mode dr_mode;
116
- struct clk *clk_usb_general;
117
- struct clk *clk_usb;
118
- struct reset_control *reset;
120
+struct phy_meson8b_usb2_match_data {
121
+ bool host_enable_aca;
119122 };
120123
121
-static u32 phy_meson8b_usb2_read(struct phy_meson8b_usb2_priv *phy_priv,
122
- u32 reg)
123
-{
124
- return readl(phy_priv->regs + reg);
125
-}
124
+struct phy_meson8b_usb2_priv {
125
+ struct regmap *regmap;
126
+ enum usb_dr_mode dr_mode;
127
+ struct clk *clk_usb_general;
128
+ struct clk *clk_usb;
129
+ struct reset_control *reset;
130
+ const struct phy_meson8b_usb2_match_data *match;
131
+};
126132
127
-static void phy_meson8b_usb2_mask_bits(struct phy_meson8b_usb2_priv *phy_priv,
128
- u32 reg, u32 mask, u32 value)
129
-{
130
- u32 data;
131
-
132
- data = phy_meson8b_usb2_read(phy_priv, reg);
133
- data &= ~mask;
134
- data |= (value & mask);
135
-
136
- writel(data, phy_priv->regs + reg);
137
-}
133
+static const struct regmap_config phy_meson8b_usb2_regmap_conf = {
134
+ .reg_bits = 8,
135
+ .val_bits = 32,
136
+ .reg_stride = 4,
137
+ .max_register = REG_TUNE,
138
+};
138139
139140 static int phy_meson8b_usb2_power_on(struct phy *phy)
140141 {
141142 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy);
143
+ u32 reg;
142144 int ret;
143145
144146 if (!IS_ERR_OR_NULL(priv->reset)) {
....@@ -162,38 +164,43 @@
162164 return ret;
163165 }
164166
165
- phy_meson8b_usb2_mask_bits(priv, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL,
166
- REG_CONFIG_CLK_32k_ALTSEL);
167
+ regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL,
168
+ REG_CONFIG_CLK_32k_ALTSEL);
167169
168
- phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK,
169
- 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT);
170
+ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK,
171
+ 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT);
170172
171
- phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_FSEL_MASK,
172
- 0x5 << REG_CTRL_FSEL_SHIFT);
173
+ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK,
174
+ 0x5 << REG_CTRL_FSEL_SHIFT);
173175
174176 /* reset the PHY */
175
- phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET,
176
- REG_CTRL_POWER_ON_RESET);
177
+ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
178
+ REG_CTRL_POWER_ON_RESET);
177179 udelay(RESET_COMPLETE_TIME);
178
- phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0);
180
+ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0);
179181 udelay(RESET_COMPLETE_TIME);
180182
181
- phy_meson8b_usb2_mask_bits(priv, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT,
182
- REG_CTRL_SOF_TOGGLE_OUT);
183
+ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT,
184
+ REG_CTRL_SOF_TOGGLE_OUT);
183185
184186 if (priv->dr_mode == USB_DR_MODE_HOST) {
185
- phy_meson8b_usb2_mask_bits(priv, REG_ADP_BC,
187
+ regmap_update_bits(priv->regmap, REG_DBG_UART,
188
+ REG_DBG_UART_SET_IDDQ, 0);
189
+
190
+ if (priv->match->host_enable_aca) {
191
+ regmap_update_bits(priv->regmap, REG_ADP_BC,
186192 REG_ADP_BC_ACA_ENABLE,
187193 REG_ADP_BC_ACA_ENABLE);
188194
189
- udelay(ACA_ENABLE_COMPLETE_TIME);
195
+ udelay(ACA_ENABLE_COMPLETE_TIME);
190196
191
- if (phy_meson8b_usb2_read(priv, REG_ADP_BC) &
192
- REG_ADP_BC_ACA_PIN_FLOAT) {
193
- dev_warn(&phy->dev, "USB ID detect failed!\n");
194
- clk_disable_unprepare(priv->clk_usb);
195
- clk_disable_unprepare(priv->clk_usb_general);
196
- return -EINVAL;
197
+ regmap_read(priv->regmap, REG_ADP_BC, &reg);
198
+ if (reg & REG_ADP_BC_ACA_PIN_FLOAT) {
199
+ dev_warn(&phy->dev, "USB ID detect failed!\n");
200
+ clk_disable_unprepare(priv->clk_usb);
201
+ clk_disable_unprepare(priv->clk_usb_general);
202
+ return -EINVAL;
203
+ }
197204 }
198205 }
199206
....@@ -203,6 +210,11 @@
203210 static int phy_meson8b_usb2_power_off(struct phy *phy)
204211 {
205212 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy);
213
+
214
+ if (priv->dr_mode == USB_DR_MODE_HOST)
215
+ regmap_update_bits(priv->regmap, REG_DBG_UART,
216
+ REG_DBG_UART_SET_IDDQ,
217
+ REG_DBG_UART_SET_IDDQ);
206218
207219 clk_disable_unprepare(priv->clk_usb);
208220 clk_disable_unprepare(priv->clk_usb_general);
....@@ -219,18 +231,26 @@
219231 static int phy_meson8b_usb2_probe(struct platform_device *pdev)
220232 {
221233 struct phy_meson8b_usb2_priv *priv;
222
- struct resource *res;
223234 struct phy *phy;
224235 struct phy_provider *phy_provider;
236
+ void __iomem *base;
225237
226238 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
227239 if (!priv)
228240 return -ENOMEM;
229241
230
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
231
- priv->regs = devm_ioremap_resource(&pdev->dev, res);
232
- if (IS_ERR(priv->regs))
233
- return PTR_ERR(priv->regs);
242
+ base = devm_platform_ioremap_resource(pdev, 0);
243
+ if (IS_ERR(base))
244
+ return PTR_ERR(base);
245
+
246
+ priv->match = device_get_match_data(&pdev->dev);
247
+ if (!priv->match)
248
+ return -ENODEV;
249
+
250
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
251
+ &phy_meson8b_usb2_regmap_conf);
252
+ if (IS_ERR(priv->regmap))
253
+ return PTR_ERR(priv->regmap);
234254
235255 priv->clk_usb_general = devm_clk_get(&pdev->dev, "usb_general");
236256 if (IS_ERR(priv->clk_usb_general))
....@@ -241,8 +261,9 @@
241261 return PTR_ERR(priv->clk_usb);
242262
243263 priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
244
- if (PTR_ERR(priv->reset) == -EPROBE_DEFER)
245
- return PTR_ERR(priv->reset);
264
+ if (IS_ERR(priv->reset))
265
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset),
266
+ "Failed to get the reset line");
246267
247268 priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1);
248269 if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
....@@ -265,11 +286,32 @@
265286 return PTR_ERR_OR_ZERO(phy_provider);
266287 }
267288
289
+static const struct phy_meson8b_usb2_match_data phy_meson8_usb2_match_data = {
290
+ .host_enable_aca = false,
291
+};
292
+
293
+static const struct phy_meson8b_usb2_match_data phy_meson8b_usb2_match_data = {
294
+ .host_enable_aca = true,
295
+};
296
+
268297 static const struct of_device_id phy_meson8b_usb2_of_match[] = {
269
- { .compatible = "amlogic,meson8-usb2-phy", },
270
- { .compatible = "amlogic,meson8b-usb2-phy", },
271
- { .compatible = "amlogic,meson-gxbb-usb2-phy", },
272
- { },
298
+ {
299
+ .compatible = "amlogic,meson8-usb2-phy",
300
+ .data = &phy_meson8_usb2_match_data
301
+ },
302
+ {
303
+ .compatible = "amlogic,meson8b-usb2-phy",
304
+ .data = &phy_meson8b_usb2_match_data
305
+ },
306
+ {
307
+ .compatible = "amlogic,meson8m2-usb2-phy",
308
+ .data = &phy_meson8b_usb2_match_data
309
+ },
310
+ {
311
+ .compatible = "amlogic,meson-gxbb-usb2-phy",
312
+ .data = &phy_meson8b_usb2_match_data
313
+ },
314
+ { /* sentinel */ }
273315 };
274316 MODULE_DEVICE_TABLE(of, phy_meson8b_usb2_of_match);
275317
....@@ -283,5 +325,5 @@
283325 module_platform_driver(phy_meson8b_usb2_driver);
284326
285327 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
286
-MODULE_DESCRIPTION("Meson8, Meson8b and GXBB USB2 PHY driver");
328
+MODULE_DESCRIPTION("Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY driver");
287329 MODULE_LICENSE("GPL");