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 381885c5d5dSFrank Wang static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) 382885c5d5dSFrank Wang { 383885c5d5dSFrank Wang const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 384885c5d5dSFrank Wang u32 val; 385885c5d5dSFrank Wang 386885c5d5dSFrank Wang switch (priv->mode) { 387885c5d5dSFrank Wang case PHY_TYPE_PCIE: 388885c5d5dSFrank Wang /* Set SSC downward spread spectrum */ 389885c5d5dSFrank Wang val = readl(priv->mmio + (0x1f << 2)); 390885c5d5dSFrank Wang val &= ~GENMASK(5, 4); 391885c5d5dSFrank Wang val |= 0x01 << 4; 392885c5d5dSFrank Wang writel(val, priv->mmio + 0x7c); 393885c5d5dSFrank Wang 394885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 395885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 396885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 397885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 398885c5d5dSFrank Wang break; 399885c5d5dSFrank Wang case PHY_TYPE_USB3: 400885c5d5dSFrank Wang /* Set SSC downward spread spectrum */ 401885c5d5dSFrank Wang val = readl(priv->mmio + (0x1f << 2)); 402885c5d5dSFrank Wang val &= ~GENMASK(5, 4); 403885c5d5dSFrank Wang val |= 0x01 << 4; 404885c5d5dSFrank Wang writel(val, priv->mmio + 0x7c); 405885c5d5dSFrank Wang 406885c5d5dSFrank Wang /* Enable adaptive CTLE for USB3.0 Rx */ 407885c5d5dSFrank Wang val = readl(priv->mmio + (0x0e << 2)); 408885c5d5dSFrank Wang val &= ~GENMASK(0, 0); 409885c5d5dSFrank Wang val |= 0x01; 410885c5d5dSFrank Wang writel(val, priv->mmio + (0x0e << 2)); 411885c5d5dSFrank Wang 412885c5d5dSFrank Wang /* Set PLL KVCO fine tuning signals */ 413885c5d5dSFrank Wang val = readl(priv->mmio + (0x20 << 2)); 414885c5d5dSFrank Wang val &= ~(0x7 << 2); 415885c5d5dSFrank Wang val |= 0x2 << 2; 416885c5d5dSFrank Wang writel(val, priv->mmio + (0x20 << 2)); 417885c5d5dSFrank Wang 418885c5d5dSFrank Wang /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 419885c5d5dSFrank Wang writel(0x4, priv->mmio + (0xb << 2)); 420885c5d5dSFrank Wang 421885c5d5dSFrank Wang /* Set PLL input clock divider 1/2 */ 422885c5d5dSFrank Wang val = readl(priv->mmio + (0x5 << 2)); 423885c5d5dSFrank Wang val &= ~(0x3 << 6); 424885c5d5dSFrank Wang val |= 0x1 << 6; 425885c5d5dSFrank Wang writel(val, priv->mmio + (0x5 << 2)); 426885c5d5dSFrank Wang 427885c5d5dSFrank Wang /* Set PLL loop divider */ 428885c5d5dSFrank Wang writel(0x32, priv->mmio + (0x11 << 2)); 429885c5d5dSFrank Wang 430885c5d5dSFrank Wang /* Set PLL KVCO to min and set PLL charge pump current to max */ 431885c5d5dSFrank Wang writel(0xf0, priv->mmio + (0xa << 2)); 432885c5d5dSFrank Wang 433885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 434885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 435885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 436885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->usb_mode_set, true); 437885c5d5dSFrank Wang break; 438885c5d5dSFrank Wang default: 439885c5d5dSFrank Wang pr_err("%s, phy-type %d\n", __func__, priv->mode); 440885c5d5dSFrank Wang return -EINVAL; 441885c5d5dSFrank Wang } 442885c5d5dSFrank Wang 443885c5d5dSFrank Wang clk_set_rate(&priv->ref_clk, 100000000); 444885c5d5dSFrank Wang param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 445885c5d5dSFrank Wang 446*cc9876f4SJon Lin if (priv->mode == PHY_TYPE_PCIE) { 447*cc9876f4SJon Lin /* PLL KVCO tuning fine */ 448*cc9876f4SJon Lin val = readl(priv->mmio + (0x20 << 2)); 449*cc9876f4SJon Lin val &= ~(0x7 << 2); 450*cc9876f4SJon Lin val |= 0x2 << 2; 451*cc9876f4SJon Lin writel(val, priv->mmio + (0x20 << 2)); 452*cc9876f4SJon Lin 453*cc9876f4SJon Lin /* Enable controlling random jitter, aka RMJ */ 454*cc9876f4SJon Lin writel(0x4, priv->mmio + (0xb << 2)); 455*cc9876f4SJon Lin 456*cc9876f4SJon Lin val = readl(priv->mmio + (0x5 << 2)); 457*cc9876f4SJon Lin val &= ~(0x3 << 6); 458*cc9876f4SJon Lin val |= 0x1 << 6; 459*cc9876f4SJon Lin writel(val, priv->mmio + (0x5 << 2)); 460*cc9876f4SJon Lin 461*cc9876f4SJon Lin writel(0x32, priv->mmio + (0x11 << 2)); 462*cc9876f4SJon Lin writel(0xf0, priv->mmio + (0xa << 2)); 463*cc9876f4SJon Lin } 464*cc9876f4SJon Lin 465885c5d5dSFrank Wang if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 466885c5d5dSFrank Wang val = readl(priv->mmio + (0x7 << 2)); 467885c5d5dSFrank Wang val |= BIT(4); 468885c5d5dSFrank Wang writel(val, priv->mmio + (0x7 << 2)); 469885c5d5dSFrank Wang } 470885c5d5dSFrank Wang 471885c5d5dSFrank Wang return 0; 472885c5d5dSFrank Wang } 473885c5d5dSFrank Wang 474885c5d5dSFrank Wang static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = { 475885c5d5dSFrank Wang /* pipe-phy-grf */ 476885c5d5dSFrank Wang .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 477885c5d5dSFrank Wang .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 478885c5d5dSFrank Wang .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 479885c5d5dSFrank Wang .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 480885c5d5dSFrank Wang .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 481885c5d5dSFrank Wang .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 482885c5d5dSFrank Wang .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 483885c5d5dSFrank Wang .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 484885c5d5dSFrank Wang .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 485885c5d5dSFrank Wang .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 486885c5d5dSFrank Wang .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 487885c5d5dSFrank Wang .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 488885c5d5dSFrank Wang .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 489885c5d5dSFrank Wang .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 490885c5d5dSFrank Wang .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 491885c5d5dSFrank Wang .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 492885c5d5dSFrank Wang .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 493885c5d5dSFrank Wang .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 494885c5d5dSFrank Wang .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 495885c5d5dSFrank Wang /* pipe-grf */ 496885c5d5dSFrank Wang .u3otg0_port_en = { 0x0094, 15, 0, 0x0181, 0x1100 }, 497885c5d5dSFrank Wang }; 498885c5d5dSFrank Wang 499885c5d5dSFrank Wang static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = { 500885c5d5dSFrank Wang .grfcfg = &rk3562_combphy_grfcfgs, 501885c5d5dSFrank Wang .combphy_cfg = rk3562_combphy_cfg, 502885c5d5dSFrank Wang }; 503885c5d5dSFrank Wang 504925c5749SYifeng Zhao static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) 505925c5749SYifeng Zhao { 506925c5749SYifeng Zhao const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 507925c5749SYifeng Zhao u32 val; 508925c5749SYifeng Zhao 509925c5749SYifeng Zhao switch (priv->mode) { 510925c5749SYifeng Zhao case PHY_TYPE_PCIE: 511925c5749SYifeng Zhao /* Set SSC downward spread spectrum */ 512925c5749SYifeng Zhao val = readl(priv->mmio + (0x1f << 2)); 513925c5749SYifeng Zhao val &= ~GENMASK(5, 4); 514925c5749SYifeng Zhao val |= 0x01 << 4; 515925c5749SYifeng Zhao writel(val, priv->mmio + 0x7c); 516925c5749SYifeng Zhao 517925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 518925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 519925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 520925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 521925c5749SYifeng Zhao break; 522925c5749SYifeng Zhao case PHY_TYPE_USB3: 523925c5749SYifeng Zhao /* Set SSC downward spread spectrum */ 524925c5749SYifeng Zhao val = readl(priv->mmio + (0x1f << 2)); 525925c5749SYifeng Zhao val &= ~GENMASK(5, 4); 526925c5749SYifeng Zhao val |= 0x01 << 4; 527925c5749SYifeng Zhao writel(val, priv->mmio + 0x7c); 528925c5749SYifeng Zhao 529925c5749SYifeng Zhao /* Enable adaptive CTLE for USB3.0 Rx */ 530925c5749SYifeng Zhao val = readl(priv->mmio + (0x0e << 2)); 531925c5749SYifeng Zhao val &= ~GENMASK(0, 0); 532925c5749SYifeng Zhao val |= 0x01; 533925c5749SYifeng Zhao writel(val, priv->mmio + (0x0e << 2)); 534925c5749SYifeng Zhao 535a0d03578SWilliam Wu /* Set PLL KVCO fine tuning signals */ 536a0d03578SWilliam Wu val = readl(priv->mmio + (0x20 << 2)); 537a0d03578SWilliam Wu val &= ~(0x7 << 2); 538a0d03578SWilliam Wu val |= 0x2 << 2; 539a0d03578SWilliam Wu writel(val, priv->mmio + (0x20 << 2)); 540a0d03578SWilliam Wu 541a0d03578SWilliam Wu /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 542a0d03578SWilliam Wu writel(0x4, priv->mmio + (0xb << 2)); 543a0d03578SWilliam Wu 544a0d03578SWilliam Wu /* Set PLL input clock divider 1/2 */ 545a0d03578SWilliam Wu val = readl(priv->mmio + (0x5 << 2)); 546a0d03578SWilliam Wu val &= ~(0x3 << 6); 547a0d03578SWilliam Wu val |= 0x1 << 6; 548a0d03578SWilliam Wu writel(val, priv->mmio + (0x5 << 2)); 549a0d03578SWilliam Wu 550a0d03578SWilliam Wu /* Set PLL loop divider */ 551a0d03578SWilliam Wu writel(0x32, priv->mmio + (0x11 << 2)); 552a0d03578SWilliam Wu 553a0d03578SWilliam Wu /* Set PLL KVCO to min and set PLL charge pump current to max */ 554a0d03578SWilliam Wu writel(0xf0, priv->mmio + (0xa << 2)); 555a0d03578SWilliam Wu 556925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); 557925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 558925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 559925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->usb_mode_set, true); 560925c5749SYifeng Zhao break; 561925c5749SYifeng Zhao case PHY_TYPE_SATA: 562925c5749SYifeng Zhao writel(0x41, priv->mmio + 0x38); 563925c5749SYifeng Zhao writel(0x8F, priv->mmio + 0x18); 564925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con0_for_sata, true); 565925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con1_for_sata, true); 566925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con2_for_sata, true); 567925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->con3_for_sata, true); 568925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 569925c5749SYifeng Zhao break; 570925c5749SYifeng Zhao case PHY_TYPE_SGMII: 571925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 572925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 573925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 574925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->sgmii_mode_set, true); 575925c5749SYifeng Zhao break; 576925c5749SYifeng Zhao case PHY_TYPE_QSGMII: 577925c5749SYifeng Zhao param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true); 578925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true); 579925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_rate_sel, true); 580925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true); 581925c5749SYifeng Zhao param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true); 582925c5749SYifeng Zhao break; 583925c5749SYifeng Zhao default: 584925c5749SYifeng Zhao pr_err("%s, phy-type %d\n", __func__, priv->mode); 585925c5749SYifeng Zhao return -EINVAL; 586925c5749SYifeng Zhao } 587925c5749SYifeng Zhao 588dbf89912SRen Jianing /* The default ref clock is 25Mhz */ 589dbf89912SRen Jianing param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); 590925c5749SYifeng Zhao 591925c5749SYifeng Zhao if (dev_read_bool(priv->dev, "rockchip,enable-ssc")) { 592925c5749SYifeng Zhao val = readl(priv->mmio + (0x7 << 2)); 593925c5749SYifeng Zhao val |= BIT(4); 594925c5749SYifeng Zhao writel(val, priv->mmio + (0x7 << 2)); 595925c5749SYifeng Zhao } 596925c5749SYifeng Zhao 597925c5749SYifeng Zhao return 0; 598925c5749SYifeng Zhao } 599925c5749SYifeng Zhao 600925c5749SYifeng Zhao static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { 601925c5749SYifeng Zhao /* pipe-phy-grf */ 602925c5749SYifeng Zhao .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 603925c5749SYifeng Zhao .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 604925c5749SYifeng Zhao .sgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x01 }, 605925c5749SYifeng Zhao .qsgmii_mode_set = { 0x0000, 5, 0, 0x00, 0x21 }, 606925c5749SYifeng Zhao .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 607925c5749SYifeng Zhao .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 608925c5749SYifeng Zhao .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 609925c5749SYifeng Zhao .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 610925c5749SYifeng Zhao .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 611925c5749SYifeng Zhao .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, 612925c5749SYifeng Zhao .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, 613925c5749SYifeng Zhao .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 614925c5749SYifeng Zhao .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 615925c5749SYifeng Zhao .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 616925c5749SYifeng Zhao .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 617925c5749SYifeng Zhao .pipe_sel_usb = { 0x000c, 14, 13, 0x00, 0x01 }, 618925c5749SYifeng Zhao .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x00, 0x07 }, 619925c5749SYifeng Zhao .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 620925c5749SYifeng Zhao .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 621925c5749SYifeng Zhao .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 622925c5749SYifeng Zhao .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 623925c5749SYifeng Zhao .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 624925c5749SYifeng Zhao .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0119 }, 625925c5749SYifeng Zhao .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0040 }, 626925c5749SYifeng Zhao .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c3 }, 627925c5749SYifeng Zhao .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x4407 }, 628925c5749SYifeng Zhao /* pipe-grf */ 629925c5749SYifeng Zhao .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, 630925c5749SYifeng Zhao .pipe_sgmii_mac_sel = { 0x0040, 1, 1, 0x00, 0x01 }, 631925c5749SYifeng Zhao .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, 632925c5749SYifeng Zhao .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, 633925c5749SYifeng Zhao .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, 634925c5749SYifeng Zhao }; 635925c5749SYifeng Zhao 636925c5749SYifeng Zhao static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { 637925c5749SYifeng Zhao .grfcfg = &rk3568_combphy_grfcfgs, 638925c5749SYifeng Zhao .combphy_cfg = rk3568_combphy_cfg, 639925c5749SYifeng Zhao }; 640925c5749SYifeng Zhao 641cf3c44cbSJon Lin static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) 642cf3c44cbSJon Lin { 643cf3c44cbSJon Lin const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; 644d8968f57SWilliam Wu u32 val; 645cf3c44cbSJon Lin 646cf3c44cbSJon Lin switch (priv->mode) { 647cf3c44cbSJon Lin case PHY_TYPE_PCIE: 648cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con0_for_pcie, true); 649cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 650cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 651cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 652cf3c44cbSJon Lin break; 653cf3c44cbSJon Lin case PHY_TYPE_USB3: 654d8968f57SWilliam Wu /* Set SSC downward spread spectrum */ 655d8968f57SWilliam Wu val = readl(priv->mmio + (0x1f << 2)); 656d8968f57SWilliam Wu val &= ~GENMASK(5, 4); 657d8968f57SWilliam Wu val |= 0x01 << 4; 658d8968f57SWilliam Wu writel(val, priv->mmio + 0x7c); 659d8968f57SWilliam Wu 660d8968f57SWilliam Wu /* Enable adaptive CTLE for USB3.0 Rx */ 661d8968f57SWilliam Wu val = readl(priv->mmio + (0x0e << 2)); 662d8968f57SWilliam Wu val &= ~GENMASK(0, 0); 663d8968f57SWilliam Wu val |= 0x01; 664d8968f57SWilliam Wu writel(val, priv->mmio + (0x0e << 2)); 665d8968f57SWilliam Wu 666d8968f57SWilliam Wu /* Set PLL KVCO fine tuning signals */ 667d8968f57SWilliam Wu val = readl(priv->mmio + (0x20 << 2)); 668d8968f57SWilliam Wu val &= ~(0x7 << 2); 669d8968f57SWilliam Wu val |= 0x2 << 2; 670d8968f57SWilliam Wu writel(val, priv->mmio + (0x20 << 2)); 671d8968f57SWilliam Wu 672d8968f57SWilliam Wu /* Set PLL LPF R1 to su_trim[10:7]=1001 */ 673d8968f57SWilliam Wu writel(0x4, priv->mmio + (0xb << 2)); 674d8968f57SWilliam Wu 675d8968f57SWilliam Wu /* Set PLL input clock divider 1/2 */ 676d8968f57SWilliam Wu val = readl(priv->mmio + (0x5 << 2)); 677d8968f57SWilliam Wu val &= ~(0x3 << 6); 678d8968f57SWilliam Wu val |= 0x1 << 6; 679d8968f57SWilliam Wu writel(val, priv->mmio + (0x5 << 2)); 680d8968f57SWilliam Wu 681d8968f57SWilliam Wu /* Set PLL loop divider */ 682d8968f57SWilliam Wu writel(0x32, priv->mmio + (0x11 << 2)); 683d8968f57SWilliam Wu 684d8968f57SWilliam Wu /* Set PLL KVCO to min and set PLL charge pump current to max */ 685d8968f57SWilliam Wu writel(0xf0, priv->mmio + (0xa << 2)); 686d8968f57SWilliam Wu 68787bfcd06SWilliam Wu /* Set Rx squelch input filler bandwidth */ 68887bfcd06SWilliam Wu writel(0x0d, priv->mmio + (0x14 << 2)); 68987bfcd06SWilliam Wu 690cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); 691cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); 692cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->usb_mode_set, true); 693cf3c44cbSJon Lin break; 694cf3c44cbSJon Lin case PHY_TYPE_SATA: 695418dd88dSYifeng Zhao /* Enable adaptive CTLE for SATA Rx */ 696418dd88dSYifeng Zhao val = readl(priv->mmio + (0x0e << 2)); 697418dd88dSYifeng Zhao val &= ~GENMASK(0, 0); 698418dd88dSYifeng Zhao val |= 0x01; 699418dd88dSYifeng Zhao writel(val, priv->mmio + (0x0e << 2)); 700418dd88dSYifeng Zhao /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ 701418dd88dSYifeng Zhao writel(0x8F, priv->mmio + (0x06 << 2)); 702418dd88dSYifeng Zhao 703cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con0_for_sata, true); 704cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con1_for_sata, true); 705cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con2_for_sata, true); 706cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->con3_for_sata, true); 707cf3c44cbSJon Lin param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true); 708cf3c44cbSJon Lin param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true); 709cf3c44cbSJon Lin break; 710cf3c44cbSJon Lin case PHY_TYPE_SGMII: 711cf3c44cbSJon Lin case PHY_TYPE_QSGMII: 712cf3c44cbSJon Lin default: 713cf3c44cbSJon Lin dev_err(priv->dev, "incompatible PHY type\n"); 714cf3c44cbSJon Lin return -EINVAL; 715cf3c44cbSJon Lin } 716cf3c44cbSJon Lin 717c72d402cSJon Lin /* 100MHz refclock signal is good */ 718c72d402cSJon Lin clk_set_rate(&priv->ref_clk, 100000000); 719cf3c44cbSJon Lin param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); 720e278c201SKever Yang if (priv->mode == PHY_TYPE_PCIE) { 721e278c201SKever Yang /* PLL KVCO tuning fine */ 722e278c201SKever Yang val = readl(priv->mmio + (0x20 << 2)); 723e278c201SKever Yang val &= ~GENMASK(4, 2); 724e278c201SKever Yang val |= 0x4 << 2; 725e278c201SKever Yang writel(val, priv->mmio + (0x20 << 2)); 726e278c201SKever Yang 727e278c201SKever Yang /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ 728e278c201SKever Yang val = 0x4c; 729e278c201SKever Yang writel(val, priv->mmio + (0x1b << 2)); 730e278c201SKever Yang 731e278c201SKever Yang /* Set up su_trim: T3 */ 732e278c201SKever Yang val = 0xb0; 733e278c201SKever Yang writel(val, priv->mmio + (0xa << 2)); 734e278c201SKever Yang val = 0x47; 735e278c201SKever Yang writel(val, priv->mmio + (0xb << 2)); 736e278c201SKever Yang val = 0x57; 737e278c201SKever Yang writel(val, priv->mmio + (0xd << 2)); 738e278c201SKever Yang } 739cf3c44cbSJon Lin 740cf3c44cbSJon Lin return 0; 741cf3c44cbSJon Lin } 742cf3c44cbSJon Lin 743cf3c44cbSJon Lin static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = { 744cf3c44cbSJon Lin /* pipe-phy-grf */ 745cf3c44cbSJon Lin .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, 746cf3c44cbSJon Lin .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, 747cf3c44cbSJon Lin .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, 748cf3c44cbSJon Lin .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, 749cf3c44cbSJon Lin .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, 750cf3c44cbSJon Lin .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, 751cf3c44cbSJon Lin .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, 752cf3c44cbSJon Lin .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, 753cf3c44cbSJon Lin .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, 754cf3c44cbSJon Lin .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, 755cf3c44cbSJon Lin .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, 756cf3c44cbSJon Lin .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, 757cf3c44cbSJon Lin .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, 758cf3c44cbSJon Lin .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, 759cf3c44cbSJon Lin .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, 760cf3c44cbSJon Lin .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, 761cf3c44cbSJon Lin .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, 762418dd88dSYifeng Zhao .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, 763cf3c44cbSJon Lin .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, 764cf3c44cbSJon Lin .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, 765cf3c44cbSJon Lin /* pipe-grf */ 766cf3c44cbSJon Lin .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, 767cf3c44cbSJon Lin .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, 768cf3c44cbSJon Lin }; 769cf3c44cbSJon Lin 770cf3c44cbSJon Lin static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { 771cf3c44cbSJon Lin .grfcfg = &rk3588_combphy_grfcfgs, 772cf3c44cbSJon Lin .combphy_cfg = rk3588_combphy_cfg, 773cf3c44cbSJon Lin }; 774cf3c44cbSJon Lin 775925c5749SYifeng Zhao static const struct udevice_id rockchip_combphy_ids[] = { 776925c5749SYifeng Zhao { 7773452d642SJianwei Zheng .compatible = "rockchip,rk3528-naneng-combphy", 7783452d642SJianwei Zheng .data = (ulong)&rk3528_combphy_cfgs 7793452d642SJianwei Zheng }, 7803452d642SJianwei Zheng { 781885c5d5dSFrank Wang .compatible = "rockchip,rk3562-naneng-combphy", 782885c5d5dSFrank Wang .data = (ulong)&rk3562_combphy_cfgs 783885c5d5dSFrank Wang }, 784885c5d5dSFrank Wang { 785925c5749SYifeng Zhao .compatible = "rockchip,rk3568-naneng-combphy", 786925c5749SYifeng Zhao .data = (ulong)&rk3568_combphy_cfgs 787925c5749SYifeng Zhao }, 788cf3c44cbSJon Lin { 789cf3c44cbSJon Lin .compatible = "rockchip,rk3588-naneng-combphy", 790cf3c44cbSJon Lin .data = (ulong)&rk3588_combphy_cfgs 791cf3c44cbSJon Lin }, 792925c5749SYifeng Zhao { } 793925c5749SYifeng Zhao }; 794925c5749SYifeng Zhao 795925c5749SYifeng Zhao U_BOOT_DRIVER(rockchip_naneng_combphy) = { 796925c5749SYifeng Zhao .name = "naneng-combphy", 797925c5749SYifeng Zhao .id = UCLASS_PHY, 798925c5749SYifeng Zhao .of_match = rockchip_combphy_ids, 799925c5749SYifeng Zhao .ops = &rochchip_combphy_ops, 800925c5749SYifeng Zhao .probe = rockchip_combphy_probe, 801925c5749SYifeng Zhao .priv_auto_alloc_size = sizeof(struct rockchip_combphy_priv), 802925c5749SYifeng Zhao }; 803