From 1cef86cabd2f285d18a7d67ce75303a7d7a39290 Mon Sep 17 00:00:00 2001 From: William Wu Date: Mon, 24 Feb 2025 10:42:53 +0800 Subject: [PATCH] phy: rockchip: naneng-combphy: Add support for rv1126b usb3 This patch adds the USB3.0 PHY configurations for RV1126B USB3.0 interface. The RV1126B USB3.0 PHY clamp default value is 1'b0 which means that clamp enable. This patch sets clamp value to 1'b1 for USB3.0 function. Signed-off-by: William Wu Change-Id: Id285ffd72e849a878b8d338671060ad222143c7e --- .../rockchip/phy-rockchip-naneng-combphy.c | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 723e7856232b..d351ad8833a5 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -62,6 +62,7 @@ struct rockchip_combphy_grfcfg { struct combphy_reg pipe_con1_for_sata; struct combphy_reg pipe_sgmii_mac_sel; struct combphy_reg pipe_xpcs_phy_ready; + struct combphy_reg u3otg0_clamp_dis; struct combphy_reg u3otg0_port_en; struct combphy_reg u3otg1_port_en; struct combphy_reg pipe_phy_grf_reset; @@ -159,6 +160,10 @@ static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); return ret; + } else { + if (cfg->u3otg0_clamp_dis.enable) + rockchip_combphy_param_write(priv->pipe_grf, + &cfg->u3otg0_clamp_dis, true); } if (priv->cfg->combphy_cfg) { @@ -1436,6 +1441,121 @@ static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { .force_det_out = true, }; +static int rv1126b_combphy_cfg(struct rockchip_combphy_priv *priv) +{ + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; + struct clk *refclk = NULL; + unsigned long rate; + int i; + + /* Configure PHY reference clock frequency */ + for (i = 0; i < priv->num_clks; i++) { + if (!strncmp(priv->clks[i].id, "refclk", 6)) { + refclk = priv->clks[i].clk; + break; + } + } + + if (!refclk) { + dev_err(priv->dev, "No refclk found\n"); + return -EINVAL; + } + + switch (priv->mode) { + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(priv, GENMASK(5, 4), BIT(4), 0x1f << 2); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(priv, GENMASK(0, 0), BIT(0), 0x0e << 2); + + /* Set PLL KVCO fine tuning signals */ + rockchip_combphy_updatel(priv, GENMASK(4, 2), 0x2 << 2, 0x20 << 2); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ + writel(0x4, priv->mmio + (0x0b << 2)); + + /* Set PLL input clock divider 1/2 */ + rockchip_combphy_updatel(priv, GENMASK(7, 6), BIT(6), 0x05 << 2); + + /* Set PLL loop divider */ + writel(0x32, priv->mmio + (0x11 << 2)); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ + writel(0xf0, priv->mmio + (0x0a << 2)); + + /* Set Rx squelch input filler bandwidth */ + writel(0x0e, priv->mmio + (0x14 << 2)); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); + break; + default: + dev_err(priv->dev, "incompatible PHY type\n"); + return -EINVAL; + } + + rate = clk_get_rate(refclk); + + switch (rate) { + case 24000000: + if (priv->mode == PHY_TYPE_USB3) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ + rockchip_combphy_updatel(priv, GENMASK(7, 6), BIT(6), 0x0e << 2); + rockchip_combphy_updatel(priv, GENMASK(7, 0), 0x5f, 0x0f << 2); + } + break; + case 25000000: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true); + break; + case 100000000: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + break; + default: + dev_err(priv->dev, "Unsupported rate: %lu\n", rate); + return -EINVAL; + } + + return 0; +} + +static const struct rockchip_combphy_grfcfg rv1126b_combphy_grfcfgs = { + /* pipe-phy-grf */ + .usb_mode_set = { 0x18000, 5, 0, 0x00, 0x04 }, + .pipe_rxterm_set = { 0x18000, 12, 12, 0x00, 0x01 }, + .pipe_txelec_set = { 0x18004, 1, 1, 0x00, 0x01 }, + .pipe_txcomp_set = { 0x18004, 4, 4, 0x00, 0x01 }, + .pipe_clk_25m = { 0x18004, 14, 13, 0x00, 0x01 }, + .pipe_clk_100m = { 0x18004, 14, 13, 0x00, 0x02 }, + .pipe_phymode_sel = { 0x18008, 1, 1, 0x00, 0x01 }, + .pipe_rate_sel = { 0x18008, 2, 2, 0x00, 0x01 }, + .pipe_rxterm_sel = { 0x18008, 8, 8, 0x00, 0x01 }, + .pipe_txelec_sel = { 0x18008, 12, 12, 0x00, 0x01 }, + .pipe_txcomp_sel = { 0x18008, 15, 15, 0x00, 0x01 }, + .pipe_clk_ext = { 0x1800c, 9, 8, 0x02, 0x01 }, + .pipe_sel_usb = { 0x1800c, 14, 13, 0x00, 0x01 }, + .pipe_phy_status = { 0x18034, 6, 6, 0x01, 0x00 }, + /* peri-grf */ + .u3otg0_port_en = { 0x1003c, 15, 0, 0x0189, 0x1100 }, + /* pmu-grf */ + .u3otg0_clamp_dis = { 0x30000, 14, 14, 0x00, 0x01 }, +}; + +static const struct clk_bulk_data rv1126b_clks[] = { + { .id = "refclk" }, + { .id = "apbclk" }, +}; + +static const struct rockchip_combphy_cfg rv1126b_combphy_cfgs = { + .num_clks = ARRAY_SIZE(rv1126b_clks), + .clks = rv1126b_clks, + .grfcfg = &rv1126b_combphy_grfcfgs, + .combphy_cfg = rv1126b_combphy_cfg, + .force_det_out = true, +}; + static const struct of_device_id rockchip_combphy_of_match[] = { { .compatible = "rockchip,rk3528-naneng-combphy", @@ -1457,6 +1577,10 @@ static const struct of_device_id rockchip_combphy_of_match[] = { .compatible = "rockchip,rk3588-naneng-combphy", .data = &rk3588_combphy_cfgs, }, + { + .compatible = "rockchip,rv1126b-usb3-phy", + .data = &rv1126b_combphy_cfgs, + }, { }, }; MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);