diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index 123d19f10416..de10c2f12f69 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -72,6 +72,13 @@ struct udphy_vogrf_cfg { struct udphy_grf_reg hpd_trigger; }; +struct dp_tx_drv_ctrl { + u32 trsv_reg0204; + u32 trsv_reg0205; + u32 trsv_reg0206; + u32 trsv_reg0207; +}; + struct rockchip_udphy; struct rockchip_udphy_cfg { @@ -81,6 +88,8 @@ struct rockchip_udphy_cfg { struct udphy_grf_cfg grfcfg; struct udphy_vogrf_cfg vogrfcfg[2]; + const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4]; + const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg_typec[4])[4]; int (*combophy_init)(struct rockchip_udphy *udphy); int (*dp_phy_set_rate)(struct rockchip_udphy *udphy, struct phy_configure_opts_dp *dp); @@ -124,12 +133,125 @@ struct rockchip_udphy { u32 dp_lane_sel[4]; u32 dp_aux_dout_sel; u32 dp_aux_din_sel; + u8 bw; int id; /* PHY const config */ const struct rockchip_udphy_cfg *cfgs; }; +static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = { + /* voltage swing 0, pre-emphasis 0->3 */ + { + { 0x20, 0x10, 0x42, 0xe5 }, + { 0x26, 0x14, 0x42, 0xe5 }, + { 0x29, 0x18, 0x42, 0xe5 }, + { 0x2b, 0x1c, 0x43, 0xe7 }, + }, + + /* voltage swing 1, pre-emphasis 0->2 */ + { + { 0x23, 0x10, 0x42, 0xe7 }, + { 0x2a, 0x17, 0x43, 0xe7 }, + { 0x2b, 0x1a, 0x43, 0xe7 }, + }, + + /* voltage swing 2, pre-emphasis 0->1 */ + { + { 0x27, 0x10, 0x42, 0xe7 }, + { 0x2b, 0x17, 0x43, 0xe7 }, + }, + + /* voltage swing 3, pre-emphasis 0 */ + { + { 0x29, 0x10, 0x43, 0xe7 }, + }, +}; + +static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr_typec[4][4] = { + /* voltage swing 0, pre-emphasis 0->3 */ + { + { 0x20, 0x10, 0x42, 0xe5 }, + { 0x26, 0x14, 0x42, 0xe5 }, + { 0x29, 0x18, 0x42, 0xe5 }, + { 0x2b, 0x1c, 0x43, 0xe7 }, + }, + + /* voltage swing 1, pre-emphasis 0->2 */ + { + { 0x23, 0x10, 0x42, 0xe7 }, + { 0x2a, 0x17, 0x43, 0xe7 }, + { 0x2b, 0x1a, 0x43, 0xe7 }, + }, + + /* voltage swing 2, pre-emphasis 0->1 */ + { + { 0x27, 0x10, 0x43, 0x67 }, + { 0x2b, 0x17, 0x43, 0xe7 }, + }, + + /* voltage swing 3, pre-emphasis 0 */ + { + { 0x29, 0x10, 0x43, 0xe7 }, + }, +}; + +static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = { + /* voltage swing 0, pre-emphasis 0->3 */ + { + { 0x21, 0x10, 0x42, 0xe5 }, + { 0x26, 0x14, 0x42, 0xe5 }, + { 0x26, 0x16, 0x43, 0xe5 }, + { 0x2a, 0x19, 0x43, 0xe7 }, + }, + + /* voltage swing 1, pre-emphasis 0->2 */ + { + { 0x24, 0x10, 0x42, 0xe7 }, + { 0x2a, 0x17, 0x43, 0xe7 }, + { 0x2b, 0x1a, 0x43, 0xe7 }, + }, + + /* voltage swing 2, pre-emphasis 0->1 */ + { + { 0x28, 0x10, 0x42, 0xe7 }, + { 0x2b, 0x17, 0x43, 0xe7 }, + }, + + /* voltage swing 3, pre-emphasis 0 */ + { + { 0x28, 0x10, 0x43, 0xe7 }, + }, +}; + +static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = { + /* voltage swing 0, pre-emphasis 0->3 */ + { + { 0x21, 0x10, 0x42, 0xe5 }, + { 0x26, 0x14, 0x42, 0xe5 }, + { 0x26, 0x16, 0x43, 0xe5 }, + { 0x29, 0x18, 0x43, 0xe7 }, + }, + + /* voltage swing 1, pre-emphasis 0->2 */ + { + { 0x24, 0x10, 0x42, 0xe7 }, + { 0x2a, 0x18, 0x43, 0xe7 }, + { 0x2b, 0x1b, 0x43, 0xe7 } + }, + + /* voltage swing 2, pre-emphasis 0->1 */ + { + { 0x27, 0x10, 0x42, 0xe7 }, + { 0x2b, 0x18, 0x43, 0xe7 } + }, + + /* voltage swing 3, pre-emphasis 0 */ + { + { 0x28, 0x10, 0x43, 0xe7 }, + }, +}; + static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = { {0x0090, 0x68}, {0x0094, 0x68}, {0x0128, 0x24}, {0x012c, 0x44}, @@ -150,10 +272,10 @@ static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = { {0x01fc, 0x29}, {0x0208, 0x2a}, {0x020c, 0x17}, {0x0210, 0x17}, {0x0214, 0x2a}, {0x0224, 0x20}, - {0x03f0, 0x0d}, {0x03f4, 0x09}, - {0x03f8, 0x09}, {0x03fc, 0x0d}, - {0x0404, 0x0e}, {0x0408, 0x14}, - {0x040c, 0x14}, {0x0410, 0x3b}, + {0x03f0, 0x0a}, {0x03f4, 0x07}, + {0x03f8, 0x07}, {0x03fc, 0x0c}, + {0x0404, 0x12}, {0x0408, 0x1a}, + {0x040c, 0x1a}, {0x0410, 0x3f}, {0x0ce0, 0x68}, {0x0ce8, 0xd0}, {0x0cf0, 0x87}, {0x0cf8, 0x70}, {0x0d00, 0x70}, {0x0d08, 0xa9}, @@ -1033,13 +1155,15 @@ static int rockchip_udphy_probe(struct platform_device *pdev) return ret; } - ret = udphy_setup_typec_mux(udphy); - if (ret) - return ret; + if (device_property_present(dev, "svid")) { + ret = udphy_setup_typec_mux(udphy); + if (ret) + return ret; - ret = devm_add_action_or_reset(dev, udphy_typec_mux_unregister, udphy); - if (ret) - return ret; + ret = devm_add_action_or_reset(dev, udphy_typec_mux_unregister, udphy); + if (ret) + return ret; + } for_each_available_child_of_node(np, child_np) { struct phy *phy; @@ -1271,7 +1395,6 @@ static int rk3588_udphy_dplane_select(struct rockchip_udphy *udphy) static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy, struct phy_configure_opts_dp *dp) { - u8 bw; u32 val; int ret; @@ -1280,23 +1403,23 @@ static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy, switch (dp->link_rate) { case 1620: - bw = DP_BW_RBR; + udphy->bw = DP_BW_RBR; break; case 2700: - bw = DP_BW_HBR; + udphy->bw = DP_BW_HBR; break; case 5400: - bw = DP_BW_HBR2; + udphy->bw = DP_BW_HBR2; break; case 8100: - bw = DP_BW_HBR3; + udphy->bw = DP_BW_HBR3; break; default: return -EINVAL; } regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW, - FIELD_PREP(CMN_DP_TX_LINK_BW, bw)); + FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw)); regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN, FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc)); regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN, @@ -1314,55 +1437,25 @@ static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy, return 0; } -static const struct { - u32 trsv_reg0204; - u32 trsv_reg0205; - u32 trsv_reg0206; - u32 trsv_reg0207; -} training_table[4][4] = { - /* voltage swing 0, pre-emphasis 0->3 */ - { - { 0x21, 0x10, 0x42, 0xe5 }, - { 0x25, 0x14, 0x42, 0xe5 }, - { 0x26, 0x17, 0x43, 0xe5 }, - { 0x2b, 0x1c, 0x43, 0xe7 } - }, - - /* voltage swing 1, pre-emphasis 0->2 */ - { - { 0x26, 0x10, 0x42, 0xe7 }, - { 0x2b, 0x15, 0x42, 0xe7 }, - { 0x2b, 0x18, 0x43, 0xe7 } - }, - - /* voltage swing 2, pre-emphasis 0->1 */ - { - { 0x2a, 0x10, 0x42, 0xe7 }, - { 0x2b, 0x15, 0x43, 0xe7 } - }, - - /* voltage swing 3, pre-emphasis 0 */ - { - { 0x2b, 0x10, 0x43, 0xe7 }, - }, -}; - -static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy, +static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy, u8 bw, u32 voltage, u32 pre, u32 lane) { u32 offset = 0x800 * lane; u32 val; + const struct rockchip_udphy_cfg *cfg = udphy->cfgs; + const struct dp_tx_drv_ctrl (*dp_ctrl)[4]; - val = training_table[voltage][pre].trsv_reg0204; + dp_ctrl = udphy->mux ? cfg->dp_tx_ctrl_cfg_typec[bw] : cfg->dp_tx_ctrl_cfg[bw]; + val = dp_ctrl[voltage][pre].trsv_reg0204; regmap_write(udphy->pma_regmap, 0x0810 + offset, val); - val = training_table[voltage][pre].trsv_reg0205; + val = dp_ctrl[voltage][pre].trsv_reg0205; regmap_write(udphy->pma_regmap, 0x0814 + offset, val); - val = training_table[voltage][pre].trsv_reg0206; + val = dp_ctrl[voltage][pre].trsv_reg0206; regmap_write(udphy->pma_regmap, 0x0818 + offset, val); - val = training_table[voltage][pre].trsv_reg0207; + val = dp_ctrl[voltage][pre].trsv_reg0207; regmap_write(udphy->pma_regmap, 0x081c + offset, val); } @@ -1389,8 +1482,7 @@ static int rk3588_dp_phy_set_voltages(struct rockchip_udphy *udphy, break; } - rk3588_dp_phy_set_voltage(udphy, dp->voltage[i], - dp->pre[i], lane); + rk3588_dp_phy_set_voltage(udphy, udphy->bw, dp->voltage[i], dp->pre[i], lane); } return 0; @@ -1424,6 +1516,18 @@ static const struct rockchip_udphy_cfg rk3588_udphy_cfgs = { .hpd_trigger = { 0x0008, 11, 10, 1, 3 }, }, }, + .dp_tx_ctrl_cfg = { + rk3588_dp_tx_drv_ctrl_rbr_hbr, + rk3588_dp_tx_drv_ctrl_rbr_hbr, + rk3588_dp_tx_drv_ctrl_hbr2, + rk3588_dp_tx_drv_ctrl_hbr3, + }, + .dp_tx_ctrl_cfg_typec = { + rk3588_dp_tx_drv_ctrl_rbr_hbr_typec, + rk3588_dp_tx_drv_ctrl_rbr_hbr_typec, + rk3588_dp_tx_drv_ctrl_hbr2, + rk3588_dp_tx_drv_ctrl_hbr3, + }, .combophy_init = rk3588_udphy_init, .dp_phy_set_rate = rk3588_dp_phy_set_rate, .dp_phy_set_voltages = rk3588_dp_phy_set_voltages,