]> git.sur5r.net Git - u-boot/blob - drivers/phy/meson-gxl-usb3.c
dm: spi: Update sandbox SPI emulation driver to use ofnode
[u-boot] / drivers / phy / meson-gxl-usb3.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Meson GXL USB3 PHY driver
4  *
5  * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
6  * Copyright (C) 2018 BayLibre, SAS
7  * Author: Neil Armstrong <narmstron@baylibre.com>
8  */
9
10 #include <common.h>
11 #include <asm/io.h>
12 #include <bitfield.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <generic-phy.h>
16 #include <regmap.h>
17 #include <clk.h>
18
19 #include <linux/bitops.h>
20 #include <linux/compat.h>
21 #include <linux/bitfield.h>
22
23 #define USB_R0                                                  0x00
24         #define USB_R0_P30_FSEL_MASK                            GENMASK(5, 0)
25         #define USB_R0_P30_PHY_RESET                            BIT(6)
26         #define USB_R0_P30_TEST_POWERDOWN_HSP                   BIT(7)
27         #define USB_R0_P30_TEST_POWERDOWN_SSP                   BIT(8)
28         #define USB_R0_P30_ACJT_LEVEL_MASK                      GENMASK(13, 9)
29         #define USB_R0_P30_TX_BOOST_LEVEL_MASK                  GENMASK(16, 14)
30         #define USB_R0_P30_LANE0_TX2RX_LOOPBACK                 BIT(17)
31         #define USB_R0_P30_LANE0_EXT_PCLK_REQ                   BIT(18)
32         #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK             GENMASK(28, 19)
33         #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK               GENMASK(30, 29)
34         #define USB_R0_U2D_ACT                                  BIT(31)
35
36 #define USB_R1                                                  0x04
37         #define USB_R1_U3H_BIGENDIAN_GS                         BIT(0)
38         #define USB_R1_U3H_PME_ENABLE                           BIT(1)
39         #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK            GENMASK(6, 2)
40         #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK            GENMASK(11, 7)
41         #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK            GENMASK(15, 12)
42         #define USB_R1_U3H_HOST_U3_PORT_DISABLE                 BIT(16)
43         #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT      BIT(17)
44         #define USB_R1_U3H_HOST_MSI_ENABLE                      BIT(18)
45         #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK                 GENMASK(24, 19)
46         #define USB_R1_P30_PCS_TX_SWING_FULL_MASK               GENMASK(31, 25)
47
48 #define USB_R2                                                  0x08
49         #define USB_R2_P30_CR_DATA_IN_MASK                      GENMASK(15, 0)
50         #define USB_R2_P30_CR_READ                              BIT(16)
51         #define USB_R2_P30_CR_WRITE                             BIT(17)
52         #define USB_R2_P30_CR_CAP_ADDR                          BIT(18)
53         #define USB_R2_P30_CR_CAP_DATA                          BIT(19)
54         #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK             GENMASK(25, 20)
55         #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK               GENMASK(31, 26)
56
57 #define USB_R3                                                  0x0c
58         #define USB_R3_P30_SSC_ENABLE                           BIT(0)
59         #define USB_R3_P30_SSC_RANGE_MASK                       GENMASK(3, 1)
60         #define USB_R3_P30_SSC_REF_CLK_SEL_MASK                 GENMASK(12, 4)
61         #define USB_R3_P30_REF_SSP_EN                           BIT(13)
62         #define USB_R3_P30_LOS_BIAS_MASK                        GENMASK(18, 16)
63         #define USB_R3_P30_LOS_LEVEL_MASK                       GENMASK(23, 19)
64         #define USB_R3_P30_MPLL_MULTIPLIER_MASK                 GENMASK(30, 24)
65
66 #define USB_R4                                                  0x10
67         #define USB_R4_P21_PORT_RESET_0                         BIT(0)
68         #define USB_R4_P21_SLEEP_M0                             BIT(1)
69         #define USB_R4_MEM_PD_MASK                              GENMASK(3, 2)
70         #define USB_R4_P21_ONLY                                 BIT(4)
71
72 #define USB_R5                                                  0x14
73         #define USB_R5_ID_DIG_SYNC                              BIT(0)
74         #define USB_R5_ID_DIG_REG                               BIT(1)
75         #define USB_R5_ID_DIG_CFG_MASK                          GENMASK(3, 2)
76         #define USB_R5_ID_DIG_EN_0                              BIT(4)
77         #define USB_R5_ID_DIG_EN_1                              BIT(5)
78         #define USB_R5_ID_DIG_CURR                              BIT(6)
79         #define USB_R5_ID_DIG_IRQ                               BIT(7)
80         #define USB_R5_ID_DIG_TH_MASK                           GENMASK(15, 8)
81         #define USB_R5_ID_DIG_CNT_MASK                          GENMASK(23, 16)
82
83 /* read-only register */
84 #define USB_R6                                                  0x18
85         #define USB_R6_P30_CR_DATA_OUT_MASK                     GENMASK(15, 0)
86         #define USB_R6_P30_CR_ACK                               BIT(16)
87
88 struct phy_meson_gxl_usb3_priv {
89         struct regmap           *regmap;
90 #if CONFIG_IS_ENABLED(CLK)
91         struct clk              clk;
92 #endif
93 };
94
95 static int
96 phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
97 {
98         uint val;
99
100         regmap_read(priv->regmap, USB_R0, &val);
101         val &= ~USB_R0_U2D_ACT;
102         regmap_write(priv->regmap, USB_R0, val);
103
104         regmap_read(priv->regmap, USB_R4, &val);
105         val &= ~USB_R4_P21_SLEEP_M0;
106         regmap_write(priv->regmap, USB_R4, val);
107
108         return 0;
109 }
110
111 static int phy_meson_gxl_usb3_power_on(struct phy *phy)
112 {
113         struct udevice *dev = phy->dev;
114         struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
115         uint val;
116
117         regmap_read(priv->regmap, USB_R5, &val);
118         val |= USB_R5_ID_DIG_EN_0;
119         val |= USB_R5_ID_DIG_EN_1;
120         val &= ~USB_R5_ID_DIG_TH_MASK;
121         val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
122         regmap_write(priv->regmap, USB_R5, val);
123
124         return phy_meson_gxl_usb3_set_host_mode(priv);
125 }
126
127 static int phy_meson_gxl_usb3_power_off(struct phy *phy)
128 {
129         struct udevice *dev = phy->dev;
130         struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
131         uint val;
132
133         regmap_read(priv->regmap, USB_R5, &val);
134         val &= ~USB_R5_ID_DIG_EN_0;
135         val &= ~USB_R5_ID_DIG_EN_1;
136         regmap_write(priv->regmap, USB_R5, val);
137
138         return 0;
139 }
140
141 static int phy_meson_gxl_usb3_init(struct phy *phy)
142 {
143         struct udevice *dev = phy->dev;
144         struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
145         uint val;
146
147         regmap_read(priv->regmap, USB_R1, &val);
148         val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
149         val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
150         regmap_write(priv->regmap, USB_R1, val);
151
152         return 0;
153 }
154
155 struct phy_ops meson_gxl_usb3_phy_ops = {
156         .init = phy_meson_gxl_usb3_init,
157         .power_on = phy_meson_gxl_usb3_power_on,
158         .power_off = phy_meson_gxl_usb3_power_off,
159 };
160
161 int meson_gxl_usb3_phy_probe(struct udevice *dev)
162 {
163         struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
164         int ret;
165
166         ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
167         if (ret)
168                 return ret;
169         
170 #if CONFIG_IS_ENABLED(CLK)
171         ret = clk_get_by_index(dev, 0, &priv->clk);
172         if (ret < 0)
173                 return ret;
174
175         ret = clk_enable(&priv->clk);
176         if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
177                 pr_err("failed to enable PHY clock\n");
178                 clk_free(&priv->clk);
179                 return ret;
180         }
181 #endif
182
183         return 0;
184 }
185
186 static const struct udevice_id meson_gxl_usb3_phy_ids[] = {
187         { .compatible = "amlogic,meson-gxl-usb3-phy" },
188         { }
189 };
190
191 U_BOOT_DRIVER(meson_gxl_usb3_phy) = {
192         .name = "meson_gxl_usb3_phy",
193         .id = UCLASS_PHY,
194         .of_match = meson_gxl_usb3_phy_ids,
195         .probe = meson_gxl_usb3_phy_probe,
196         .ops = &meson_gxl_usb3_phy_ops,
197         .priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb3_priv),
198 };