forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/usb/phy/phy-mxs-usb.c
....@@ -17,9 +17,11 @@
1717 #include <linux/of_device.h>
1818 #include <linux/regmap.h>
1919 #include <linux/mfd/syscon.h>
20
+#include <linux/iopoll.h>
2021
2122 #define DRIVER_NAME "mxs_phy"
2223
24
+/* Register Macro */
2325 #define HW_USBPHY_PWD 0x00
2426 #define HW_USBPHY_TX 0x10
2527 #define HW_USBPHY_CTRL 0x30
....@@ -36,6 +38,11 @@
3638 #define GM_USBPHY_TX_TXCAL45DP(x) (((x) & 0xf) << 16)
3739 #define GM_USBPHY_TX_TXCAL45DN(x) (((x) & 0xf) << 8)
3840 #define GM_USBPHY_TX_D_CAL(x) (((x) & 0xf) << 0)
41
+
42
+/* imx7ulp */
43
+#define HW_USBPHY_PLL_SIC 0xa0
44
+#define HW_USBPHY_PLL_SIC_SET 0xa4
45
+#define HW_USBPHY_PLL_SIC_CLR 0xa8
3946
4047 #define BM_USBPHY_CTRL_SFTRST BIT(31)
4148 #define BM_USBPHY_CTRL_CLKGATE BIT(30)
....@@ -55,6 +62,12 @@
5562 #define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
5663
5764 #define BM_USBPHY_DEBUG_CLKGATE BIT(30)
65
+/* imx7ulp */
66
+#define BM_USBPHY_PLL_LOCK BIT(31)
67
+#define BM_USBPHY_PLL_REG_ENABLE BIT(21)
68
+#define BM_USBPHY_PLL_BYPASS BIT(16)
69
+#define BM_USBPHY_PLL_POWER BIT(12)
70
+#define BM_USBPHY_PLL_EN_USB_CLKS BIT(6)
5871
5972 /* Anatop Registers */
6073 #define ANADIG_ANA_MISC0 0x150
....@@ -63,6 +76,7 @@
6376
6477 #define ANADIG_USB1_CHRG_DETECT_SET 0x1b4
6578 #define ANADIG_USB1_CHRG_DETECT_CLR 0x1b8
79
+#define ANADIG_USB2_CHRG_DETECT_SET 0x214
6680 #define ANADIG_USB1_CHRG_DETECT_EN_B BIT(20)
6781 #define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B BIT(19)
6882 #define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT BIT(18)
....@@ -167,6 +181,9 @@
167181 .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
168182 };
169183
184
+static const struct mxs_phy_data imx7ulp_phy_data = {
185
+};
186
+
170187 static const struct of_device_id mxs_phy_dt_ids[] = {
171188 { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
172189 { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
....@@ -174,6 +191,7 @@
174191 { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
175192 { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
176193 { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
194
+ { .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
177195 { /* sentinel */ }
178196 };
179197 MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
....@@ -196,6 +214,11 @@
196214 static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
197215 {
198216 return mxs_phy->data == &imx6sl_phy_data;
217
+}
218
+
219
+static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
220
+{
221
+ return mxs_phy->data == &imx7ulp_phy_data;
199222 }
200223
201224 /*
....@@ -221,14 +244,49 @@
221244 }
222245 }
223246
247
+static int mxs_phy_pll_enable(void __iomem *base, bool enable)
248
+{
249
+ int ret = 0;
250
+
251
+ if (enable) {
252
+ u32 value;
253
+
254
+ writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_SET);
255
+ writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_CLR);
256
+ writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_SET);
257
+ ret = readl_poll_timeout(base + HW_USBPHY_PLL_SIC,
258
+ value, (value & BM_USBPHY_PLL_LOCK) != 0,
259
+ 100, 10000);
260
+ if (ret)
261
+ return ret;
262
+
263
+ writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
264
+ HW_USBPHY_PLL_SIC_SET);
265
+ } else {
266
+ writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
267
+ HW_USBPHY_PLL_SIC_CLR);
268
+ writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_CLR);
269
+ writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_SET);
270
+ writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_CLR);
271
+ }
272
+
273
+ return ret;
274
+}
275
+
224276 static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
225277 {
226278 int ret;
227279 void __iomem *base = mxs_phy->phy.io_priv;
228280
281
+ if (is_imx7ulp_phy(mxs_phy)) {
282
+ ret = mxs_phy_pll_enable(base, true);
283
+ if (ret)
284
+ return ret;
285
+ }
286
+
229287 ret = stmp_reset_block(base + HW_USBPHY_CTRL);
230288 if (ret)
231
- return ret;
289
+ goto disable_pll;
232290
233291 /* Power up the PHY */
234292 writel(0, base + HW_USBPHY_PWD);
....@@ -250,9 +308,27 @@
250308 if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX)
251309 writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
252310
311
+ if (mxs_phy->regmap_anatop) {
312
+ unsigned int reg = mxs_phy->port_id ?
313
+ ANADIG_USB1_CHRG_DETECT_SET :
314
+ ANADIG_USB2_CHRG_DETECT_SET;
315
+ /*
316
+ * The external charger detector needs to be disabled,
317
+ * or the signal at DP will be poor
318
+ */
319
+ regmap_write(mxs_phy->regmap_anatop, reg,
320
+ ANADIG_USB1_CHRG_DETECT_EN_B |
321
+ ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
322
+ }
323
+
253324 mxs_phy_tx_init(mxs_phy);
254325
255326 return 0;
327
+
328
+disable_pll:
329
+ if (is_imx7ulp_phy(mxs_phy))
330
+ mxs_phy_pll_enable(base, false);
331
+ return ret;
256332 }
257333
258334 /* Return true if the vbus is there */
....@@ -312,14 +388,8 @@
312388
313389 static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
314390 {
315
- void __iomem *base = mxs_phy->phy.io_priv;
316
- u32 phyctrl = readl(base + HW_USBPHY_CTRL);
317
-
318
- if (IS_ENABLED(CONFIG_USB_OTG) &&
319
- !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
320
- return true;
321
-
322
- return false;
391
+ return IS_ENABLED(CONFIG_USB_OTG) &&
392
+ mxs_phy->phy.last_event == USB_EVENT_ID;
323393 }
324394
325395 static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
....@@ -373,6 +443,9 @@
373443
374444 writel(BM_USBPHY_CTRL_CLKGATE,
375445 phy->io_priv + HW_USBPHY_CTRL_SET);
446
+
447
+ if (is_imx7ulp_phy(mxs_phy))
448
+ mxs_phy_pll_enable(phy->io_priv, false);
376449
377450 clk_disable_unprepare(mxs_phy->clk);
378451 }
....@@ -563,7 +636,7 @@
563636 regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
564637 if (!(val & ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
565638 chgr_type = SDP_TYPE;
566
- dev_dbg(x->phy.dev, "It is a stardard downstream port\n");
639
+ dev_dbg(x->phy.dev, "It is a standard downstream port\n");
567640 }
568641
569642 /* Disable charger detector */
....@@ -631,7 +704,6 @@
631704
632705 static int mxs_phy_probe(struct platform_device *pdev)
633706 {
634
- struct resource *res;
635707 void __iomem *base;
636708 struct clk *clk;
637709 struct mxs_phy *mxs_phy;
....@@ -644,8 +716,7 @@
644716 if (!of_id)
645717 return -ENODEV;
646718
647
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
648
- base = devm_ioremap_resource(&pdev->dev, res);
719
+ base = devm_platform_ioremap_resource(pdev, 0);
649720 if (IS_ERR(base))
650721 return PTR_ERR(base);
651722