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