1*5ab43d0fSKunihiko Hayashi // SPDX-License-Identifier: GPL-2.0 2*5ab43d0fSKunihiko Hayashi /* 3*5ab43d0fSKunihiko Hayashi * phy-uniphier-usb3ss.c - SS-PHY driver for Socionext UniPhier USB3 controller 4*5ab43d0fSKunihiko Hayashi * Copyright 2015-2018 Socionext Inc. 5*5ab43d0fSKunihiko Hayashi * Author: 6*5ab43d0fSKunihiko Hayashi * Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 7*5ab43d0fSKunihiko Hayashi * Contributors: 8*5ab43d0fSKunihiko Hayashi * Motoya Tanigawa <tanigawa.motoya@socionext.com> 9*5ab43d0fSKunihiko Hayashi * Masami Hiramatsu <masami.hiramatsu@linaro.org> 10*5ab43d0fSKunihiko Hayashi */ 11*5ab43d0fSKunihiko Hayashi 12*5ab43d0fSKunihiko Hayashi #include <linux/bitfield.h> 13*5ab43d0fSKunihiko Hayashi #include <linux/bitops.h> 14*5ab43d0fSKunihiko Hayashi #include <linux/clk.h> 15*5ab43d0fSKunihiko Hayashi #include <linux/io.h> 16*5ab43d0fSKunihiko Hayashi #include <linux/module.h> 17*5ab43d0fSKunihiko Hayashi #include <linux/of.h> 18*5ab43d0fSKunihiko Hayashi #include <linux/of_platform.h> 19*5ab43d0fSKunihiko Hayashi #include <linux/phy/phy.h> 20*5ab43d0fSKunihiko Hayashi #include <linux/platform_device.h> 21*5ab43d0fSKunihiko Hayashi #include <linux/regulator/consumer.h> 22*5ab43d0fSKunihiko Hayashi #include <linux/reset.h> 23*5ab43d0fSKunihiko Hayashi 24*5ab43d0fSKunihiko Hayashi #define SSPHY_TESTI 0x0 25*5ab43d0fSKunihiko Hayashi #define SSPHY_TESTO 0x4 26*5ab43d0fSKunihiko Hayashi #define TESTI_DAT_MASK GENMASK(13, 6) 27*5ab43d0fSKunihiko Hayashi #define TESTI_ADR_MASK GENMASK(5, 1) 28*5ab43d0fSKunihiko Hayashi #define TESTI_WR_EN BIT(0) 29*5ab43d0fSKunihiko Hayashi 30*5ab43d0fSKunihiko Hayashi #define PHY_F(regno, msb, lsb) { (regno), (msb), (lsb) } 31*5ab43d0fSKunihiko Hayashi 32*5ab43d0fSKunihiko Hayashi #define CDR_CPD_TRIM PHY_F(7, 3, 0) /* RxPLL charge pump current */ 33*5ab43d0fSKunihiko Hayashi #define CDR_CPF_TRIM PHY_F(8, 3, 0) /* RxPLL charge pump current 2 */ 34*5ab43d0fSKunihiko Hayashi #define TX_PLL_TRIM PHY_F(9, 3, 0) /* TxPLL charge pump current */ 35*5ab43d0fSKunihiko Hayashi #define BGAP_TRIM PHY_F(11, 3, 0) /* Bandgap voltage */ 36*5ab43d0fSKunihiko Hayashi #define CDR_TRIM PHY_F(13, 6, 5) /* Clock Data Recovery setting */ 37*5ab43d0fSKunihiko Hayashi #define VCO_CTRL PHY_F(26, 7, 4) /* VCO control */ 38*5ab43d0fSKunihiko Hayashi #define VCOPLL_CTRL PHY_F(27, 2, 0) /* TxPLL VCO tuning */ 39*5ab43d0fSKunihiko Hayashi #define VCOPLL_CM PHY_F(28, 1, 0) /* TxPLL voltage */ 40*5ab43d0fSKunihiko Hayashi 41*5ab43d0fSKunihiko Hayashi #define MAX_PHY_PARAMS 7 42*5ab43d0fSKunihiko Hayashi 43*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_param { 44*5ab43d0fSKunihiko Hayashi struct { 45*5ab43d0fSKunihiko Hayashi int reg_no; 46*5ab43d0fSKunihiko Hayashi int msb; 47*5ab43d0fSKunihiko Hayashi int lsb; 48*5ab43d0fSKunihiko Hayashi } field; 49*5ab43d0fSKunihiko Hayashi u8 value; 50*5ab43d0fSKunihiko Hayashi }; 51*5ab43d0fSKunihiko Hayashi 52*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv { 53*5ab43d0fSKunihiko Hayashi struct device *dev; 54*5ab43d0fSKunihiko Hayashi void __iomem *base; 55*5ab43d0fSKunihiko Hayashi struct clk *clk, *clk_ext, *clk_parent, *clk_parent_gio; 56*5ab43d0fSKunihiko Hayashi struct reset_control *rst, *rst_parent, *rst_parent_gio; 57*5ab43d0fSKunihiko Hayashi struct regulator *vbus; 58*5ab43d0fSKunihiko Hayashi const struct uniphier_u3ssphy_soc_data *data; 59*5ab43d0fSKunihiko Hayashi }; 60*5ab43d0fSKunihiko Hayashi 61*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_soc_data { 62*5ab43d0fSKunihiko Hayashi bool is_legacy; 63*5ab43d0fSKunihiko Hayashi int nparams; 64*5ab43d0fSKunihiko Hayashi const struct uniphier_u3ssphy_param param[MAX_PHY_PARAMS]; 65*5ab43d0fSKunihiko Hayashi }; 66*5ab43d0fSKunihiko Hayashi 67*5ab43d0fSKunihiko Hayashi static void uniphier_u3ssphy_testio_write(struct uniphier_u3ssphy_priv *priv, 68*5ab43d0fSKunihiko Hayashi u32 data) 69*5ab43d0fSKunihiko Hayashi { 70*5ab43d0fSKunihiko Hayashi /* need to read TESTO twice after accessing TESTI */ 71*5ab43d0fSKunihiko Hayashi writel(data, priv->base + SSPHY_TESTI); 72*5ab43d0fSKunihiko Hayashi readl(priv->base + SSPHY_TESTO); 73*5ab43d0fSKunihiko Hayashi readl(priv->base + SSPHY_TESTO); 74*5ab43d0fSKunihiko Hayashi } 75*5ab43d0fSKunihiko Hayashi 76*5ab43d0fSKunihiko Hayashi static void uniphier_u3ssphy_set_param(struct uniphier_u3ssphy_priv *priv, 77*5ab43d0fSKunihiko Hayashi const struct uniphier_u3ssphy_param *p) 78*5ab43d0fSKunihiko Hayashi { 79*5ab43d0fSKunihiko Hayashi u32 val; 80*5ab43d0fSKunihiko Hayashi u8 field_mask = GENMASK(p->field.msb, p->field.lsb); 81*5ab43d0fSKunihiko Hayashi u8 data; 82*5ab43d0fSKunihiko Hayashi 83*5ab43d0fSKunihiko Hayashi /* read previous data */ 84*5ab43d0fSKunihiko Hayashi val = FIELD_PREP(TESTI_DAT_MASK, 1); 85*5ab43d0fSKunihiko Hayashi val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); 86*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_testio_write(priv, val); 87*5ab43d0fSKunihiko Hayashi val = readl(priv->base + SSPHY_TESTO); 88*5ab43d0fSKunihiko Hayashi 89*5ab43d0fSKunihiko Hayashi /* update value */ 90*5ab43d0fSKunihiko Hayashi val &= ~FIELD_PREP(TESTI_DAT_MASK, field_mask); 91*5ab43d0fSKunihiko Hayashi data = field_mask & (p->value << p->field.lsb); 92*5ab43d0fSKunihiko Hayashi val = FIELD_PREP(TESTI_DAT_MASK, data); 93*5ab43d0fSKunihiko Hayashi val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); 94*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_testio_write(priv, val); 95*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_testio_write(priv, val | TESTI_WR_EN); 96*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_testio_write(priv, val); 97*5ab43d0fSKunihiko Hayashi 98*5ab43d0fSKunihiko Hayashi /* read current data as dummy */ 99*5ab43d0fSKunihiko Hayashi val = FIELD_PREP(TESTI_DAT_MASK, 1); 100*5ab43d0fSKunihiko Hayashi val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); 101*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_testio_write(priv, val); 102*5ab43d0fSKunihiko Hayashi readl(priv->base + SSPHY_TESTO); 103*5ab43d0fSKunihiko Hayashi } 104*5ab43d0fSKunihiko Hayashi 105*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_power_on(struct phy *phy) 106*5ab43d0fSKunihiko Hayashi { 107*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy); 108*5ab43d0fSKunihiko Hayashi int ret; 109*5ab43d0fSKunihiko Hayashi 110*5ab43d0fSKunihiko Hayashi ret = clk_prepare_enable(priv->clk_ext); 111*5ab43d0fSKunihiko Hayashi if (ret) 112*5ab43d0fSKunihiko Hayashi return ret; 113*5ab43d0fSKunihiko Hayashi 114*5ab43d0fSKunihiko Hayashi ret = clk_prepare_enable(priv->clk); 115*5ab43d0fSKunihiko Hayashi if (ret) 116*5ab43d0fSKunihiko Hayashi goto out_clk_ext_disable; 117*5ab43d0fSKunihiko Hayashi 118*5ab43d0fSKunihiko Hayashi ret = reset_control_deassert(priv->rst); 119*5ab43d0fSKunihiko Hayashi if (ret) 120*5ab43d0fSKunihiko Hayashi goto out_clk_disable; 121*5ab43d0fSKunihiko Hayashi 122*5ab43d0fSKunihiko Hayashi if (priv->vbus) { 123*5ab43d0fSKunihiko Hayashi ret = regulator_enable(priv->vbus); 124*5ab43d0fSKunihiko Hayashi if (ret) 125*5ab43d0fSKunihiko Hayashi goto out_rst_assert; 126*5ab43d0fSKunihiko Hayashi } 127*5ab43d0fSKunihiko Hayashi 128*5ab43d0fSKunihiko Hayashi return 0; 129*5ab43d0fSKunihiko Hayashi 130*5ab43d0fSKunihiko Hayashi out_rst_assert: 131*5ab43d0fSKunihiko Hayashi reset_control_assert(priv->rst); 132*5ab43d0fSKunihiko Hayashi out_clk_disable: 133*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk); 134*5ab43d0fSKunihiko Hayashi out_clk_ext_disable: 135*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_ext); 136*5ab43d0fSKunihiko Hayashi 137*5ab43d0fSKunihiko Hayashi return ret; 138*5ab43d0fSKunihiko Hayashi } 139*5ab43d0fSKunihiko Hayashi 140*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_power_off(struct phy *phy) 141*5ab43d0fSKunihiko Hayashi { 142*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy); 143*5ab43d0fSKunihiko Hayashi 144*5ab43d0fSKunihiko Hayashi if (priv->vbus) 145*5ab43d0fSKunihiko Hayashi regulator_disable(priv->vbus); 146*5ab43d0fSKunihiko Hayashi 147*5ab43d0fSKunihiko Hayashi reset_control_assert(priv->rst); 148*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk); 149*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_ext); 150*5ab43d0fSKunihiko Hayashi 151*5ab43d0fSKunihiko Hayashi return 0; 152*5ab43d0fSKunihiko Hayashi } 153*5ab43d0fSKunihiko Hayashi 154*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_init(struct phy *phy) 155*5ab43d0fSKunihiko Hayashi { 156*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy); 157*5ab43d0fSKunihiko Hayashi int i, ret; 158*5ab43d0fSKunihiko Hayashi 159*5ab43d0fSKunihiko Hayashi ret = clk_prepare_enable(priv->clk_parent); 160*5ab43d0fSKunihiko Hayashi if (ret) 161*5ab43d0fSKunihiko Hayashi return ret; 162*5ab43d0fSKunihiko Hayashi 163*5ab43d0fSKunihiko Hayashi ret = clk_prepare_enable(priv->clk_parent_gio); 164*5ab43d0fSKunihiko Hayashi if (ret) 165*5ab43d0fSKunihiko Hayashi goto out_clk_disable; 166*5ab43d0fSKunihiko Hayashi 167*5ab43d0fSKunihiko Hayashi ret = reset_control_deassert(priv->rst_parent); 168*5ab43d0fSKunihiko Hayashi if (ret) 169*5ab43d0fSKunihiko Hayashi goto out_clk_gio_disable; 170*5ab43d0fSKunihiko Hayashi 171*5ab43d0fSKunihiko Hayashi ret = reset_control_deassert(priv->rst_parent_gio); 172*5ab43d0fSKunihiko Hayashi if (ret) 173*5ab43d0fSKunihiko Hayashi goto out_rst_assert; 174*5ab43d0fSKunihiko Hayashi 175*5ab43d0fSKunihiko Hayashi if (priv->data->is_legacy) 176*5ab43d0fSKunihiko Hayashi return 0; 177*5ab43d0fSKunihiko Hayashi 178*5ab43d0fSKunihiko Hayashi for (i = 0; i < priv->data->nparams; i++) 179*5ab43d0fSKunihiko Hayashi uniphier_u3ssphy_set_param(priv, &priv->data->param[i]); 180*5ab43d0fSKunihiko Hayashi 181*5ab43d0fSKunihiko Hayashi return 0; 182*5ab43d0fSKunihiko Hayashi 183*5ab43d0fSKunihiko Hayashi out_rst_assert: 184*5ab43d0fSKunihiko Hayashi reset_control_assert(priv->rst_parent); 185*5ab43d0fSKunihiko Hayashi out_clk_gio_disable: 186*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_parent_gio); 187*5ab43d0fSKunihiko Hayashi out_clk_disable: 188*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_parent); 189*5ab43d0fSKunihiko Hayashi 190*5ab43d0fSKunihiko Hayashi return ret; 191*5ab43d0fSKunihiko Hayashi } 192*5ab43d0fSKunihiko Hayashi 193*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_exit(struct phy *phy) 194*5ab43d0fSKunihiko Hayashi { 195*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv *priv = phy_get_drvdata(phy); 196*5ab43d0fSKunihiko Hayashi 197*5ab43d0fSKunihiko Hayashi reset_control_assert(priv->rst_parent_gio); 198*5ab43d0fSKunihiko Hayashi reset_control_assert(priv->rst_parent); 199*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_parent_gio); 200*5ab43d0fSKunihiko Hayashi clk_disable_unprepare(priv->clk_parent); 201*5ab43d0fSKunihiko Hayashi 202*5ab43d0fSKunihiko Hayashi return 0; 203*5ab43d0fSKunihiko Hayashi } 204*5ab43d0fSKunihiko Hayashi 205*5ab43d0fSKunihiko Hayashi static const struct phy_ops uniphier_u3ssphy_ops = { 206*5ab43d0fSKunihiko Hayashi .init = uniphier_u3ssphy_init, 207*5ab43d0fSKunihiko Hayashi .exit = uniphier_u3ssphy_exit, 208*5ab43d0fSKunihiko Hayashi .power_on = uniphier_u3ssphy_power_on, 209*5ab43d0fSKunihiko Hayashi .power_off = uniphier_u3ssphy_power_off, 210*5ab43d0fSKunihiko Hayashi .owner = THIS_MODULE, 211*5ab43d0fSKunihiko Hayashi }; 212*5ab43d0fSKunihiko Hayashi 213*5ab43d0fSKunihiko Hayashi static int uniphier_u3ssphy_probe(struct platform_device *pdev) 214*5ab43d0fSKunihiko Hayashi { 215*5ab43d0fSKunihiko Hayashi struct device *dev = &pdev->dev; 216*5ab43d0fSKunihiko Hayashi struct uniphier_u3ssphy_priv *priv; 217*5ab43d0fSKunihiko Hayashi struct phy_provider *phy_provider; 218*5ab43d0fSKunihiko Hayashi struct resource *res; 219*5ab43d0fSKunihiko Hayashi struct phy *phy; 220*5ab43d0fSKunihiko Hayashi 221*5ab43d0fSKunihiko Hayashi priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 222*5ab43d0fSKunihiko Hayashi if (!priv) 223*5ab43d0fSKunihiko Hayashi return -ENOMEM; 224*5ab43d0fSKunihiko Hayashi 225*5ab43d0fSKunihiko Hayashi priv->dev = dev; 226*5ab43d0fSKunihiko Hayashi priv->data = of_device_get_match_data(dev); 227*5ab43d0fSKunihiko Hayashi if (WARN_ON(!priv->data || 228*5ab43d0fSKunihiko Hayashi priv->data->nparams > MAX_PHY_PARAMS)) 229*5ab43d0fSKunihiko Hayashi return -EINVAL; 230*5ab43d0fSKunihiko Hayashi 231*5ab43d0fSKunihiko Hayashi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 232*5ab43d0fSKunihiko Hayashi priv->base = devm_ioremap_resource(dev, res); 233*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->base)) 234*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->base); 235*5ab43d0fSKunihiko Hayashi 236*5ab43d0fSKunihiko Hayashi if (!priv->data->is_legacy) { 237*5ab43d0fSKunihiko Hayashi priv->clk = devm_clk_get(dev, "phy"); 238*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->clk)) 239*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->clk); 240*5ab43d0fSKunihiko Hayashi 241*5ab43d0fSKunihiko Hayashi priv->clk_ext = devm_clk_get(dev, "phy-ext"); 242*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->clk_ext)) { 243*5ab43d0fSKunihiko Hayashi if (PTR_ERR(priv->clk_ext) == -ENOENT) 244*5ab43d0fSKunihiko Hayashi priv->clk_ext = NULL; 245*5ab43d0fSKunihiko Hayashi else 246*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->clk_ext); 247*5ab43d0fSKunihiko Hayashi } 248*5ab43d0fSKunihiko Hayashi 249*5ab43d0fSKunihiko Hayashi priv->rst = devm_reset_control_get_shared(dev, "phy"); 250*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->rst)) 251*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->rst); 252*5ab43d0fSKunihiko Hayashi } else { 253*5ab43d0fSKunihiko Hayashi priv->clk_parent_gio = devm_clk_get(dev, "gio"); 254*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->clk_parent_gio)) 255*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->clk_parent_gio); 256*5ab43d0fSKunihiko Hayashi 257*5ab43d0fSKunihiko Hayashi priv->rst_parent_gio = 258*5ab43d0fSKunihiko Hayashi devm_reset_control_get_shared(dev, "gio"); 259*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->rst_parent_gio)) 260*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->rst_parent_gio); 261*5ab43d0fSKunihiko Hayashi } 262*5ab43d0fSKunihiko Hayashi 263*5ab43d0fSKunihiko Hayashi priv->clk_parent = devm_clk_get(dev, "link"); 264*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->clk_parent)) 265*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->clk_parent); 266*5ab43d0fSKunihiko Hayashi 267*5ab43d0fSKunihiko Hayashi priv->rst_parent = devm_reset_control_get_shared(dev, "link"); 268*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->rst_parent)) 269*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->rst_parent); 270*5ab43d0fSKunihiko Hayashi 271*5ab43d0fSKunihiko Hayashi priv->vbus = devm_regulator_get_optional(dev, "vbus"); 272*5ab43d0fSKunihiko Hayashi if (IS_ERR(priv->vbus)) { 273*5ab43d0fSKunihiko Hayashi if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) 274*5ab43d0fSKunihiko Hayashi return PTR_ERR(priv->vbus); 275*5ab43d0fSKunihiko Hayashi priv->vbus = NULL; 276*5ab43d0fSKunihiko Hayashi } 277*5ab43d0fSKunihiko Hayashi 278*5ab43d0fSKunihiko Hayashi phy = devm_phy_create(dev, dev->of_node, &uniphier_u3ssphy_ops); 279*5ab43d0fSKunihiko Hayashi if (IS_ERR(phy)) 280*5ab43d0fSKunihiko Hayashi return PTR_ERR(phy); 281*5ab43d0fSKunihiko Hayashi 282*5ab43d0fSKunihiko Hayashi phy_set_drvdata(phy, priv); 283*5ab43d0fSKunihiko Hayashi phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 284*5ab43d0fSKunihiko Hayashi 285*5ab43d0fSKunihiko Hayashi return PTR_ERR_OR_ZERO(phy_provider); 286*5ab43d0fSKunihiko Hayashi } 287*5ab43d0fSKunihiko Hayashi 288*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_pro4_data = { 289*5ab43d0fSKunihiko Hayashi .is_legacy = true, 290*5ab43d0fSKunihiko Hayashi }; 291*5ab43d0fSKunihiko Hayashi 292*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_pxs2_data = { 293*5ab43d0fSKunihiko Hayashi .is_legacy = false, 294*5ab43d0fSKunihiko Hayashi .nparams = 7, 295*5ab43d0fSKunihiko Hayashi .param = { 296*5ab43d0fSKunihiko Hayashi { CDR_CPD_TRIM, 10 }, 297*5ab43d0fSKunihiko Hayashi { CDR_CPF_TRIM, 3 }, 298*5ab43d0fSKunihiko Hayashi { TX_PLL_TRIM, 5 }, 299*5ab43d0fSKunihiko Hayashi { BGAP_TRIM, 9 }, 300*5ab43d0fSKunihiko Hayashi { CDR_TRIM, 2 }, 301*5ab43d0fSKunihiko Hayashi { VCOPLL_CTRL, 7 }, 302*5ab43d0fSKunihiko Hayashi { VCOPLL_CM, 1 }, 303*5ab43d0fSKunihiko Hayashi }, 304*5ab43d0fSKunihiko Hayashi }; 305*5ab43d0fSKunihiko Hayashi 306*5ab43d0fSKunihiko Hayashi static const struct uniphier_u3ssphy_soc_data uniphier_ld20_data = { 307*5ab43d0fSKunihiko Hayashi .is_legacy = false, 308*5ab43d0fSKunihiko Hayashi .nparams = 3, 309*5ab43d0fSKunihiko Hayashi .param = { 310*5ab43d0fSKunihiko Hayashi { CDR_CPD_TRIM, 6 }, 311*5ab43d0fSKunihiko Hayashi { CDR_TRIM, 2 }, 312*5ab43d0fSKunihiko Hayashi { VCO_CTRL, 5 }, 313*5ab43d0fSKunihiko Hayashi }, 314*5ab43d0fSKunihiko Hayashi }; 315*5ab43d0fSKunihiko Hayashi 316*5ab43d0fSKunihiko Hayashi static const struct of_device_id uniphier_u3ssphy_match[] = { 317*5ab43d0fSKunihiko Hayashi { 318*5ab43d0fSKunihiko Hayashi .compatible = "socionext,uniphier-pro4-usb3-ssphy", 319*5ab43d0fSKunihiko Hayashi .data = &uniphier_pro4_data, 320*5ab43d0fSKunihiko Hayashi }, 321*5ab43d0fSKunihiko Hayashi { 322*5ab43d0fSKunihiko Hayashi .compatible = "socionext,uniphier-pxs2-usb3-ssphy", 323*5ab43d0fSKunihiko Hayashi .data = &uniphier_pxs2_data, 324*5ab43d0fSKunihiko Hayashi }, 325*5ab43d0fSKunihiko Hayashi { 326*5ab43d0fSKunihiko Hayashi .compatible = "socionext,uniphier-ld20-usb3-ssphy", 327*5ab43d0fSKunihiko Hayashi .data = &uniphier_ld20_data, 328*5ab43d0fSKunihiko Hayashi }, 329*5ab43d0fSKunihiko Hayashi { 330*5ab43d0fSKunihiko Hayashi .compatible = "socionext,uniphier-pxs3-usb3-ssphy", 331*5ab43d0fSKunihiko Hayashi .data = &uniphier_ld20_data, 332*5ab43d0fSKunihiko Hayashi }, 333*5ab43d0fSKunihiko Hayashi { /* sentinel */ } 334*5ab43d0fSKunihiko Hayashi }; 335*5ab43d0fSKunihiko Hayashi MODULE_DEVICE_TABLE(of, uniphier_u3ssphy_match); 336*5ab43d0fSKunihiko Hayashi 337*5ab43d0fSKunihiko Hayashi static struct platform_driver uniphier_u3ssphy_driver = { 338*5ab43d0fSKunihiko Hayashi .probe = uniphier_u3ssphy_probe, 339*5ab43d0fSKunihiko Hayashi .driver = { 340*5ab43d0fSKunihiko Hayashi .name = "uniphier-usb3-ssphy", 341*5ab43d0fSKunihiko Hayashi .of_match_table = uniphier_u3ssphy_match, 342*5ab43d0fSKunihiko Hayashi }, 343*5ab43d0fSKunihiko Hayashi }; 344*5ab43d0fSKunihiko Hayashi 345*5ab43d0fSKunihiko Hayashi module_platform_driver(uniphier_u3ssphy_driver); 346*5ab43d0fSKunihiko Hayashi 347*5ab43d0fSKunihiko Hayashi MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); 348*5ab43d0fSKunihiko Hayashi MODULE_DESCRIPTION("UniPhier SS-PHY driver for USB3 controller"); 349*5ab43d0fSKunihiko Hayashi MODULE_LICENSE("GPL v2"); 350