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 }; 199