1925c5749SYifeng Zhao // SPDX-License-Identifier: GPL-2.0 2925c5749SYifeng Zhao /* 3925c5749SYifeng Zhao * Rockchip USB3.0/PCIe Gen2/SATA/SGMII combphy driver 4925c5749SYifeng Zhao * 5925c5749SYifeng Zhao * Copyright (C) 2021 Rockchip Electronics Co., Ltd. 6925c5749SYifeng Zhao */ 7925c5749SYifeng Zhao 8925c5749SYifeng Zhao #include <common.h> 9925c5749SYifeng Zhao #include <clk.h> 10925c5749SYifeng Zhao #include <dm.h> 11925c5749SYifeng Zhao #include <dm/lists.h> 12925c5749SYifeng Zhao #include <dt-bindings/phy/phy.h> 13925c5749SYifeng Zhao #include <generic-phy.h> 14925c5749SYifeng Zhao #include <syscon.h> 15925c5749SYifeng Zhao #include <asm/io.h> 16925c5749SYifeng Zhao #include <asm/arch/clock.h> 17925c5749SYifeng Zhao #include <regmap.h> 18925c5749SYifeng Zhao #include <reset-uclass.h> 19925c5749SYifeng Zhao 20925c5749SYifeng Zhao #define BIT_WRITEABLE_SHIFT 16 21925c5749SYifeng Zhao 22925c5749SYifeng Zhao struct rockchip_combphy_priv; 23925c5749SYifeng Zhao 24925c5749SYifeng Zhao struct combphy_reg { 253452d642SJianwei Zheng u32 offset; 26925c5749SYifeng Zhao u16 bitend; 27925c5749SYifeng Zhao u16 bitstart; 28925c5749SYifeng Zhao u16 disable; 29925c5749SYifeng Zhao u16 enable; 30925c5749SYifeng Zhao }; 31925c5749SYifeng Zhao 32925c5749SYifeng Zhao struct rockchip_combphy_grfcfg { 33925c5749SYifeng Zhao struct combphy_reg pcie_mode_set; 34925c5749SYifeng Zhao struct combphy_reg usb_mode_set; 35925c5749SYifeng Zhao struct combphy_reg sgmii_mode_set; 36925c5749SYifeng Zhao struct combphy_reg qsgmii_mode_set; 37925c5749SYifeng Zhao struct combphy_reg pipe_rxterm_set; 38925c5749SYifeng Zhao struct combphy_reg pipe_txelec_set; 39925c5749SYifeng Zhao struct combphy_reg pipe_txcomp_set; 403452d642SJianwei Zheng struct combphy_reg pipe_clk_24m; 41925c5749SYifeng Zhao struct combphy_reg pipe_clk_25m; 42925c5749SYifeng Zhao struct combphy_reg pipe_clk_100m; 43925c5749SYifeng Zhao struct combphy_reg pipe_phymode_sel; 44925c5749SYifeng Zhao struct combphy_reg pipe_rate_sel; 45925c5749SYifeng Zhao struct combphy_reg pipe_rxterm_sel; 46925c5749SYifeng Zhao struct combphy_reg pipe_txelec_sel; 47925c5749SYifeng Zhao struct combphy_reg pipe_txcomp_sel; 48925c5749SYifeng Zhao struct combphy_reg pipe_clk_ext; 49925c5749SYifeng Zhao struct combphy_reg pipe_sel_usb; 50925c5749SYifeng Zhao struct combphy_reg pipe_sel_qsgmii; 51925c5749SYifeng Zhao struct combphy_reg pipe_phy_status; 52925c5749SYifeng Zhao struct combphy_reg con0_for_pcie; 53925c5749SYifeng Zhao struct combphy_reg con1_for_pcie; 54925c5749SYifeng Zhao struct combphy_reg con2_for_pcie; 55925c5749SYifeng Zhao struct combphy_reg con3_for_pcie; 56925c5749SYifeng Zhao struct combphy_reg con0_for_sata; 57925c5749SYifeng Zhao struct combphy_reg con1_for_sata; 58925c5749SYifeng Zhao struct combphy_reg con2_for_sata; 59925c5749SYifeng Zhao struct combphy_reg con3_for_sata; 60925c5749SYifeng Zhao struct combphy_reg pipe_con0_for_sata; 61cf3c44cbSJon Lin struct combphy_reg pipe_con1_for_sata; 62925c5749SYifeng Zhao struct combphy_reg pipe_sgmii_mac_sel; 63925c5749SYifeng Zhao struct combphy_reg pipe_xpcs_phy_ready; 64925c5749SYifeng Zhao struct combphy_reg u3otg0_port_en; 65925c5749SYifeng Zhao struct combphy_reg u3otg1_port_en; 66925c5749SYifeng Zhao }; 67925c5749SYifeng Zhao 68925c5749SYifeng Zhao struct rockchip_combphy_cfg { 69925c5749SYifeng Zhao const struct rockchip_combphy_grfcfg *grfcfg; 70925c5749SYifeng Zhao int (*combphy_cfg)(struct rockchip_combphy_priv *priv); 71925c5749SYifeng Zhao }; 72925c5749SYifeng Zhao 73925c5749SYifeng Zhao struct rockchip_combphy_priv { 74925c5749SYifeng Zhao u32 mode; 75925c5749SYifeng Zhao void __iomem *mmio; 76925c5749SYifeng Zhao struct udevice *dev; 77925c5749SYifeng Zhao struct regmap *pipe_grf; 78925c5749SYifeng Zhao struct regmap *phy_grf; 79925c5749SYifeng Zhao struct phy *phy; 80925c5749SYifeng Zhao struct reset_ctl phy_rst; 81925c5749SYifeng Zhao struct clk ref_clk; 82925c5749SYifeng Zhao const struct rockchip_combphy_cfg *cfg; 83925c5749SYifeng Zhao }; 84925c5749SYifeng Zhao 85925c5749SYifeng Zhao static int param_write(struct regmap *base, 86925c5749SYifeng Zhao const struct combphy_reg *reg, bool en) 87925c5749SYifeng Zhao { 88925c5749SYifeng Zhao u32 val, mask, tmp; 89925c5749SYifeng Zhao 90925c5749SYifeng Zhao tmp = en ? reg->enable : reg->disable; 91925c5749SYifeng Zhao mask = GENMASK(reg->bitend, reg->bitstart); 92925c5749SYifeng Zhao val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); 93925c5749SYifeng Zhao 94925c5749SYifeng Zhao return regmap_write(base, reg->offset, val); 95925c5749SYifeng Zhao } 96925c5749SYifeng Zhao 97925c5749SYifeng Zhao static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv) 98925c5749SYifeng Zhao { 99925c5749SYifeng Zhao int ret = 0; 100925c5749SYifeng Zhao 101925c5749SYifeng Zhao if (priv->cfg->combphy_cfg) { 102925c5749SYifeng Zhao ret = priv->cfg->combphy_cfg(priv); 103925c5749SYifeng Zhao if (ret) { 104925c5749SYifeng Zhao dev_err(priv->dev, "failed to init phy for pcie\n"); 105925c5749SYifeng Zhao return ret; 106925c5749SYifeng Zhao } 107925c5749SYifeng Zhao } 108925c5749SYifeng Zhao 109925c5749SYifeng Zhao return ret; 110925c5749SYifeng Zhao } 111925c5749SYifeng Zhao 112925c5749SYifeng Zhao static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv) 113925c5749SYifeng Zhao { 114925c5749SYifeng Zhao int ret = 0; 115925c5749SYifeng Zhao 116925c5749SYifeng Zhao if (priv->cfg->combphy_cfg) { 117925c5749SYifeng Zhao ret = priv->cfg->combphy_cfg(priv); 118925c5749SYifeng Zhao if (ret) { 119925c5749SYifeng Zhao dev_err(priv->dev, "failed to init phy for usb3\n"); 120925c5749SYifeng Zhao return ret; 121925c5749SYifeng Zhao } 122925c5749SYifeng Zhao } 123925c5749SYifeng Zhao 124925c5749SYifeng Zhao return ret; 125925c5749SYifeng Zhao } 126925c5749SYifeng Zhao 127925c5749SYifeng Zhao static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv) 128925c5749SYifeng Zhao { 129925c5749SYifeng Zhao int ret = 0; 130925c5749SYifeng Zhao 131925c5749SYifeng Zhao if (priv->cfg->combphy_cfg) { 132925c5749SYifeng Zhao ret = priv->cfg->combphy_cfg(priv); 133925c5749SYifeng Zhao if (ret) { 134925c5749SYifeng Zhao dev_err(priv->dev, "failed to init phy for sata\n"); 135925c5749SYifeng Zhao return ret; 136925c5749SYifeng Zhao } 137925c5749SYifeng Zhao } 138925c5749SYifeng Zhao 139925c5749SYifeng Zhao return ret; 140925c5749SYifeng Zhao } 141925c5749SYifeng Zhao 142925c5749SYifeng Zhao static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv) 143925c5749SYifeng Zhao { 144925c5749SYifeng Zhao int ret = 0; 145925c5749SYifeng Zhao 146925c5749SYifeng Zhao if (priv->cfg->combphy_cfg) { 147925c5749SYifeng Zhao ret = priv->cfg->combphy_cfg(priv); 148925c5749SYifeng Zhao if (ret) { 149925c5749SYifeng Zhao dev_err(priv->dev, "failed to init phy for sgmii\n"); 150925c5749SYifeng Zhao return ret; 151925c5749SYifeng Zhao } 152925c5749SYifeng Zhao } 153925c5749SYifeng Zhao 154925c5749SYifeng Zhao return ret; 155925c5749SYifeng Zhao } 156925c5749SYifeng Zhao 157925c5749SYifeng Zhao static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv) 158925c5749SYifeng Zhao { 159925c5749SYifeng Zhao switch (priv->mode) { 160925c5749SYifeng Zhao case PHY_TYPE_PCIE: 161925c5749SYifeng Zhao rockchip_combphy_pcie_init(priv); 162925c5749SYifeng Zhao break; 163925c5749SYifeng Zhao case PHY_TYPE_USB3: 164925c5749SYifeng Zhao rockchip_combphy_usb3_init(priv); 165925c5749SYifeng Zhao break; 166925c5749SYifeng Zhao case PHY_TYPE_SATA: 167925c5749SYifeng Zhao rockchip_combphy_sata_init(priv); 168925c5749SYifeng Zhao break; 169925c5749SYifeng Zhao case PHY_TYPE_SGMII: 170925c5749SYifeng Zhao case PHY_TYPE_QSGMII: 171925c5749SYifeng Zhao return rockchip_combphy_sgmii_init(priv); 172925c5749SYifeng Zhao default: 173925c5749SYifeng Zhao dev_err(priv->dev, "incompatible PHY type\n"); 174925c5749SYifeng Zhao return -EINVAL; 175925c5749SYifeng Zhao } 176925c5749SYifeng Zhao 177925c5749SYifeng Zhao return 0; 178925c5749SYifeng Zhao } 179925c5749SYifeng Zhao 180925c5749SYifeng Zhao static int rockchip_combphy_init(struct phy *phy) 181925c5749SYifeng Zhao { 182925c5749SYifeng Zhao struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 183925c5749SYifeng Zhao int ret; 184925c5749SYifeng Zhao 185925c5749SYifeng Zhao ret = clk_enable(&priv->ref_clk); 186925c5749SYifeng Zhao if (ret < 0 && ret != -ENOSYS) 187925c5749SYifeng Zhao return ret; 188925c5749SYifeng Zhao 189925c5749SYifeng Zhao ret = rockchip_combphy_set_mode(priv); 190925c5749SYifeng Zhao if (ret) 191925c5749SYifeng Zhao goto err_clk; 192925c5749SYifeng Zhao 193925c5749SYifeng Zhao reset_deassert(&priv->phy_rst); 194925c5749SYifeng Zhao 195925c5749SYifeng Zhao return 0; 196925c5749SYifeng Zhao 197925c5749SYifeng Zhao err_clk: 198925c5749SYifeng Zhao clk_disable(&priv->ref_clk); 199925c5749SYifeng Zhao 200925c5749SYifeng Zhao return ret; 201925c5749SYifeng Zhao } 202925c5749SYifeng Zhao 203925c5749SYifeng Zhao static int rockchip_combphy_exit(struct phy *phy) 204925c5749SYifeng Zhao { 205925c5749SYifeng Zhao struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 206925c5749SYifeng Zhao 207925c5749SYifeng Zhao clk_disable(&priv->ref_clk); 208925c5749SYifeng Zhao reset_assert(&priv->phy_rst); 209925c5749SYifeng Zhao 210925c5749SYifeng Zhao return 0; 211925c5749SYifeng Zhao } 212925c5749SYifeng Zhao 213925c5749SYifeng Zhao static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *args) 214925c5749SYifeng Zhao { 215925c5749SYifeng Zhao struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev); 216925c5749SYifeng Zhao 217925c5749SYifeng Zhao if (args->args_count != 1) { 218925c5749SYifeng Zhao pr_err("invalid number of arguments\n"); 219925c5749SYifeng Zhao return -EINVAL; 220925c5749SYifeng Zhao } 221925c5749SYifeng Zhao 222925c5749SYifeng Zhao priv->mode = args->args[0]; 223925c5749SYifeng Zhao 224925c5749SYifeng Zhao return 0; 225925c5749SYifeng Zhao } 226925c5749SYifeng Zhao 227925c5749SYifeng Zhao static const struct phy_ops rochchip_combphy_ops = { 228925c5749SYifeng Zhao .init = rockchip_combphy_init, 229925c5749SYifeng Zhao .exit = rockchip_combphy_exit, 230925c5749SYifeng Zhao .of_xlate = rockchip_combphy_xlate, 231925c5749SYifeng Zhao }; 232925c5749SYifeng Zhao 233925c5749SYifeng Zhao static int rockchip_combphy_parse_dt(struct udevice *dev, 234925c5749SYifeng Zhao struct rockchip_combphy_priv *priv) 235925c5749SYifeng Zhao { 236925c5749SYifeng Zhao struct udevice *syscon; 237925c5749SYifeng Zhao int ret; 2387cc44222SJon Lin u32 vals[4]; 239925c5749SYifeng Zhao 240925c5749SYifeng Zhao ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon); 241925c5749SYifeng Zhao if (ret) { 242cf3c44cbSJon Lin dev_err(dev, "failed to find peri_ctrl pipe-grf regmap ret= %d\n", ret); 243925c5749SYifeng Zhao return ret; 244925c5749SYifeng Zhao } 245925c5749SYifeng Zhao priv->pipe_grf = syscon_get_regmap(syscon); 246925c5749SYifeng Zhao 247925c5749SYifeng Zhao ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon); 248925c5749SYifeng Zhao if (ret) { 249925c5749SYifeng Zhao dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n"); 250925c5749SYifeng Zhao return ret; 251925c5749SYifeng Zhao } 252925c5749SYifeng Zhao priv->phy_grf = syscon_get_regmap(syscon); 253925c5749SYifeng Zhao 254925c5749SYifeng Zhao ret = clk_get_by_index(dev, 0, &priv->ref_clk); 255925c5749SYifeng Zhao if (ret) { 256925c5749SYifeng Zhao dev_err(dev, "failed to find ref clock\n"); 257925c5749SYifeng Zhao return PTR_ERR(&priv->ref_clk); 258925c5749SYifeng Zhao } 259925c5749SYifeng Zhao 260dbf89912SRen Jianing ret = reset_get_by_name(dev, "combphy", &priv->phy_rst); 261925c5749SYifeng Zhao if (ret) { 262925c5749SYifeng Zhao dev_err(dev, "no phy reset control specified\n"); 263925c5749SYifeng Zhao return ret; 264925c5749SYifeng Zhao } 265925c5749SYifeng Zhao 2667cc44222SJon Lin if (!dev_read_u32_array(dev, "rockchip,pcie1ln-sel-bits", 2677cc44222SJon Lin vals, ARRAY_SIZE(vals))) 2687cc44222SJon Lin regmap_write(priv->pipe_grf, vals[0], 2697cc44222SJon Lin (GENMASK(vals[2], vals[1]) << 16) | vals[3]); 2707cc44222SJon Lin 271925c5749SYifeng Zhao return 0; 272925c5749SYifeng Zhao } 273925c5749SYifeng Zhao 274925c5749SYifeng Zhao static int rockchip_combphy_probe(struct udevice *udev) 275925c5749SYifeng Zhao { 276925c5749SYifeng Zhao struct rockchip_combphy_priv *priv = dev_get_priv(udev); 277925c5749SYifeng Zhao const struct rockchip_combphy_cfg *phy_cfg; 278925c5749SYifeng Zhao 279925c5749SYifeng Zhao priv->mmio = (void __iomem *)dev_read_addr(udev); 280925c5749SYifeng Zhao if (IS_ERR(priv->mmio)) 281925c5749SYifeng Zhao return PTR_ERR(priv->mmio); 282925c5749SYifeng Zhao 283925c5749SYifeng Zhao phy_cfg = (const struct rockchip_combphy_cfg *)dev_get_driver_data(udev); 284925c5749SYifeng Zhao if (!phy_cfg) { 285925c5749SYifeng Zhao dev_err(udev, "No OF match data provided\n"); 286925c5749SYifeng Zhao return -EINVAL; 287925c5749SYifeng Zhao } 288925c5749SYifeng Zhao 289925c5749SYifeng Zhao priv->dev = udev; 290925c5749SYifeng Zhao priv->mode = PHY_TYPE_SATA; 291925c5749SYifeng Zhao priv->cfg = phy_cfg; 292925c5749SYifeng Zhao 2935eec6d12SJon Lin return rockchip_combphy_parse_dt(udev, priv); 294925c5749SYifeng Zhao } 295925c5749SYifeng Zhao 2963452d642SJianwei Zheng static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) 2973452d642SJianwei Zheng { 2983452d642SJianwei Zheng const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 2993452d642SJianwei Zheng u32 val; 3003452d642SJianwei Zheng 3013452d642SJianwei Zheng switch (priv->mode) { 3023452d642SJianwei Zheng case PHY_TYPE_PCIE: 3033452d642SJianwei Zheng /* Set SSC downward spread spectrum */ 3043452d642SJianwei Zheng val = readl(priv->mmio + 0x18); 3053452d642SJianwei Zheng val &= ~GENMASK(5, 4); 3063452d642SJianwei Zheng val |= 0x01 << 4; 3073452d642SJianwei Zheng writel(val, priv->mmio + 0x18); 3083452d642SJianwei Zheng 3093452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 3103452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 3113452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 3123452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 3133452d642SJianwei Zheng break; 3143452d642SJianwei Zheng case PHY_TYPE_USB3: 3153452d642SJianwei Zheng /* Set SSC downward spread spectrum */ 3163452d642SJianwei Zheng val = readl(priv->mmio + 0x18); 3173452d642SJianwei Zheng val &= ~GENMASK(5, 4); 3183452d642SJianwei Zheng val |= 0x01 << 4; 3193452d642SJianwei Zheng writel(val, priv->mmio + 0x18); 3203452d642SJianwei Zheng 3213452d642SJianwei Zheng /* Enable adaptive CTLE for USB3.0 Rx */ 3223452d642SJianwei Zheng val = readl(priv->mmio + 0x200); 3233452d642SJianwei Zheng val &= ~GENMASK(17, 17); 3243452d642SJianwei Zheng val |= 0x01; 3253452d642SJianwei Zheng writel(val, priv->mmio + 0x200); 3263452d642SJianwei Zheng 3273452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 3283452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 3293452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->usb_mode_set, true); 3303452d642SJianwei Zheng break; 3313452d642SJianwei Zheng default: 3323452d642SJianwei Zheng dev_err(priv->dev, "incompatible PHY type\n"); 3333452d642SJianwei Zheng return -EINVAL; 3343452d642SJianwei Zheng } 3353452d642SJianwei Zheng 3363452d642SJianwei Zheng param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 3373452d642SJianwei Zheng if (priv->mode == PHY_TYPE_PCIE) { 3383452d642SJianwei Zheng /* PLL KVCO tuning fine */ 3393452d642SJianwei Zheng val = readl(priv->mmio + 0x18); 3403452d642SJianwei Zheng val &= ~(0x7 << 10); 3413452d642SJianwei Zheng val |= 0x2 << 10; 3423452d642SJianwei Zheng writel(val, priv->mmio + 0x18); 3433452d642SJianwei Zheng 3443452d642SJianwei Zheng /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */ 3453452d642SJianwei Zheng val = readl(priv->mmio + 0x108); 3463452d642SJianwei Zheng val &= ~(0x7f7); 3473452d642SJianwei Zheng val |= 0x4f0; 3483452d642SJianwei Zheng writel(val, priv->mmio + 0x108); 3493452d642SJianwei Zheng } 3503452d642SJianwei Zheng 3513452d642SJianwei Zheng return 0; 3523452d642SJianwei Zheng } 3533452d642SJianwei Zheng 3543452d642SJianwei Zheng static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { 3553452d642SJianwei Zheng /* pipe-phy-grf */ 3563452d642SJianwei Zheng .pcie_mode_set = { 0x48000, 5, 0, 0x00, 0x11 }, 3573452d642SJianwei Zheng .usb_mode_set = { 0x48000, 5, 0, 0x00, 0x04 }, 3583452d642SJianwei Zheng .pipe_rxterm_set = { 0x48000, 12, 12, 0x00, 0x01 }, 3593452d642SJianwei Zheng .pipe_txelec_set = { 0x48004, 1, 1, 0x00, 0x01 }, 3603452d642SJianwei Zheng .pipe_txcomp_set = { 0x48004, 4, 4, 0x00, 0x01 }, 3613452d642SJianwei Zheng .pipe_clk_24m = { 0x48004, 14, 13, 0x00, 0x00 }, 3623452d642SJianwei Zheng .pipe_clk_100m = { 0x48004, 14, 13, 0x00, 0x02 }, 3633452d642SJianwei Zheng .pipe_rxterm_sel = { 0x48008, 8, 8, 0x00, 0x01 }, 3643452d642SJianwei Zheng .pipe_txelec_sel = { 0x48008, 12, 12, 0x00, 0x01 }, 3653452d642SJianwei Zheng .pipe_txcomp_sel = { 0x48008, 15, 15, 0x00, 0x01 }, 3663452d642SJianwei Zheng .pipe_clk_ext = { 0x4800c, 9, 8, 0x02, 0x01 }, 3673452d642SJianwei Zheng .pipe_phy_status = { 0x48034, 6, 6, 0x01, 0x00 }, 3683452d642SJianwei Zheng .con0_for_pcie = { 0x48000, 15, 0, 0x00, 0x110 }, 3693452d642SJianwei Zheng .con1_for_pcie = { 0x48004, 15, 0, 0x00, 0x00 }, 3703452d642SJianwei Zheng .con2_for_pcie = { 0x48008, 15, 0, 0x00, 0x101 }, 3713452d642SJianwei Zheng .con3_for_pcie = { 0x4800c, 15, 0, 0x00, 0x0200 }, 3723452d642SJianwei Zheng /* pipe-grf */ 3733452d642SJianwei Zheng .u3otg0_port_en = { 0x40044, 15, 0, 0x0181, 0x1100 }, 3743452d642SJianwei Zheng }; 3753452d642SJianwei Zheng 3763452d642SJianwei Zheng static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = { 3773452d642SJianwei Zheng .grfcfg = &rk3528_combphy_grfcfgs, 3783452d642SJianwei Zheng .combphy_cfg = rk3528_combphy_cfg, 3793452d642SJianwei Zheng }; 3803452d642SJianwei Zheng 381*885c5d5dSFrank Wang static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) 382*885c5d5dSFrank Wang { 383*885c5d5dSFrank Wang const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 384*885c5d5dSFrank Wang u32 val; 385*885c5d5dSFrank Wang 386*885c5d5dSFrank Wang switch (priv->mode) { 387*885c5d5dSFrank Wang case PHY_TYPE_PCIE: 388*885c5d5dSFrank Wang /* Set SSC downward spread spectrum */ 389*885c5d5dSFrank Wang val = readl(priv->mmio + (0x1f << 2)); 390*885c5d5dSFrank Wang val &= ~GENMASK(5, 4); 391*885c5d5dSFrank Wang val |= 0x01 << 4; 392*885c5d5dSFrank Wang writel(val, priv->mmio + 0x7c); 393*885c5d5dSFrank Wang 394*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 395*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 396*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 397*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 398*885c5d5dSFrank Wang break; 399*885c5d5dSFrank Wang case PHY_TYPE_USB3: 400*885c5d5dSFrank Wang /* Set SSC downward spread spectrum */ 401*885c5d5dSFrank Wang val = readl(priv->mmio + (0x1f << 2)); 402*885c5d5dSFrank Wang val &= ~GENMASK(5, 4); 403*885c5d5dSFrank Wang val |= 0x01 << 4; 404*885c5d5dSFrank Wang writel(val, priv->mmio + 0x7c); 405*885c5d5dSFrank Wang 406*885c5d5dSFrank Wang /* Enable adaptive CTLE for USB3.0 Rx */ 407*885c5d5dSFrank Wang val = readl(priv->mmio + (0x0e << 2)); 408*885c5d5dSFrank Wang val &= ~GENMASK(0, 0); 409*885c5d5dSFrank Wang val |= 0x01; 410*885c5d5dSFrank Wang writel(val, priv->mmio + (0x0e << 2)); 411*885c5d5dSFrank Wang 412*885c5d5dSFrank Wang /* Set PLL KVCO fine tuning signals */ 413*885c5d5dSFrank Wang val = readl(priv->mmio + (0x20 << 2)); 414*885c5d5dSFrank Wang val &= ~(0x7 << 2); 415*885c5d5dSFrank Wang val |= 0x2 << 2; 416*885c5d5dSFrank Wang writel(val, priv->mmio + (0x20 << 2)); 417*885c5d5dSFrank Wang 418*885c5d5dSFrank Wang /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 419*885c5d5dSFrank Wang writel(0x4, priv->mmio + (0xb << 2)); 420*885c5d5dSFrank Wang 421*885c5d5dSFrank Wang /* Set PLL input clock divider 1/2 */ 422*885c5d5dSFrank Wang val = readl(priv->mmio + (0x5 << 2)); 423*885c5d5dSFrank Wang val &= ~(0x3 << 6); 424*885c5d5dSFrank Wang val |= 0x1 << 6; 425*885c5d5dSFrank Wang writel(val, priv->mmio + (0x5 << 2)); 426*885c5d5dSFrank Wang 427*885c5d5dSFrank Wang /* Set PLL loop divider */ 428*885c5d5dSFrank Wang writel(0x32, priv->mmio + (0x11 << 2)); 429*885c5d5dSFrank Wang 430*885c5d5dSFrank Wang /* Set PLL KVCO to min and set PLL charge pump current to max */ 431*885c5d5dSFrank Wang writel(0xf0, priv->mmio + (0xa << 2)); 432*885c5d5dSFrank Wang 433*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 434*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 435*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 436*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->usb_mode_set, true); 437*885c5d5dSFrank Wang break; 438*885c5d5dSFrank Wang default: 439*885c5d5dSFrank Wang pr_err("%s, phy-type %d\n", __func__, priv->mode); 440*885c5d5dSFrank Wang return -EINVAL; 441*885c5d5dSFrank Wang } 442*885c5d5dSFrank Wang 443*885c5d5dSFrank Wang clk_set_rate(&priv->ref_clk, 100000000); 444*885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 445*885c5d5dSFrank Wang 446*885c5d5dSFrank Wang if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 447*885c5d5dSFrank Wang val = readl(priv->mmio + (0x7 << 2)); 448*885c5d5dSFrank Wang val |= BIT(4); 449*885c5d5dSFrank Wang writel(val, priv->mmio + (0x7 << 2)); 450*885c5d5dSFrank Wang } 451*885c5d5dSFrank Wang 452*885c5d5dSFrank Wang return 0; 453*885c5d5dSFrank Wang } 454*885c5d5dSFrank Wang 455*885c5d5dSFrank Wang static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = { 456*885c5d5dSFrank Wang /* pipe-phy-grf */ 457*885c5d5dSFrank Wang .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 458*885c5d5dSFrank Wang .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 459*885c5d5dSFrank Wang .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 460*885c5d5dSFrank Wang .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 461*885c5d5dSFrank Wang .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 462*885c5d5dSFrank Wang .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 463*885c5d5dSFrank Wang .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 464*885c5d5dSFrank Wang .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 465*885c5d5dSFrank Wang .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 466*885c5d5dSFrank Wang .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 467*885c5d5dSFrank Wang .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 468*885c5d5dSFrank Wang .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 469*885c5d5dSFrank Wang .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 470*885c5d5dSFrank Wang .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 471*885c5d5dSFrank Wang .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 472*885c5d5dSFrank Wang .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 473*885c5d5dSFrank Wang .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 474*885c5d5dSFrank Wang .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 475*885c5d5dSFrank Wang .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 476*885c5d5dSFrank Wang /* pipe-grf */ 477*885c5d5dSFrank Wang .u3otg0_port_en = { 0x0094, 15, 0, 0x0181, 0x1100 }, 478*885c5d5dSFrank Wang }; 479*885c5d5dSFrank Wang 480*885c5d5dSFrank Wang static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = { 481*885c5d5dSFrank Wang .grfcfg = &rk3562_combphy_grfcfgs, 482*885c5d5dSFrank Wang .combphy_cfg = rk3562_combphy_cfg, 483*885c5d5dSFrank Wang }; 484*885c5d5dSFrank Wang 485925c5749SYifeng Zhao static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) 486925c5749SYifeng Zhao { 487925c5749SYifeng Zhao const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 488925c5749SYifeng Zhao u32 val; 489925c5749SYifeng Zhao 490925c5749SYifeng Zhao switch (priv->mode) { 491925c5749SYifeng Zhao case PHY_TYPE_PCIE: 492925c5749SYifeng Zhao /* Set SSC downward spread spectrum */ 493925c5749SYifeng Zhao val = readl(priv->mmio + (0x1f << 2)); 494925c5749SYifeng Zhao val &= ~GENMASK(5, 4); 495925c5749SYifeng Zhao val |= 0x01 << 4; 496925c5749SYifeng Zhao writel(val, priv->mmio + 0x7c); 497925c5749SYifeng Zhao 498925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 499925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 500925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 501925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 502925c5749SYifeng Zhao break; 503925c5749SYifeng Zhao case PHY_TYPE_USB3: 504925c5749SYifeng Zhao /* Set SSC downward spread spectrum */ 505925c5749SYifeng Zhao val = readl(priv->mmio + (0x1f << 2)); 506925c5749SYifeng Zhao val &= ~GENMASK(5, 4); 507925c5749SYifeng Zhao val |= 0x01 << 4; 508925c5749SYifeng Zhao writel(val, priv->mmio + 0x7c); 509925c5749SYifeng Zhao 510925c5749SYifeng Zhao /* Enable adaptive CTLE for USB3.0 Rx */ 511925c5749SYifeng Zhao val = readl(priv->mmio + (0x0e << 2)); 512925c5749SYifeng Zhao val &= ~GENMASK(0, 0); 513925c5749SYifeng Zhao val |= 0x01; 514925c5749SYifeng Zhao writel(val, priv->mmio + (0x0e << 2)); 515925c5749SYifeng Zhao 516a0d03578SWilliam Wu /* Set PLL KVCO fine tuning signals */ 517a0d03578SWilliam Wu val = readl(priv->mmio + (0x20 << 2)); 518a0d03578SWilliam Wu val &= ~(0x7 << 2); 519a0d03578SWilliam Wu val |= 0x2 << 2; 520a0d03578SWilliam Wu writel(val, priv->mmio + (0x20 << 2)); 521a0d03578SWilliam Wu 522a0d03578SWilliam Wu /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 523a0d03578SWilliam Wu writel(0x4, priv->mmio + (0xb << 2)); 524a0d03578SWilliam Wu 525a0d03578SWilliam Wu /* Set PLL input clock divider 1/2 */ 526a0d03578SWilliam Wu val = readl(priv->mmio + (0x5 << 2)); 527a0d03578SWilliam Wu val &= ~(0x3 << 6); 528a0d03578SWilliam Wu val |= 0x1 << 6; 529a0d03578SWilliam Wu writel(val, priv->mmio + (0x5 << 2)); 530a0d03578SWilliam Wu 531a0d03578SWilliam Wu /* Set PLL loop divider */ 532a0d03578SWilliam Wu writel(0x32, priv->mmio + (0x11 << 2)); 533a0d03578SWilliam Wu 534a0d03578SWilliam Wu /* Set PLL KVCO to min and set PLL charge pump current to max */ 535a0d03578SWilliam Wu writel(0xf0, priv->mmio + (0xa << 2)); 536a0d03578SWilliam Wu 537925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 538925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 539925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 540925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->usb_mode_set, true); 541925c5749SYifeng Zhao break; 542925c5749SYifeng Zhao case PHY_TYPE_SATA: 543925c5749SYifeng Zhao writel(0x41, priv->mmio + 0x38); 544925c5749SYifeng Zhao writel(0x8F, priv->mmio + 0x18); 545925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con0_for_sata, true); 546925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con1_for_sata, true); 547925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con2_for_sata, true); 548925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con3_for_sata, true); 549925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 550925c5749SYifeng Zhao break; 551925c5749SYifeng Zhao case PHY_TYPE_SGMII: 552925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 553925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 554925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 555925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); 556925c5749SYifeng Zhao break; 557925c5749SYifeng Zhao case PHY_TYPE_QSGMII: 558925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 559925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 560925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); 561925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 562925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); 563925c5749SYifeng Zhao break; 564925c5749SYifeng Zhao default: 565925c5749SYifeng Zhao pr_err("%s, phy-type %d\n", __func__, priv->mode); 566925c5749SYifeng Zhao return -EINVAL; 567925c5749SYifeng Zhao } 568925c5749SYifeng Zhao 569dbf89912SRen Jianing /* The default ref clock is 25Mhz */ 570dbf89912SRen Jianing param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); 571925c5749SYifeng Zhao 572925c5749SYifeng Zhao if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 573925c5749SYifeng Zhao val = readl(priv->mmio + (0x7 << 2)); 574925c5749SYifeng Zhao val |= BIT(4); 575925c5749SYifeng Zhao writel(val, priv->mmio + (0x7 << 2)); 576925c5749SYifeng Zhao } 577925c5749SYifeng Zhao 578925c5749SYifeng Zhao return 0; 579925c5749SYifeng Zhao } 580925c5749SYifeng Zhao 581925c5749SYifeng Zhao static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { 582925c5749SYifeng Zhao /* pipe-phy-grf */ 583925c5749SYifeng Zhao .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 584925c5749SYifeng Zhao .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 585925c5749SYifeng Zhao .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, 586925c5749SYifeng Zhao .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, 587925c5749SYifeng Zhao .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 588925c5749SYifeng Zhao .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 589925c5749SYifeng Zhao .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 590925c5749SYifeng Zhao .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 591925c5749SYifeng Zhao .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 592925c5749SYifeng Zhao .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 593925c5749SYifeng Zhao .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 594925c5749SYifeng Zhao .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 595925c5749SYifeng Zhao .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 596925c5749SYifeng Zhao .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 597925c5749SYifeng Zhao .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 598925c5749SYifeng Zhao .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 599925c5749SYifeng Zhao .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, 600925c5749SYifeng Zhao .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 601925c5749SYifeng Zhao .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 602925c5749SYifeng Zhao .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 603925c5749SYifeng Zhao .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 604925c5749SYifeng Zhao .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 605925c5749SYifeng Zhao .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, 606925c5749SYifeng Zhao .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, 607925c5749SYifeng Zhao .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, 608925c5749SYifeng Zhao .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, 609925c5749SYifeng Zhao /* pipe-grf */ 610925c5749SYifeng Zhao .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 611925c5749SYifeng Zhao .pipe_sgmii_mac_sel = { 0x0040, 1, 1, 0x00, 0x01 }, 612925c5749SYifeng Zhao .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 613925c5749SYifeng Zhao .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, 614925c5749SYifeng Zhao .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, 615925c5749SYifeng Zhao }; 616925c5749SYifeng Zhao 617925c5749SYifeng Zhao static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { 618925c5749SYifeng Zhao .grfcfg = &rk3568_combphy_grfcfgs, 619925c5749SYifeng Zhao .combphy_cfg = rk3568_combphy_cfg, 620925c5749SYifeng Zhao }; 621925c5749SYifeng Zhao 622cf3c44cbSJon Lin static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) 623cf3c44cbSJon Lin { 624cf3c44cbSJon Lin const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 625d8968f57SWilliam Wu u32 val; 626cf3c44cbSJon Lin 627cf3c44cbSJon Lin switch (priv->mode) { 628cf3c44cbSJon Lin case PHY_TYPE_PCIE: 629cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 630cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 631cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 632cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 633cf3c44cbSJon Lin break; 634cf3c44cbSJon Lin case PHY_TYPE_USB3: 635d8968f57SWilliam Wu /* Set SSC downward spread spectrum */ 636d8968f57SWilliam Wu val = readl(priv->mmio + (0x1f << 2)); 637d8968f57SWilliam Wu val &= ~GENMASK(5, 4); 638d8968f57SWilliam Wu val |= 0x01 << 4; 639d8968f57SWilliam Wu writel(val, priv->mmio + 0x7c); 640d8968f57SWilliam Wu 641d8968f57SWilliam Wu /* Enable adaptive CTLE for USB3.0 Rx */ 642d8968f57SWilliam Wu val = readl(priv->mmio + (0x0e << 2)); 643d8968f57SWilliam Wu val &= ~GENMASK(0, 0); 644d8968f57SWilliam Wu val |= 0x01; 645d8968f57SWilliam Wu writel(val, priv->mmio + (0x0e << 2)); 646d8968f57SWilliam Wu 647d8968f57SWilliam Wu /* Set PLL KVCO fine tuning signals */ 648d8968f57SWilliam Wu val = readl(priv->mmio + (0x20 << 2)); 649d8968f57SWilliam Wu val &= ~(0x7 << 2); 650d8968f57SWilliam Wu val |= 0x2 << 2; 651d8968f57SWilliam Wu writel(val, priv->mmio + (0x20 << 2)); 652d8968f57SWilliam Wu 653d8968f57SWilliam Wu /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 654d8968f57SWilliam Wu writel(0x4, priv->mmio + (0xb << 2)); 655d8968f57SWilliam Wu 656d8968f57SWilliam Wu /* Set PLL input clock divider 1/2 */ 657d8968f57SWilliam Wu val = readl(priv->mmio + (0x5 << 2)); 658d8968f57SWilliam Wu val &= ~(0x3 << 6); 659d8968f57SWilliam Wu val |= 0x1 << 6; 660d8968f57SWilliam Wu writel(val, priv->mmio + (0x5 << 2)); 661d8968f57SWilliam Wu 662d8968f57SWilliam Wu /* Set PLL loop divider */ 663d8968f57SWilliam Wu writel(0x32, priv->mmio + (0x11 << 2)); 664d8968f57SWilliam Wu 665d8968f57SWilliam Wu /* Set PLL KVCO to min and set PLL charge pump current to max */ 666d8968f57SWilliam Wu writel(0xf0, priv->mmio + (0xa << 2)); 667d8968f57SWilliam Wu 66887bfcd06SWilliam Wu /* Set Rx squelch input filler bandwidth */ 66987bfcd06SWilliam Wu writel(0x0d, priv->mmio + (0x14 << 2)); 67087bfcd06SWilliam Wu 671cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 672cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 673cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->usb_mode_set, true); 674cf3c44cbSJon Lin break; 675cf3c44cbSJon Lin case PHY_TYPE_SATA: 676418dd88dSYifeng Zhao /* Enable adaptive CTLE for SATA Rx */ 677418dd88dSYifeng Zhao val = readl(priv->mmio + (0x0e << 2)); 678418dd88dSYifeng Zhao val &= ~GENMASK(0, 0); 679418dd88dSYifeng Zhao val |= 0x01; 680418dd88dSYifeng Zhao writel(val, priv->mmio + (0x0e << 2)); 681418dd88dSYifeng Zhao /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ 682418dd88dSYifeng Zhao writel(0x8F, priv->mmio + (0x06 << 2)); 683418dd88dSYifeng Zhao 684cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con0_for_sata, true); 685cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con1_for_sata, true); 686cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con2_for_sata, true); 687cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con3_for_sata, true); 688cf3c44cbSJon Lin param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 689cf3c44cbSJon Lin param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true); 690cf3c44cbSJon Lin break; 691cf3c44cbSJon Lin case PHY_TYPE_SGMII: 692cf3c44cbSJon Lin case PHY_TYPE_QSGMII: 693cf3c44cbSJon Lin default: 694cf3c44cbSJon Lin dev_err(priv->dev, "incompatible PHY type\n"); 695cf3c44cbSJon Lin return -EINVAL; 696cf3c44cbSJon Lin } 697cf3c44cbSJon Lin 698c72d402cSJon Lin /* 100MHz refclock signal is good */ 699c72d402cSJon Lin clk_set_rate(&priv->ref_clk, 100000000); 700cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 701e278c201SKever Yang if (priv->mode == PHY_TYPE_PCIE) { 702e278c201SKever Yang /* PLL KVCO tuning fine */ 703e278c201SKever Yang val = readl(priv->mmio + (0x20 << 2)); 704e278c201SKever Yang val &= ~GENMASK(4, 2); 705e278c201SKever Yang val |= 0x4 << 2; 706e278c201SKever Yang writel(val, priv->mmio + (0x20 << 2)); 707e278c201SKever Yang 708e278c201SKever Yang /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 709e278c201SKever Yang val = 0x4c; 710e278c201SKever Yang writel(val, priv->mmio + (0x1b << 2)); 711e278c201SKever Yang 712e278c201SKever Yang /* Set up su_trim: T3 */ 713e278c201SKever Yang val = 0xb0; 714e278c201SKever Yang writel(val, priv->mmio + (0xa << 2)); 715e278c201SKever Yang val = 0x47; 716e278c201SKever Yang writel(val, priv->mmio + (0xb << 2)); 717e278c201SKever Yang val = 0x57; 718e278c201SKever Yang writel(val, priv->mmio + (0xd << 2)); 719e278c201SKever Yang } 720cf3c44cbSJon Lin 721cf3c44cbSJon Lin return 0; 722cf3c44cbSJon Lin } 723cf3c44cbSJon Lin 724cf3c44cbSJon Lin static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { 725cf3c44cbSJon Lin /* pipe-phy-grf */ 726cf3c44cbSJon Lin .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 727cf3c44cbSJon Lin .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 728cf3c44cbSJon Lin .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 729cf3c44cbSJon Lin .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 730cf3c44cbSJon Lin .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 731cf3c44cbSJon Lin .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 732cf3c44cbSJon Lin .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 733cf3c44cbSJon Lin .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 734cf3c44cbSJon Lin .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 735cf3c44cbSJon Lin .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 736cf3c44cbSJon Lin .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 737cf3c44cbSJon Lin .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 738cf3c44cbSJon Lin .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 739cf3c44cbSJon Lin .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 740cf3c44cbSJon Lin .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 741cf3c44cbSJon Lin .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 742cf3c44cbSJon Lin .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, 743418dd88dSYifeng Zhao .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, 744cf3c44cbSJon Lin .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, 745cf3c44cbSJon Lin .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, 746cf3c44cbSJon Lin /* pipe-grf */ 747cf3c44cbSJon Lin .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, 748cf3c44cbSJon Lin .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, 749cf3c44cbSJon Lin }; 750cf3c44cbSJon Lin 751cf3c44cbSJon Lin static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { 752cf3c44cbSJon Lin .grfcfg = &rk3588_combphy_grfcfgs, 753cf3c44cbSJon Lin .combphy_cfg = rk3588_combphy_cfg, 754cf3c44cbSJon Lin }; 755cf3c44cbSJon Lin 756925c5749SYifeng Zhao static const struct udevice_id rockchip_combphy_ids[] = { 757925c5749SYifeng Zhao { 7583452d642SJianwei Zheng .compatible = "rockchip,rk3528-naneng-combphy", 7593452d642SJianwei Zheng .data = (ulong)&rk3528_combphy_cfgs 7603452d642SJianwei Zheng }, 7613452d642SJianwei Zheng { 762*885c5d5dSFrank Wang .compatible = "rockchip,rk3562-naneng-combphy", 763*885c5d5dSFrank Wang .data = (ulong)&rk3562_combphy_cfgs 764*885c5d5dSFrank Wang }, 765*885c5d5dSFrank Wang { 766925c5749SYifeng Zhao .compatible = "rockchip,rk3568-naneng-combphy", 767925c5749SYifeng Zhao .data = (ulong)&rk3568_combphy_cfgs 768925c5749SYifeng Zhao }, 769cf3c44cbSJon Lin { 770cf3c44cbSJon Lin .compatible = "rockchip,rk3588-naneng-combphy", 771cf3c44cbSJon Lin .data = (ulong)&rk3588_combphy_cfgs 772cf3c44cbSJon Lin }, 773925c5749SYifeng Zhao { } 774925c5749SYifeng Zhao }; 775925c5749SYifeng Zhao 776925c5749SYifeng Zhao U_BOOT_DRIVER(rockchip_naneng_combphy) = { 777925c5749SYifeng Zhao .name = "naneng-combphy", 778925c5749SYifeng Zhao .id = UCLASS_PHY, 779925c5749SYifeng Zhao .of_match = rockchip_combphy_ids, 780925c5749SYifeng Zhao .ops = &rochchip_combphy_ops, 781925c5749SYifeng Zhao .probe = rockchip_combphy_probe, 782925c5749SYifeng Zhao .priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv), 783925c5749SYifeng Zhao }; 784