diff options
Diffstat (limited to 'drivers/phy/rockchip/phy-rockchip-usbdp.c')
| -rw-r--r-- | drivers/phy/rockchip/phy-rockchip-usbdp.c | 134 |
1 files changed, 96 insertions, 38 deletions
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index 2c51e5c62d3e..fba35510d88c 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -187,6 +187,8 @@ struct rk_udphy { u32 dp_aux_din_sel; bool dp_sink_hpd_sel; bool dp_sink_hpd_cfg; + unsigned int link_rate; + unsigned int lanes; u8 bw; int id; @@ -664,7 +666,7 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw, goto unlock_ret; } - udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; + udphy->flip = orien == TYPEC_ORIENTATION_REVERSE; rk_udphy_set_typec_default_mapping(udphy); rk_udphy_usb_bvalid_enable(udphy, true); @@ -978,7 +980,7 @@ static int rk_udphy_parse_dt(struct rk_udphy *udphy) if (device_property_present(dev, "maximum-speed")) { maximum_speed = usb_get_maximum_speed(dev); - udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false; + udphy->hs = maximum_speed <= USB_SPEED_HIGH; } ret = rk_udphy_clk_init(udphy, dev); @@ -1045,7 +1047,6 @@ static int rk_udphy_dp_phy_init(struct phy *phy) mutex_lock(&udphy->mutex); udphy->dp_in_use = true; - rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg); mutex_unlock(&udphy->mutex); @@ -1103,15 +1104,19 @@ static int rk_udphy_dp_phy_power_off(struct phy *phy) return 0; } -static int rk_udphy_dp_phy_verify_link_rate(unsigned int link_rate) +/* + * Verify link rate + */ +static int rk_udphy_dp_phy_verify_link_rate(struct rk_udphy *udphy, + struct phy_configure_opts_dp *dp) { - switch (link_rate) { + switch (dp->link_rate) { case 1620: case 2700: case 5400: case 8100: + udphy->link_rate = dp->link_rate; break; - default: return -EINVAL; } @@ -1119,45 +1124,44 @@ static int rk_udphy_dp_phy_verify_link_rate(unsigned int link_rate) return 0; } -static int rk_udphy_dp_phy_verify_config(struct rk_udphy *udphy, - struct phy_configure_opts_dp *dp) +static int rk_udphy_dp_phy_verify_lanes(struct rk_udphy *udphy, + struct phy_configure_opts_dp *dp) { - int i, ret; - - /* If changing link rate was required, verify it's supported. */ - ret = rk_udphy_dp_phy_verify_link_rate(dp->link_rate); - if (ret) - return ret; - - /* Verify lane count. */ switch (dp->lanes) { case 1: case 2: case 4: /* valid lane count. */ + udphy->lanes = dp->lanes; break; default: return -EINVAL; } - /* - * If changing voltages is required, check swing and pre-emphasis - * levels, per-lane. - */ - if (dp->set_voltages) { - /* Lane count verified previously. */ - for (i = 0; i < dp->lanes; i++) { - if (dp->voltage[i] > 3 || dp->pre[i] > 3) - return -EINVAL; + return 0; +} - /* - * Sum of voltage swing and pre-emphasis levels cannot - * exceed 3. - */ - if (dp->voltage[i] + dp->pre[i] > 3) - return -EINVAL; - } +/* + * If changing voltages is required, check swing and pre-emphasis + * levels, per-lane. + */ +static int rk_udphy_dp_phy_verify_voltages(struct rk_udphy *udphy, + struct phy_configure_opts_dp *dp) +{ + int i; + + /* Lane count verified previously. */ + for (i = 0; i < udphy->lanes; i++) { + if (dp->voltage[i] > 3 || dp->pre[i] > 3) + return -EINVAL; + + /* + * Sum of voltage swing and pre-emphasis levels cannot + * exceed 3. + */ + if (dp->voltage[i] + dp->pre[i] > 3) + return -EINVAL; } return 0; @@ -1197,9 +1201,23 @@ static int rk_udphy_dp_phy_configure(struct phy *phy, u32 i, val, lane; int ret; - ret = rk_udphy_dp_phy_verify_config(udphy, dp); - if (ret) - return ret; + if (dp->set_rate) { + ret = rk_udphy_dp_phy_verify_link_rate(udphy, dp); + if (ret) + return ret; + } + + if (dp->set_lanes) { + ret = rk_udphy_dp_phy_verify_lanes(udphy, dp); + if (ret) + return ret; + } + + if (dp->set_voltages) { + ret = rk_udphy_dp_phy_verify_voltages(udphy, dp); + if (ret) + return ret; + } if (dp->set_rate) { regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, @@ -1244,9 +1262,9 @@ static int rk_udphy_dp_phy_configure(struct phy *phy, } if (dp->set_voltages) { - for (i = 0; i < dp->lanes; i++) { + for (i = 0; i < udphy->lanes; i++) { lane = udphy->dp_lane_sel[i]; - switch (dp->link_rate) { + switch (udphy->link_rate) { case 1620: case 2700: regmap_update_bits(udphy->pma_regmap, @@ -1412,7 +1430,6 @@ static const struct regmap_config rk_udphy_pma_regmap_cfg = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .fast_io = true, .max_register = 0x20dc, }; @@ -1538,6 +1555,43 @@ static const char * const rk_udphy_rst_list[] = { "init", "cmn", "lane", "pcs_apb", "pma_apb" }; +static const struct rk_udphy_cfg rk3576_udphy_cfgs = { + .num_phys = 1, + .phy_ids = { 0x2b010000 }, + .num_rsts = ARRAY_SIZE(rk_udphy_rst_list), + .rst_list = rk_udphy_rst_list, + .grfcfg = { + /* u2phy-grf */ + .bvalid_phy_con = RK_UDPHY_GEN_GRF_REG(0x0010, 1, 0, 0x2, 0x3), + .bvalid_grf_con = RK_UDPHY_GEN_GRF_REG(0x0000, 15, 14, 0x1, 0x3), + + /* usb-grf */ + .usb3otg0_cfg = RK_UDPHY_GEN_GRF_REG(0x0030, 15, 0, 0x1100, 0x0188), + + /* usbdpphy-grf */ + .low_pwrn = RK_UDPHY_GEN_GRF_REG(0x0004, 13, 13, 0, 1), + .rx_lfps = RK_UDPHY_GEN_GRF_REG(0x0004, 14, 14, 0, 1), + }, + .vogrfcfg = { + { + .hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0000, 11, 10, 1, 3), + .dp_lane_reg = 0x0000, + }, + }, + .dp_tx_ctrl_cfg = { + 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, + }, + .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, + }, +}; + static const struct rk_udphy_cfg rk3588_udphy_cfgs = { .num_phys = 2, .phy_ids = { @@ -1585,6 +1639,10 @@ static const struct rk_udphy_cfg rk3588_udphy_cfgs = { static const struct of_device_id rk_udphy_dt_match[] = { { + .compatible = "rockchip,rk3576-usbdp-phy", + .data = &rk3576_udphy_cfgs + }, + { .compatible = "rockchip,rk3588-usbdp-phy", .data = &rk3588_udphy_cfgs }, |
