File Index
Files and directories
Sign in
FILE

phy-rockchip-naneng-combphy.c

File preview with syntax highlighting.

linux-6.19.14/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver
   4 *
   5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
   6 */
   7
   8#include <dt-bindings/phy/phy.h>
   9#include <linux/clk.h>
  10#include <linux/mfd/syscon.h>
  11#include <linux/of.h>
  12#include <linux/phy/phy.h>
  13#include <linux/platform_device.h>
  14#include <linux/regmap.h>
  15#include <linux/reset.h>
  16#include <linux/units.h>
  17
  18#define BIT_WRITEABLE_SHIFT		16
  19#define REF_CLOCK_24MHz			(24 * HZ_PER_MHZ)
  20#define REF_CLOCK_25MHz			(25 * HZ_PER_MHZ)
  21#define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
  22
  23/* RK3528 COMBO PHY REG */
  24#define RK3528_PHYREG5				0x14
  25#define RK3528_PHYREG5_GATE_TX_PCK_SEL		BIT(3)
  26#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF	BIT(3)
  27#define RK3528_PHYREG6				0x18
  28#define RK3528_PHYREG6_PLL_KVCO			GENMASK(12, 10)
  29#define RK3528_PHYREG6_PLL_KVCO_VALUE		0x2
  30#define RK3528_PHYREG6_SSC_DIR			GENMASK(5, 4)
  31#define RK3528_PHYREG6_SSC_UPWARD		0
  32#define RK3528_PHYREG6_SSC_DOWNWARD		1
  33
  34#define RK3528_PHYREG40				0x100
  35#define RK3528_PHYREG40_SSC_EN			BIT(20)
  36#define RK3528_PHYREG40_SSC_CNT			GENMASK(10, 0)
  37#define RK3528_PHYREG40_SSC_CNT_VALUE		0x17d
  38
  39#define RK3528_PHYREG42				0x108
  40#define RK3528_PHYREG42_CKDRV_CLK_SEL		BIT(29)
  41#define RK3528_PHYREG42_CKDRV_CLK_PLL		0
  42#define RK3528_PHYREG42_CKDRV_CLK_CKRCV		1
  43#define RK3528_PHYREG42_PLL_LPF_R1_ADJ		GENMASK(10, 7)
  44#define RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE	0x9
  45#define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ	GENMASK(6, 4)
  46#define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE 0x7
  47#define RK3528_PHYREG42_PLL_KVCO_ADJ		GENMASK(2, 0)
  48#define RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE	0x0
  49
  50#define RK3528_PHYREG80				0x200
  51#define RK3528_PHYREG80_CTLE_EN			BIT(17)
  52
  53#define RK3528_PHYREG81				0x204
  54#define RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X	BIT(5)
  55#define RK3528_PHYREG81_SLEW_RATE_CTRL		GENMASK(2, 0)
  56#define RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW	0x7
  57
  58#define RK3528_PHYREG83				0x20c
  59#define RK3528_PHYREG83_RX_SQUELCH		GENMASK(2, 0)
  60#define RK3528_PHYREG83_RX_SQUELCH_VALUE	0x6
  61
  62#define RK3528_PHYREG86				0x218
  63#define RK3528_PHYREG86_RTERM_DET_CLK_EN	BIT(14)
  64
  65/* RK3568 COMBO PHY REG */
  66#define RK3568_PHYREG6				0x14
  67#define RK3568_PHYREG6_PLL_DIV_MASK		GENMASK(7, 6)
  68#define RK3568_PHYREG6_PLL_DIV_SHIFT		6
  69#define RK3568_PHYREG6_PLL_DIV_2		1
  70
  71#define RK3568_PHYREG7				0x18
  72#define RK3568_PHYREG7_TX_RTERM_MASK		GENMASK(7, 4)
  73#define RK3568_PHYREG7_TX_RTERM_SHIFT		4
  74#define RK3568_PHYREG7_TX_RTERM_50OHM		8
  75#define RK3568_PHYREG7_RX_RTERM_MASK		GENMASK(3, 0)
  76#define RK3568_PHYREG7_RX_RTERM_SHIFT		0
  77#define RK3568_PHYREG7_RX_RTERM_44OHM		15
  78
  79#define RK3568_PHYREG8				0x1C
  80#define RK3568_PHYREG8_SSC_EN			BIT(4)
  81
  82#define RK3568_PHYREG11				0x28
  83#define RK3568_PHYREG11_SU_TRIM_0_7		0xF0
  84
  85#define RK3568_PHYREG12				0x2C
  86#define RK3568_PHYREG12_PLL_LPF_ADJ_VALUE	4
  87
  88#define RK3568_PHYREG13				0x30
  89#define RK3568_PHYREG13_RESISTER_MASK		GENMASK(5, 4)
  90#define RK3568_PHYREG13_RESISTER_SHIFT		0x4
  91#define RK3568_PHYREG13_RESISTER_HIGH_Z		3
  92#define RK3568_PHYREG13_CKRCV_AMP0		BIT(7)
  93
  94#define RK3568_PHYREG14				0x34
  95#define RK3568_PHYREG14_CKRCV_AMP1		BIT(0)
  96
  97#define RK3568_PHYREG15				0x38
  98#define RK3568_PHYREG15_CTLE_EN			BIT(0)
  99#define RK3568_PHYREG15_SSC_CNT_MASK		GENMASK(7, 6)
 100#define RK3568_PHYREG15_SSC_CNT_SHIFT		6
 101#define RK3568_PHYREG15_SSC_CNT_VALUE		1
 102
 103#define RK3568_PHYREG16				0x3C
 104#define RK3568_PHYREG16_SSC_CNT_VALUE		0x5f
 105
 106#define RK3568_PHYREG18				0x44
 107#define RK3568_PHYREG18_PLL_LOOP		0x32
 108
 109#define RK3568_PHYREG30				0x74
 110#define RK3568_PHYREG30_GATE_TX_PCK_SEL         BIT(7)
 111#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7)
 112
 113#define RK3568_PHYREG32				0x7C
 114#define RK3568_PHYREG32_SSC_MASK		GENMASK(7, 4)
 115#define RK3568_PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
 116#define RK3568_PHYREG32_SSC_DIR_SHIFT		4
 117#define RK3568_PHYREG32_SSC_UPWARD		0
 118#define RK3568_PHYREG32_SSC_DOWNWARD		1
 119#define RK3568_PHYREG32_SSC_OFFSET_MASK	GENMASK(7, 6)
 120#define RK3568_PHYREG32_SSC_OFFSET_SHIFT	6
 121#define RK3568_PHYREG32_SSC_OFFSET_500PPM	1
 122
 123#define RK3568_PHYREG33				0x80
 124#define RK3568_PHYREG33_PLL_KVCO_MASK		GENMASK(4, 2)
 125#define RK3568_PHYREG33_PLL_KVCO_SHIFT		2
 126#define RK3568_PHYREG33_PLL_KVCO_VALUE		2
 127#define RK3576_PHYREG33_PLL_KVCO_VALUE		4
 128
 129/* RK3588 COMBO PHY registers */
 130#define RK3588_PHYREG27				0x6C
 131#define RK3588_PHYREG27_RX_TRIM			0x4C
 132
 133/* RK3576 COMBO PHY registers */
 134#define RK3576_PHYREG10				0x24
 135#define RK3576_PHYREG10_SSC_PCM_MASK		GENMASK(3, 0)
 136#define RK3576_PHYREG10_SSC_PCM_3500PPM		7
 137
 138#define RK3576_PHYREG17				0x40
 139
 140#define RK3576_PHYREG21				0x50
 141#define RK3576_PHYREG21_RX_SQUELCH_VAL		0x0D
 142
 143#define RK3576_PHYREG30				0x74
 144
 145struct rockchip_combphy_priv;
 146
 147struct combphy_reg {
 148	u16 offset;
 149	u16 bitend;
 150	u16 bitstart;
 151	u16 disable;
 152	u16 enable;
 153};
 154
 155struct rockchip_combphy_grfcfg {
 156	struct combphy_reg pcie_mode_set;
 157	struct combphy_reg usb_mode_set;
 158	struct combphy_reg sgmii_mode_set;
 159	struct combphy_reg qsgmii_mode_set;
 160	struct combphy_reg pipe_rxterm_set;
 161	struct combphy_reg pipe_txelec_set;
 162	struct combphy_reg pipe_txcomp_set;
 163	struct combphy_reg pipe_clk_24m;
 164	struct combphy_reg pipe_clk_25m;
 165	struct combphy_reg pipe_clk_100m;
 166	struct combphy_reg pipe_phymode_sel;
 167	struct combphy_reg pipe_rate_sel;
 168	struct combphy_reg pipe_rxterm_sel;
 169	struct combphy_reg pipe_txelec_sel;
 170	struct combphy_reg pipe_txcomp_sel;
 171	struct combphy_reg pipe_clk_ext;
 172	struct combphy_reg pipe_sel_usb;
 173	struct combphy_reg pipe_sel_qsgmii;
 174	struct combphy_reg pipe_phy_status;
 175	struct combphy_reg con0_for_pcie;
 176	struct combphy_reg con1_for_pcie;
 177	struct combphy_reg con2_for_pcie;
 178	struct combphy_reg con3_for_pcie;
 179	struct combphy_reg con0_for_sata;
 180	struct combphy_reg con1_for_sata;
 181	struct combphy_reg con2_for_sata;
 182	struct combphy_reg con3_for_sata;
 183	struct combphy_reg pipe_con0_for_sata;
 184	struct combphy_reg pipe_con1_for_sata;
 185	struct combphy_reg pipe_xpcs_phy_ready;
 186	struct combphy_reg pipe_pcie1l0_sel;
 187	struct combphy_reg pipe_pcie1l1_sel;
 188	struct combphy_reg u3otg0_port_en;
 189	struct combphy_reg u3otg1_port_en;
 190};
 191
 192struct rockchip_combphy_cfg {
 193	unsigned int num_phys;
 194	unsigned int phy_ids[3];
 195	const struct rockchip_combphy_grfcfg *grfcfg;
 196	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
 197};
 198
 199struct rockchip_combphy_priv {
 200	u8 type;
 201	int id;
 202	void __iomem *mmio;
 203	int num_clks;
 204	struct clk_bulk_data *clks;
 205	struct device *dev;
 206	struct regmap *pipe_grf;
 207	struct regmap *phy_grf;
 208	struct phy *phy;
 209	struct reset_control *phy_rst;
 210	const struct rockchip_combphy_cfg *cfg;
 211	bool enable_ssc;
 212	bool ext_refclk;
 213	struct clk *refclk;
 214};
 215
 216static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,
 217				     int mask, int val, int reg)
 218{
 219	unsigned int temp;
 220
 221	temp = readl(priv->mmio + reg);
 222	temp = (temp & ~(mask)) | val;
 223	writel(temp, priv->mmio + reg);
 224}
 225
 226static int rockchip_combphy_param_write(struct regmap *base,
 227					const struct combphy_reg *reg, bool en)
 228{
 229	u32 val, mask, tmp;
 230
 231	tmp = en ? reg->enable : reg->disable;
 232	mask = GENMASK(reg->bitend, reg->bitstart);
 233	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
 234
 235	return regmap_write(base, reg->offset, val);
 236}
 237
 238static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
 239{
 240	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 241	u32 mask, val;
 242
 243	mask = GENMASK(cfg->pipe_phy_status.bitend,
 244		       cfg->pipe_phy_status.bitstart);
 245
 246	regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
 247	val = (val & mask) >> cfg->pipe_phy_status.bitstart;
 248
 249	return val;
 250}
 251
 252static int rockchip_combphy_init(struct phy *phy)
 253{
 254	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
 255	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 256	u32 val;
 257	int ret;
 258
 259	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
 260	if (ret) {
 261		dev_err(priv->dev, "failed to enable clks\n");
 262		return ret;
 263	}
 264
 265	switch (priv->type) {
 266	case PHY_TYPE_PCIE:
 267	case PHY_TYPE_USB3:
 268	case PHY_TYPE_SATA:
 269	case PHY_TYPE_SGMII:
 270	case PHY_TYPE_QSGMII:
 271		if (priv->cfg->combphy_cfg)
 272			ret = priv->cfg->combphy_cfg(priv);
 273		break;
 274	default:
 275		dev_err(priv->dev, "incompatible PHY type\n");
 276		ret = -EINVAL;
 277		break;
 278	}
 279
 280	if (ret) {
 281		dev_err(priv->dev, "failed to init phy for phy type %x\n", priv->type);
 282		goto err_clk;
 283	}
 284
 285	ret = reset_control_deassert(priv->phy_rst);
 286	if (ret)
 287		goto err_clk;
 288
 289	if (priv->type == PHY_TYPE_USB3) {
 290		ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready,
 291						priv, val,
 292						val == cfg->pipe_phy_status.enable,
 293						10, 1000);
 294		if (ret)
 295			dev_warn(priv->dev, "wait phy status ready timeout\n");
 296	}
 297
 298	return 0;
 299
 300err_clk:
 301	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
 302
 303	return ret;
 304}
 305
 306static int rockchip_combphy_exit(struct phy *phy)
 307{
 308	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
 309
 310	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
 311	reset_control_assert(priv->phy_rst);
 312
 313	return 0;
 314}
 315
 316static const struct phy_ops rockchip_combphy_ops = {
 317	.init = rockchip_combphy_init,
 318	.exit = rockchip_combphy_exit,
 319	.owner = THIS_MODULE,
 320};
 321
 322static struct phy *rockchip_combphy_xlate(struct device *dev, const struct of_phandle_args *args)
 323{
 324	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
 325
 326	if (args->args_count != 1) {
 327		dev_err(dev, "invalid number of arguments\n");
 328		return ERR_PTR(-EINVAL);
 329	}
 330
 331	if (priv->type != PHY_NONE && priv->type != args->args[0])
 332		dev_warn(dev, "phy type select %d overwriting type %d\n",
 333			 args->args[0], priv->type);
 334
 335	priv->type = args->args[0];
 336
 337	return priv->phy;
 338}
 339
 340static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv)
 341{
 342	int i;
 343
 344	priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
 345	if (priv->num_clks < 1)
 346		return -EINVAL;
 347
 348	priv->refclk = NULL;
 349	for (i = 0; i < priv->num_clks; i++) {
 350		if (!strncmp(priv->clks[i].id, "ref", 3)) {
 351			priv->refclk = priv->clks[i].clk;
 352			break;
 353		}
 354	}
 355
 356	if (!priv->refclk) {
 357		dev_err(dev, "no refclk found\n");
 358		return -EINVAL;
 359	}
 360
 361	priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf");
 362	if (IS_ERR(priv->pipe_grf)) {
 363		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
 364		return PTR_ERR(priv->pipe_grf);
 365	}
 366
 367	priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf");
 368	if (IS_ERR(priv->phy_grf)) {
 369		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
 370		return PTR_ERR(priv->phy_grf);
 371	}
 372
 373	priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc");
 374
 375	priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
 376
 377	priv->phy_rst = devm_reset_control_get_exclusive(dev, "phy");
 378	/* fallback to old behaviour */
 379	if (PTR_ERR(priv->phy_rst) == -ENOENT)
 380		priv->phy_rst = devm_reset_control_array_get_exclusive(dev);
 381	if (IS_ERR(priv->phy_rst))
 382		return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n");
 383
 384	return 0;
 385}
 386
 387static int rockchip_combphy_probe(struct platform_device *pdev)
 388{
 389	struct phy_provider *phy_provider;
 390	struct device *dev = &pdev->dev;
 391	struct rockchip_combphy_priv *priv;
 392	const struct rockchip_combphy_cfg *phy_cfg;
 393	struct resource *res;
 394	int ret, id;
 395
 396	phy_cfg = of_device_get_match_data(dev);
 397	if (!phy_cfg) {
 398		dev_err(dev, "no OF match data provided\n");
 399		return -EINVAL;
 400	}
 401
 402	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 403	if (!priv)
 404		return -ENOMEM;
 405
 406	priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 407	if (IS_ERR(priv->mmio)) {
 408		ret = PTR_ERR(priv->mmio);
 409		return ret;
 410	}
 411
 412	/* find the phy-id from the io address */
 413	priv->id = -ENODEV;
 414	for (id = 0; id < phy_cfg->num_phys; id++) {
 415		if (res->start == phy_cfg->phy_ids[id]) {
 416			priv->id = id;
 417			break;
 418		}
 419	}
 420
 421	priv->dev = dev;
 422	priv->type = PHY_NONE;
 423	priv->cfg = phy_cfg;
 424
 425	ret = rockchip_combphy_parse_dt(dev, priv);
 426	if (ret)
 427		return ret;
 428
 429	ret = reset_control_assert(priv->phy_rst);
 430	if (ret) {
 431		dev_err(dev, "failed to reset phy\n");
 432		return ret;
 433	}
 434
 435	priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
 436	if (IS_ERR(priv->phy)) {
 437		dev_err(dev, "failed to create combphy\n");
 438		return PTR_ERR(priv->phy);
 439	}
 440
 441	dev_set_drvdata(dev, priv);
 442	phy_set_drvdata(priv->phy, priv);
 443
 444	phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate);
 445
 446	return PTR_ERR_OR_ZERO(phy_provider);
 447}
 448
 449static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
 450{
 451	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 452	unsigned long rate;
 453	u32 val;
 454
 455	/* Set SSC downward spread spectrum */
 456	val = FIELD_PREP(RK3528_PHYREG6_SSC_DIR, RK3528_PHYREG6_SSC_DOWNWARD);
 457	rockchip_combphy_updatel(priv, RK3528_PHYREG6_SSC_DIR, val, RK3528_PHYREG6);
 458
 459	switch (priv->type) {
 460	case PHY_TYPE_PCIE:
 461		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
 462		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
 463		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
 464		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
 465		break;
 466	case PHY_TYPE_USB3:
 467		/* Enable adaptive CTLE for USB3.0 Rx */
 468		rockchip_combphy_updatel(priv, RK3528_PHYREG80_CTLE_EN, RK3528_PHYREG80_CTLE_EN,
 469					 RK3528_PHYREG80);
 470
 471		/* Set slow slew rate control for PI */
 472		val = FIELD_PREP(RK3528_PHYREG81_SLEW_RATE_CTRL,
 473				 RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW);
 474		rockchip_combphy_updatel(priv, RK3528_PHYREG81_SLEW_RATE_CTRL, val,
 475					 RK3528_PHYREG81);
 476
 477		/* Set CDR phase path with 2x gain */
 478		rockchip_combphy_updatel(priv, RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X,
 479					 RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X, RK3528_PHYREG81);
 480
 481		/* Set Rx squelch input filler bandwidth */
 482		val = FIELD_PREP(RK3528_PHYREG83_RX_SQUELCH, RK3528_PHYREG83_RX_SQUELCH_VALUE);
 483		rockchip_combphy_updatel(priv, RK3528_PHYREG83_RX_SQUELCH, val, RK3528_PHYREG83);
 484
 485		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
 486		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
 487		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
 488		rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true);
 489		break;
 490	default:
 491		dev_err(priv->dev, "incompatible PHY type\n");
 492		return -EINVAL;
 493	}
 494
 495	rate = clk_get_rate(priv->refclk);
 496
 497	switch (rate) {
 498	case REF_CLOCK_24MHz:
 499		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
 500		if (priv->type == PHY_TYPE_USB3) {
 501			/* Set ssc_cnt[10:0]=00101111101 & 31.5KHz */
 502			val = FIELD_PREP(RK3528_PHYREG40_SSC_CNT, RK3528_PHYREG40_SSC_CNT_VALUE);
 503			rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_CNT, val,
 504						 RK3528_PHYREG40);
 505		} else if (priv->type == PHY_TYPE_PCIE) {
 506			/* tx_trim[14]=1, Enable the counting clock of the rterm detect */
 507			rockchip_combphy_updatel(priv, RK3528_PHYREG86_RTERM_DET_CLK_EN,
 508						 RK3528_PHYREG86_RTERM_DET_CLK_EN, RK3528_PHYREG86);
 509		}
 510		break;
 511	case REF_CLOCK_100MHz:
 512		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 513		if (priv->type == PHY_TYPE_PCIE) {
 514			/* Gate_tx_pck_sel length select for L1ss support */
 515			rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL,
 516						 RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, RK3528_PHYREG5);
 517
 518			/* PLL KVCO tuning fine */
 519			val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE);
 520			rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val,
 521						 RK3528_PHYREG6);
 522
 523			/* su_trim[6:4]=111, [10:7]=1001, [2:0]=000, swing 650mv */
 524			writel(0x570804f0, priv->mmio + RK3528_PHYREG42);
 525		}
 526		break;
 527	default:
 528		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
 529		return -EINVAL;
 530	}
 531
 532	if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) {
 533		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
 534
 535		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
 536			val = FIELD_PREP(RK3528_PHYREG42_CKDRV_CLK_SEL,
 537					 RK3528_PHYREG42_CKDRV_CLK_CKRCV);
 538			val |= FIELD_PREP(RK3528_PHYREG42_PLL_LPF_R1_ADJ,
 539					  RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE);
 540			val |= FIELD_PREP(RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ,
 541					  RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE);
 542			val |= FIELD_PREP(RK3528_PHYREG42_PLL_KVCO_ADJ,
 543					  RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE);
 544			rockchip_combphy_updatel(priv,
 545						 RK3528_PHYREG42_CKDRV_CLK_SEL		|
 546						 RK3528_PHYREG42_PLL_LPF_R1_ADJ		|
 547						 RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ	|
 548						 RK3528_PHYREG42_PLL_KVCO_ADJ,
 549						 val, RK3528_PHYREG42);
 550
 551			val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE);
 552			rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val,
 553						 RK3528_PHYREG6);
 554		}
 555	}
 556
 557	if (priv->type == PHY_TYPE_PCIE) {
 558		if (device_property_read_bool(priv->dev, "rockchip,enable-ssc"))
 559			rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN,
 560						 RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40);
 561	}
 562
 563	return 0;
 564}
 565
 566static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = {
 567	/* pipe-phy-grf */
 568	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
 569	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
 570	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
 571	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
 572	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
 573	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
 574	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
 575	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
 576	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
 577	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
 578	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
 579	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
 580	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x110 },
 581	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x00 },
 582	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x101 },
 583	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
 584	/* pipe-grf */
 585	.u3otg0_port_en         = { 0x0044, 15, 0, 0x0181, 0x1100 },
 586};
 587
 588static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = {
 589	.num_phys	= 1,
 590	.phy_ids	= {
 591		0xffdc0000,
 592	},
 593	.grfcfg		= &rk3528_combphy_grfcfgs,
 594	.combphy_cfg	= rk3528_combphy_cfg,
 595};
 596
 597static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
 598{
 599	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 600	unsigned long rate;
 601	u32 val;
 602
 603	switch (priv->type) {
 604	case PHY_TYPE_PCIE:
 605		/* Set SSC downward spread spectrum */
 606		val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
 607		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
 608
 609		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
 610		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
 611		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
 612		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
 613		break;
 614	case PHY_TYPE_USB3:
 615		/* Set SSC downward spread spectrum */
 616		val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
 617		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val,
 618					 RK3568_PHYREG32);
 619
 620		/* Enable adaptive CTLE for USB3.0 Rx */
 621		rockchip_combphy_updatel(priv, RK3568_PHYREG15_CTLE_EN,
 622					 RK3568_PHYREG15_CTLE_EN, RK3568_PHYREG15);
 623
 624		/* Set PLL KVCO fine tuning signals */
 625		rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
 626					 BIT(3), RK3568_PHYREG33);
 627
 628		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
 629		writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
 630
 631		/* Set PLL input clock divider 1/2 */
 632		val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2);
 633		rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6);
 634
 635		/* Set PLL loop divider */
 636		writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
 637
 638		/* Set PLL KVCO to min and set PLL charge pump current to max */
 639		writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
 640
 641		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
 642		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
 643		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
 644		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
 645		break;
 646	default:
 647		dev_err(priv->dev, "incompatible PHY type\n");
 648		return -EINVAL;
 649	}
 650
 651	rate = clk_get_rate(priv->refclk);
 652
 653	switch (rate) {
 654	case REF_CLOCK_24MHz:
 655		if (priv->type == PHY_TYPE_USB3) {
 656			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
 657			val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK,
 658					 RK3568_PHYREG15_SSC_CNT_VALUE);
 659			rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK,
 660						 val, RK3568_PHYREG15);
 661
 662			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
 663		}
 664		break;
 665	case REF_CLOCK_25MHz:
 666		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
 667		break;
 668	case REF_CLOCK_100MHz:
 669		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 670		if (priv->type == PHY_TYPE_PCIE) {
 671			/* Gate_tx_pck_sel length select for L1ss support */
 672			rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL,
 673						 RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF,
 674						 RK3568_PHYREG30);
 675			/* PLL KVCO tuning fine */
 676			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
 677					 RK3568_PHYREG33_PLL_KVCO_VALUE);
 678			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
 679						 val, RK3568_PHYREG33);
 680
 681			/* Enable controlling random jitter, aka RMJ */
 682			writel(0x4, priv->mmio + RK3568_PHYREG12);
 683
 684			val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT;
 685			rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK,
 686						 val, RK3568_PHYREG6);
 687
 688			writel(0x32, priv->mmio + RK3568_PHYREG18);
 689			writel(0xf0, priv->mmio + RK3568_PHYREG11);
 690		}
 691		break;
 692	default:
 693		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
 694		return -EINVAL;
 695	}
 696
 697	if (priv->ext_refclk) {
 698		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
 699		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
 700			val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT;
 701			val |= RK3568_PHYREG13_CKRCV_AMP0;
 702			rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val,
 703						 RK3568_PHYREG13);
 704
 705			val = readl(priv->mmio + RK3568_PHYREG14);
 706			val |= RK3568_PHYREG14_CKRCV_AMP1;
 707			writel(val, priv->mmio + RK3568_PHYREG14);
 708		}
 709	}
 710
 711	if (priv->enable_ssc) {
 712		val = readl(priv->mmio + RK3568_PHYREG8);
 713		val |= RK3568_PHYREG8_SSC_EN;
 714		writel(val, priv->mmio + RK3568_PHYREG8);
 715	}
 716
 717	return 0;
 718}
 719
 720static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = {
 721	/* pipe-phy-grf */
 722	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
 723	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
 724	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
 725	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
 726	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
 727	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
 728	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
 729	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
 730	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
 731	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
 732	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
 733	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
 734	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
 735	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
 736	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
 737	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
 738	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
 739	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
 740	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
 741};
 742
 743static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = {
 744	.num_phys = 1,
 745	.phy_ids = {
 746		0xff750000
 747	},
 748	.grfcfg		= &rk3562_combphy_grfcfgs,
 749	.combphy_cfg	= rk3562_combphy_cfg,
 750};
 751
 752static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
 753{
 754	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 755	unsigned long rate;
 756	u32 val;
 757
 758	switch (priv->type) {
 759	case PHY_TYPE_PCIE:
 760		/* Set SSC downward spread spectrum. */
 761		val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
 762
 763		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
 764
 765		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
 766		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
 767		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
 768		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
 769		break;
 770
 771	case PHY_TYPE_USB3:
 772		/* Set SSC downward spread spectrum. */
 773		val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT,
 774		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
 775
 776		/* Enable adaptive CTLE for USB3.0 Rx. */
 777		val = readl(priv->mmio + RK3568_PHYREG15);
 778		val |= RK3568_PHYREG15_CTLE_EN;
 779		writel(val, priv->mmio + RK3568_PHYREG15);
 780
 781		/* Set PLL KVCO fine tuning signals. */
 782		val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT;
 783		rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33);
 784
 785		/* Enable controlling random jitter. */
 786		writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
 787
 788		/* Set PLL input clock divider 1/2. */
 789		rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK,
 790					 RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT,
 791					 RK3568_PHYREG6);
 792
 793		writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
 794		writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
 795
 796		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
 797		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
 798		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
 799		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
 800		switch (priv->id) {
 801		case 0:
 802			rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true);
 803			break;
 804		case 1:
 805			rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg1_port_en, true);
 806			break;
 807		}
 808		break;
 809
 810	case PHY_TYPE_SATA:
 811		/* Enable adaptive CTLE for SATA Rx. */
 812		val = readl(priv->mmio + RK3568_PHYREG15);
 813		val |= RK3568_PHYREG15_CTLE_EN;
 814		writel(val, priv->mmio + RK3568_PHYREG15);
 815		/*
 816		 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
 817		 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
 818		 */
 819		val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT;
 820		val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT;
 821		writel(val, priv->mmio + RK3568_PHYREG7);
 822
 823		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
 824		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
 825		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
 826		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
 827		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
 828		break;
 829
 830	case PHY_TYPE_SGMII:
 831		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
 832		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
 833		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
 834		rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
 835		break;
 836
 837	case PHY_TYPE_QSGMII:
 838		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
 839		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
 840		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
 841		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
 842		rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
 843		break;
 844
 845	default:
 846		dev_err(priv->dev, "incompatible PHY type\n");
 847		return -EINVAL;
 848	}
 849
 850	rate = clk_get_rate(priv->refclk);
 851
 852	switch (rate) {
 853	case REF_CLOCK_24MHz:
 854		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
 855			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
 856			val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT;
 857			rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK,
 858						 val, RK3568_PHYREG15);
 859
 860			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
 861		}
 862		break;
 863
 864	case REF_CLOCK_25MHz:
 865		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
 866		break;
 867
 868	case REF_CLOCK_100MHz:
 869		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 870		if (priv->type == PHY_TYPE_PCIE) {
 871			/* PLL KVCO  fine tuning. */
 872			val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT;
 873			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
 874						 val, RK3568_PHYREG33);
 875
 876			/* Enable controlling random jitter. */
 877			writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
 878
 879			val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT;
 880			rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK,
 881						 val, RK3568_PHYREG6);
 882
 883			writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
 884			writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
 885		} else if (priv->type == PHY_TYPE_SATA) {
 886			/* downward spread spectrum +500ppm */
 887			val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
 888			val |= RK3568_PHYREG32_SSC_OFFSET_500PPM <<
 889			       RK3568_PHYREG32_SSC_OFFSET_SHIFT;
 890			rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val,
 891						 RK3568_PHYREG32);
 892		}
 893		break;
 894
 895	default:
 896		dev_err(priv->dev, "unsupported rate: %lu\n", rate);
 897		return -EINVAL;
 898	}
 899
 900	if (priv->ext_refclk) {
 901		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
 902		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
 903			val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT;
 904			val |= RK3568_PHYREG13_CKRCV_AMP0;
 905			rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val,
 906						 RK3568_PHYREG13);
 907
 908			val = readl(priv->mmio + RK3568_PHYREG14);
 909			val |= RK3568_PHYREG14_CKRCV_AMP1;
 910			writel(val, priv->mmio + RK3568_PHYREG14);
 911		}
 912	}
 913
 914	if (priv->enable_ssc) {
 915		val = readl(priv->mmio + RK3568_PHYREG8);
 916		val |= RK3568_PHYREG8_SSC_EN;
 917		writel(val, priv->mmio + RK3568_PHYREG8);
 918	}
 919
 920	return 0;
 921}
 922
 923static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
 924	/* pipe-phy-grf */
 925	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
 926	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
 927	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
 928	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
 929	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
 930	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
 931	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
 932	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
 933	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
 934	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
 935	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
 936	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
 937	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
 938	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
 939	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
 940	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
 941	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
 942	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
 943	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
 944	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
 945	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
 946	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
 947	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
 948	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
 949	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
 950	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
 951	/* pipe-grf */
 952	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
 953	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
 954	.u3otg0_port_en		= { 0x0104, 15, 0, 0x0181, 0x1100 },
 955	.u3otg1_port_en		= { 0x0144, 15, 0, 0x0181, 0x1100 },
 956};
 957
 958static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
 959	.num_phys = 3,
 960	.phy_ids = {
 961		0xfe820000,
 962		0xfe830000,
 963		0xfe840000,
 964	},
 965	.grfcfg		= &rk3568_combphy_grfcfgs,
 966	.combphy_cfg	= rk3568_combphy_cfg,
 967};
 968
 969static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
 970{
 971	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
 972	unsigned long rate;
 973	u32 val;
 974
 975	switch (priv->type) {
 976	case PHY_TYPE_PCIE:
 977		/* Set SSC downward spread spectrum */
 978		val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD);
 979		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
 980
 981		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
 982		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
 983		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
 984		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
 985		break;
 986
 987	case PHY_TYPE_USB3:
 988		/* Set SSC downward spread spectrum */
 989		val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD);
 990		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
 991
 992		/* Enable adaptive CTLE for USB3.0 Rx */
 993		val = readl(priv->mmio + RK3568_PHYREG15);
 994		val |= RK3568_PHYREG15_CTLE_EN;
 995		writel(val, priv->mmio + RK3568_PHYREG15);
 996
 997		/* Set PLL KVCO fine tuning signals */
 998		rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, BIT(3),
 999					 RK3568_PHYREG33);
1000
1001		/* Set PLL LPF R1 to su_trim[10:7]=1001 */
1002		writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
1003
1004		/* Set PLL input clock divider 1/2 */
1005		val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2);
1006		rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6);
1007
1008		/* Set PLL loop divider */
1009		writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
1010
1011		/* Set PLL KVCO to min and set PLL charge pump current to max */
1012		writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
1013
1014		/* Set Rx squelch input filler bandwidth */
1015		writel(RK3576_PHYREG21_RX_SQUELCH_VAL, priv->mmio + RK3576_PHYREG21);
1016
1017		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
1018		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
1019		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
1020		break;
1021
1022	case PHY_TYPE_SATA:
1023		/* Enable adaptive CTLE for SATA Rx */
1024		val = readl(priv->mmio + RK3568_PHYREG15);
1025		val |= RK3568_PHYREG15_CTLE_EN;
1026		writel(val, priv->mmio + RK3568_PHYREG15);
1027
1028		/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
1029		val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT;
1030		val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT;
1031		writel(val, priv->mmio + RK3568_PHYREG7);
1032
1033		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
1034		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
1035		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
1036		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
1037		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
1038		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
1039		break;
1040
1041	default:
1042		dev_err(priv->dev, "incompatible PHY type\n");
1043		return -EINVAL;
1044	}
1045
1046	rate = clk_get_rate(priv->refclk);
1047
1048	switch (rate) {
1049	case REF_CLOCK_24MHz:
1050		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
1051		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
1052			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
1053			val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK,
1054					 RK3568_PHYREG15_SSC_CNT_VALUE);
1055			rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK,
1056						 val, RK3568_PHYREG15);
1057
1058			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
1059		} else if (priv->type == PHY_TYPE_PCIE) {
1060			/* PLL KVCO tuning fine */
1061			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
1062					 RK3576_PHYREG33_PLL_KVCO_VALUE);
1063			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
1064						 val, RK3568_PHYREG33);
1065
1066			/* Set up rx_pck invert and rx msb to disable */
1067			writel(0x00, priv->mmio + RK3588_PHYREG27);
1068
1069			/*
1070			 * Set up SU adjust signal:
1071			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
1072			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b011
1073			 * su_trim[31:24], CKDRV adjust
1074			 */
1075			writel(0x90, priv->mmio + RK3568_PHYREG11);
1076			writel(0x02, priv->mmio + RK3568_PHYREG12);
1077			writel(0x57, priv->mmio + RK3568_PHYREG14);
1078
1079			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
1080		}
1081		break;
1082
1083	case REF_CLOCK_25MHz:
1084		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
1085		break;
1086
1087	case REF_CLOCK_100MHz:
1088		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
1089		if (priv->type == PHY_TYPE_PCIE) {
1090			/* gate_tx_pck_sel length select work for L1SS */
1091			writel(0xc0, priv->mmio + RK3576_PHYREG30);
1092
1093			/* PLL KVCO tuning fine */
1094			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
1095					 RK3576_PHYREG33_PLL_KVCO_VALUE);
1096			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
1097						 val, RK3568_PHYREG33);
1098
1099			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
1100			writel(0x4c, priv->mmio + RK3588_PHYREG27);
1101
1102			/*
1103			 * Set up SU adjust signal:
1104			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
1105			 * su_trim[15:8],  bypass PLL loop divider code, and
1106			 *                 PLL LPF R1 adujst bits[9:7]=3'b101
1107			 * su_trim[23:16], CKRCV adjust
1108			 * su_trim[31:24], CKDRV adjust
1109			 */
1110			writel(0x90, priv->mmio + RK3568_PHYREG11);
1111			writel(0x43, priv->mmio + RK3568_PHYREG12);
1112			writel(0x88, priv->mmio + RK3568_PHYREG13);
1113			writel(0x56, priv->mmio + RK3568_PHYREG14);
1114		} else if (priv->type == PHY_TYPE_SATA) {
1115			/* downward spread spectrum +500ppm */
1116			val = FIELD_PREP(RK3568_PHYREG32_SSC_DIR_MASK,
1117					 RK3568_PHYREG32_SSC_DOWNWARD);
1118			val |= FIELD_PREP(RK3568_PHYREG32_SSC_OFFSET_MASK,
1119					  RK3568_PHYREG32_SSC_OFFSET_500PPM);
1120			rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val,
1121						 RK3568_PHYREG32);
1122
1123			/* ssc ppm adjust to 3500ppm */
1124			rockchip_combphy_updatel(priv, RK3576_PHYREG10_SSC_PCM_MASK,
1125						 RK3576_PHYREG10_SSC_PCM_3500PPM,
1126						 RK3576_PHYREG10);
1127		}
1128		break;
1129
1130	default:
1131		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
1132		return -EINVAL;
1133	}
1134
1135	if (priv->ext_refclk) {
1136		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
1137		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
1138			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
1139					 RK3576_PHYREG33_PLL_KVCO_VALUE);
1140			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
1141						 val, RK3568_PHYREG33);
1142
1143			/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
1144			writel(0x0c, priv->mmio + RK3588_PHYREG27);
1145
1146			/*
1147			 * Set up SU adjust signal:
1148			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
1149			 * su_trim[15:8],  bypass PLL loop divider code, and
1150			 *                 PLL LPF R1 adujst bits[9:7]=3'b101.
1151			 * su_trim[23:16], CKRCV adjust
1152			 * su_trim[31:24], CKDRV adjust
1153			 */
1154			writel(0x90, priv->mmio + RK3568_PHYREG11);
1155			writel(0x43, priv->mmio + RK3568_PHYREG12);
1156			writel(0x88, priv->mmio + RK3568_PHYREG13);
1157			writel(0x56, priv->mmio + RK3568_PHYREG14);
1158		}
1159	}
1160
1161	if (priv->enable_ssc) {
1162		val = readl(priv->mmio + RK3568_PHYREG8);
1163		val |= RK3568_PHYREG8_SSC_EN;
1164		writel(val, priv->mmio + RK3568_PHYREG8);
1165
1166		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
1167			/* Set PLL loop divider */
1168			writel(0x00, priv->mmio + RK3576_PHYREG17);
1169			writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
1170
1171			/* Set up rx_pck invert and rx msb to disable */
1172			writel(0x00, priv->mmio + RK3588_PHYREG27);
1173
1174			/*
1175			 * Set up SU adjust signal:
1176			 * su_trim[7:0],   PLL KVCO adjust bits[2:0] to min
1177			 * su_trim[15:8],  PLL LPF R1 adujst bits[9:7]=3'b101
1178			 * su_trim[23:16], CKRCV adjust
1179			 * su_trim[31:24], CKDRV adjust
1180			 */
1181			writel(0x90, priv->mmio + RK3568_PHYREG11);
1182			writel(0x02, priv->mmio + RK3568_PHYREG12);
1183			writel(0x08, priv->mmio + RK3568_PHYREG13);
1184			writel(0x57, priv->mmio + RK3568_PHYREG14);
1185			writel(0x40, priv->mmio + RK3568_PHYREG15);
1186
1187			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
1188
1189			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
1190					 RK3576_PHYREG33_PLL_KVCO_VALUE);
1191			writel(val, priv->mmio + RK3568_PHYREG33);
1192		}
1193	}
1194
1195	return 0;
1196}
1197
1198static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
1199	/* pipe-phy-grf */
1200	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
1201	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
1202	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
1203	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
1204	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
1205	.pipe_clk_24m		= { 0x0004, 14, 13, 0x00, 0x00 },
1206	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
1207	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
1208	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
1209	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
1210	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
1211	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
1212	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
1213	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
1214	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
1215	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
1216	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
1217	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
1218	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
1219	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
1220	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
1221	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
1222	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
1223	/* php-grf */
1224	.pipe_con0_for_sata	= { 0x001C, 2, 0, 0x00, 0x2 },
1225	.pipe_con1_for_sata	= { 0x0020, 2, 0, 0x00, 0x2 },
1226};
1227
1228static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
1229	.num_phys = 2,
1230	.phy_ids = {
1231		0x2b050000,
1232		0x2b060000
1233	},
1234	.grfcfg		= &rk3576_combphy_grfcfgs,
1235	.combphy_cfg	= rk3576_combphy_cfg,
1236};
1237
1238static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
1239{
1240	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
1241	unsigned long rate;
1242	u32 val;
1243
1244	switch (priv->type) {
1245	case PHY_TYPE_PCIE:
1246		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
1247		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
1248		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
1249		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
1250		switch (priv->id) {
1251		case 1:
1252			rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true);
1253			break;
1254		case 2:
1255			rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true);
1256			break;
1257		}
1258		break;
1259	case PHY_TYPE_USB3:
1260		/* Set SSC downward spread spectrum */
1261		val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
1262		rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32);
1263
1264		/* Enable adaptive CTLE for USB3.0 Rx. */
1265		val = readl(priv->mmio + RK3568_PHYREG15);
1266		val |= RK3568_PHYREG15_CTLE_EN;
1267		writel(val, priv->mmio + RK3568_PHYREG15);
1268
1269		/* Set PLL KVCO fine tuning signals. */
1270		val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT;
1271		rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33);
1272
1273		/* Enable controlling random jitter. */
1274		writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
1275
1276		/* Set PLL input clock divider 1/2. */
1277		rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK,
1278					 RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT,
1279					 RK3568_PHYREG6);
1280
1281		writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18);
1282		writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
1283
1284		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
1285		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
1286		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
1287		break;
1288	case PHY_TYPE_SATA:
1289		/* Enable adaptive CTLE for SATA Rx. */
1290		val = readl(priv->mmio + RK3568_PHYREG15);
1291		val |= RK3568_PHYREG15_CTLE_EN;
1292		writel(val, priv->mmio + RK3568_PHYREG15);
1293		/*
1294		 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
1295		 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
1296		 */
1297		val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT;
1298		val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT;
1299		writel(val, priv->mmio + RK3568_PHYREG7);
1300
1301		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
1302		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
1303		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
1304		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
1305		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
1306		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
1307		break;
1308	case PHY_TYPE_SGMII:
1309	case PHY_TYPE_QSGMII:
1310	default:
1311		dev_err(priv->dev, "incompatible PHY type\n");
1312		return -EINVAL;
1313	}
1314
1315	rate = clk_get_rate(priv->refclk);
1316
1317	switch (rate) {
1318	case REF_CLOCK_24MHz:
1319		if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
1320			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
1321			val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT;
1322			rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK,
1323						 val, RK3568_PHYREG15);
1324
1325			writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16);
1326		}
1327		break;
1328
1329	case REF_CLOCK_25MHz:
1330		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
1331		break;
1332	case REF_CLOCK_100MHz:
1333		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
1334		if (priv->type == PHY_TYPE_PCIE) {
1335			/* PLL KVCO fine tuning. */
1336			val = 4 << RK3568_PHYREG33_PLL_KVCO_SHIFT;
1337			rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK,
1338						 val, RK3568_PHYREG33);
1339
1340			/* Enable controlling random jitter. */
1341			writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12);
1342
1343			/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
1344			writel(RK3588_PHYREG27_RX_TRIM, priv->mmio + RK3588_PHYREG27);
1345
1346			/* Set up su_trim:  */
1347			writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11);
1348		} else if (priv->type == PHY_TYPE_SATA) {
1349			/* downward spread spectrum +500ppm */
1350			val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT;
1351			val |= RK3568_PHYREG32_SSC_OFFSET_500PPM <<
1352			       RK3568_PHYREG32_SSC_OFFSET_SHIFT;
1353			rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val,
1354						 RK3568_PHYREG32);
1355		}
1356		break;
1357	default:
1358		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
1359		return -EINVAL;
1360	}
1361
1362	if (priv->ext_refclk) {
1363		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
1364		if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
1365			val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT;
1366			val |= RK3568_PHYREG13_CKRCV_AMP0;
1367			rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val,
1368						 RK3568_PHYREG13);
1369
1370			val = readl(priv->mmio + RK3568_PHYREG14);
1371			val |= RK3568_PHYREG14_CKRCV_AMP1;
1372			writel(val, priv->mmio + RK3568_PHYREG14);
1373		}
1374	}
1375
1376	if (priv->enable_ssc) {
1377		val = readl(priv->mmio + RK3568_PHYREG8);
1378		val |= RK3568_PHYREG8_SSC_EN;
1379		writel(val, priv->mmio + RK3568_PHYREG8);
1380	}
1381
1382	return 0;
1383}
1384
1385static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = {
1386	/* pipe-phy-grf */
1387	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
1388	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
1389	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
1390	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
1391	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
1392	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
1393	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
1394	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
1395	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
1396	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
1397	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
1398	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
1399	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
1400	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
1401	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
1402	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
1403	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0129 },
1404	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0000 },
1405	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c1 },
1406	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x0407 },
1407	/* pipe-grf */
1408	.pipe_con0_for_sata	= { 0x0000, 11, 5, 0x00, 0x22 },
1409	.pipe_con1_for_sata	= { 0x0000, 2, 0, 0x00, 0x2 },
1410	.pipe_pcie1l0_sel	= { 0x0100, 0, 0, 0x01, 0x0 },
1411	.pipe_pcie1l1_sel	= { 0x0100, 1, 1, 0x01, 0x0 },
1412};
1413
1414static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = {
1415	.num_phys = 3,
1416	.phy_ids = {
1417		0xfee00000,
1418		0xfee10000,
1419		0xfee20000,
1420	},
1421	.grfcfg		= &rk3588_combphy_grfcfgs,
1422	.combphy_cfg	= rk3588_combphy_cfg,
1423};
1424
1425static const struct of_device_id rockchip_combphy_of_match[] = {
1426	{
1427		.compatible = "rockchip,rk3528-naneng-combphy",
1428		.data = &rk3528_combphy_cfgs,
1429	},
1430	{
1431		.compatible = "rockchip,rk3562-naneng-combphy",
1432		.data = &rk3562_combphy_cfgs,
1433	},
1434	{
1435		.compatible = "rockchip,rk3568-naneng-combphy",
1436		.data = &rk3568_combphy_cfgs,
1437	},
1438	{
1439		.compatible = "rockchip,rk3576-naneng-combphy",
1440		.data = &rk3576_combphy_cfgs,
1441	},
1442	{
1443		.compatible = "rockchip,rk3588-naneng-combphy",
1444		.data = &rk3588_combphy_cfgs,
1445	},
1446	{ },
1447};
1448MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
1449
1450static struct platform_driver rockchip_combphy_driver = {
1451	.probe	= rockchip_combphy_probe,
1452	.driver = {
1453		.name = "rockchip-naneng-combphy",
1454		.of_match_table = rockchip_combphy_of_match,
1455	},
1456};
1457module_platform_driver(rockchip_combphy_driver);
1458
1459MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
1460MODULE_LICENSE("GPL v2");
~/ Read-only file preview.