Lines Matching +full:dp +full:- +full:lane +full:- +full:mux

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2021-2024 Rockchip Electronics Co., Ltd
9 #include <dt-bindings/phy/phy.h>
115 /* u2phy-grf */
119 /* usb-grf */
123 /* usbdpphy-grf */
129 /* vo-grf */
162 struct typec_mux_dev *mux; member
179 bool hs; /* flag for high-speed */
181 /* utilized for DP */
204 /* voltage swing 0, pre-emphasis 0->3 */
212 /* voltage swing 1, pre-emphasis 0->2 */
219 /* voltage swing 2, pre-emphasis 0->1 */
225 /* voltage swing 3, pre-emphasis 0 */
232 /* voltage swing 0, pre-emphasis 0->3 */
240 /* voltage swing 1, pre-emphasis 0->2 */
247 /* voltage swing 2, pre-emphasis 0->1 */
253 /* voltage swing 3, pre-emphasis 0 */
260 /* voltage swing 0, pre-emphasis 0->3 */
268 /* voltage swing 1, pre-emphasis 0->2 */
275 /* voltage swing 2, pre-emphasis 0->1 */
281 /* voltage swing 3, pre-emphasis 0 */
288 /* voltage swing 0, pre-emphasis 0->3 */
296 /* voltage swing 1, pre-emphasis 0->2 */
303 /* voltage swing 2, pre-emphasis 0->1 */
309 /* voltage swing 3, pre-emphasis 0 */
420 return regmap_write(base, reg->offset, en ? reg->enable : reg->disable); in rk_udphy_grfreg_write()
427 udphy->num_clks = devm_clk_bulk_get_all(dev, &udphy->clks); in rk_udphy_clk_init()
428 if (udphy->num_clks < 1) in rk_udphy_clk_init()
429 return -ENODEV; in rk_udphy_clk_init()
432 for (i = 0; i < udphy->num_clks; i++) { in rk_udphy_clk_init()
433 if (!strncmp(udphy->clks[i].id, "refclk", 6)) { in rk_udphy_clk_init()
434 udphy->refclk = udphy->clks[i].clk; in rk_udphy_clk_init()
439 if (!udphy->refclk) in rk_udphy_clk_init()
440 return dev_err_probe(udphy->dev, -EINVAL, "no refclk found\n"); in rk_udphy_clk_init()
447 return reset_control_bulk_assert(udphy->num_rsts, udphy->rsts); in rk_udphy_reset_assert_all()
452 return reset_control_bulk_deassert(udphy->num_rsts, udphy->rsts); in rk_udphy_reset_deassert_all()
457 struct reset_control_bulk_data *list = udphy->rsts; in rk_udphy_reset_deassert()
460 for (idx = 0; idx < udphy->num_rsts; idx++) { in rk_udphy_reset_deassert()
465 return -EINVAL; in rk_udphy_reset_deassert()
470 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_reset_init()
473 udphy->num_rsts = cfg->num_rsts; in rk_udphy_reset_init()
474 udphy->rsts = devm_kcalloc(dev, udphy->num_rsts, in rk_udphy_reset_init()
475 sizeof(*udphy->rsts), GFP_KERNEL); in rk_udphy_reset_init()
476 if (!udphy->rsts) in rk_udphy_reset_init()
477 return -ENOMEM; in rk_udphy_reset_init()
479 for (idx = 0; idx < cfg->num_rsts; idx++) in rk_udphy_reset_init()
480 udphy->rsts[idx].id = cfg->rst_list[idx]; in rk_udphy_reset_init()
482 return devm_reset_control_bulk_get_exclusive(dev, cfg->num_rsts, in rk_udphy_reset_init()
483 udphy->rsts); in rk_udphy_reset_init()
488 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_u3_port_disable()
491 preg = udphy->id ? &cfg->grfcfg.usb3otg1_cfg : &cfg->grfcfg.usb3otg0_cfg; in rk_udphy_u3_port_disable()
492 rk_udphy_grfreg_write(udphy->usbgrf, preg, disable); in rk_udphy_u3_port_disable()
497 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_usb_bvalid_enable()
499 rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_phy_con, enable); in rk_udphy_usb_bvalid_enable()
500 rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_grf_con, enable); in rk_udphy_usb_bvalid_enable()
504 * In usb/dp combo phy driver, here are 2 ways to mapping lanes.
506 * 1 Type-C Mapping table (DP_Alt_Mode V1.0b remove ABF pin mapping)
507 * ---------------------------------------------------------------------------
508 * Type-C Pin B11-B10 A2-A3 A11-A10 B2-B3
518 * ---------------------------------------------------------------------------
521 * if all 4 lane assignment for dp function, define rockchip,dp-lane-mux = <x x x x>;
523 * ---------------------------------------------------------------------------
524 * B11-B10 A2-A3 A11-A10 B2-B3
525 * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
528 * ---------------------------------------------------------------------------
529 * if 2 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x x>;
531 * ---------------------------------------------------------------------------
532 * B11-B10 A2-A3 A11-A10 B2-B3
533 * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
536 * ---------------------------------------------------------------------------
541 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_dplane_select()
544 switch (udphy->mode) { in rk_udphy_dplane_select()
546 value |= 2 << udphy->dp_lane_sel[2] * 2; in rk_udphy_dplane_select()
547 value |= 3 << udphy->dp_lane_sel[3] * 2; in rk_udphy_dplane_select()
551 value |= 0 << udphy->dp_lane_sel[0] * 2; in rk_udphy_dplane_select()
552 value |= 1 << udphy->dp_lane_sel[1] * 2; in rk_udphy_dplane_select()
562 regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg, in rk_udphy_dplane_select()
564 FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) | in rk_udphy_dplane_select()
565 FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value); in rk_udphy_dplane_select()
572 switch (udphy->mode) { in rk_udphy_dplane_get()
596 val |= BIT(udphy->dp_lane_sel[i]); in rk_udphy_dplane_enable()
598 regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, CMN_DP_LANE_EN_ALL, in rk_udphy_dplane_enable()
602 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, in rk_udphy_dplane_enable()
608 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_dp_hpd_event_trigger()
610 udphy->dp_sink_hpd_sel = true; in rk_udphy_dp_hpd_event_trigger()
611 udphy->dp_sink_hpd_cfg = hpd; in rk_udphy_dp_hpd_event_trigger()
613 if (!udphy->dp_in_use) in rk_udphy_dp_hpd_event_trigger()
616 rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd); in rk_udphy_dp_hpd_event_trigger()
621 if (udphy->flip) { in rk_udphy_set_typec_default_mapping()
622 udphy->dp_lane_sel[0] = 0; in rk_udphy_set_typec_default_mapping()
623 udphy->dp_lane_sel[1] = 1; in rk_udphy_set_typec_default_mapping()
624 udphy->dp_lane_sel[2] = 3; in rk_udphy_set_typec_default_mapping()
625 udphy->dp_lane_sel[3] = 2; in rk_udphy_set_typec_default_mapping()
626 udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; in rk_udphy_set_typec_default_mapping()
627 udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; in rk_udphy_set_typec_default_mapping()
628 udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB; in rk_udphy_set_typec_default_mapping()
629 udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB; in rk_udphy_set_typec_default_mapping()
630 udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT; in rk_udphy_set_typec_default_mapping()
631 udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT; in rk_udphy_set_typec_default_mapping()
632 gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 1); in rk_udphy_set_typec_default_mapping()
633 gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0); in rk_udphy_set_typec_default_mapping()
635 udphy->dp_lane_sel[0] = 2; in rk_udphy_set_typec_default_mapping()
636 udphy->dp_lane_sel[1] = 3; in rk_udphy_set_typec_default_mapping()
637 udphy->dp_lane_sel[2] = 1; in rk_udphy_set_typec_default_mapping()
638 udphy->dp_lane_sel[3] = 0; in rk_udphy_set_typec_default_mapping()
639 udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB; in rk_udphy_set_typec_default_mapping()
640 udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB; in rk_udphy_set_typec_default_mapping()
641 udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; in rk_udphy_set_typec_default_mapping()
642 udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; in rk_udphy_set_typec_default_mapping()
643 udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL; in rk_udphy_set_typec_default_mapping()
644 udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL; in rk_udphy_set_typec_default_mapping()
645 gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0); in rk_udphy_set_typec_default_mapping()
646 gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1); in rk_udphy_set_typec_default_mapping()
649 udphy->mode = UDPHY_MODE_DP_USB; in rk_udphy_set_typec_default_mapping()
657 mutex_lock(&udphy->mutex); in rk_udphy_orien_sw_set()
660 gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0); in rk_udphy_orien_sw_set()
661 gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0); in rk_udphy_orien_sw_set()
667 udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; in rk_udphy_orien_sw_set()
672 mutex_unlock(&udphy->mutex); in rk_udphy_orien_sw_set()
680 typec_switch_unregister(udphy->sw); in rk_udphy_orien_switch_unregister()
688 sw_desc.fwnode = dev_fwnode(udphy->dev); in rk_udphy_setup_orien_switch()
691 udphy->sw = typec_switch_register(udphy->dev, &sw_desc); in rk_udphy_setup_orien_switch()
692 if (IS_ERR(udphy->sw)) { in rk_udphy_setup_orien_switch()
693 dev_err(udphy->dev, "Error register typec orientation switch: %ld\n", in rk_udphy_setup_orien_switch()
694 PTR_ERR(udphy->sw)); in rk_udphy_setup_orien_switch()
695 return PTR_ERR(udphy->sw); in rk_udphy_setup_orien_switch()
698 return devm_add_action_or_reset(udphy->dev, in rk_udphy_setup_orien_switch()
708 rate = clk_get_rate(udphy->refclk); in rk_udphy_refclk_set()
709 dev_dbg(udphy->dev, "refclk freq %ld\n", rate); in rk_udphy_refclk_set()
713 ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_24m_refclk_cfg, in rk_udphy_refclk_set()
721 ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_26m_refclk_cfg, in rk_udphy_refclk_set()
728 dev_err(udphy->dev, "unsupported refclk freq %ld\n", rate); in rk_udphy_refclk_set()
729 return -EINVAL; in rk_udphy_refclk_set()
741 if (udphy->mode & UDPHY_MODE_USB) { in rk_udphy_status_check()
742 ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET, in rk_udphy_status_check()
746 dev_err(udphy->dev, "cmn ana lcpll lock timeout\n"); in rk_udphy_status_check()
748 * If earlier software (U-Boot) enabled USB once already in rk_udphy_status_check()
751 * time being a -EPROBE_DEFER will solve the issue. in rk_udphy_status_check()
757 return -EPROBE_DEFER; in rk_udphy_status_check()
760 if (!udphy->flip) { in rk_udphy_status_check()
761 ret = regmap_read_poll_timeout(udphy->pma_regmap, in rk_udphy_status_check()
766 dev_err(udphy->dev, "trsv ln0 mon rx cdr lock timeout\n"); in rk_udphy_status_check()
768 ret = regmap_read_poll_timeout(udphy->pma_regmap, in rk_udphy_status_check()
773 dev_err(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n"); in rk_udphy_status_check()
782 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_init()
789 if (udphy->mode & UDPHY_MODE_USB) in rk_udphy_init()
790 rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true); in rk_udphy_init()
793 rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.low_pwrn, true); in rk_udphy_init()
799 ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_init_sequence, in rk_udphy_init()
802 dev_err(udphy->dev, "init sequence set error %d\n", ret); in rk_udphy_init()
808 dev_err(udphy->dev, "refclk set error %d\n", ret); in rk_udphy_init()
812 /* Step 3: configure lane mux */ in rk_udphy_init()
813 regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, in rk_udphy_init()
815 FIELD_PREP(CMN_DP_LANE_MUX_N(3), udphy->lane_mux_sel[3]) | in rk_udphy_init()
816 FIELD_PREP(CMN_DP_LANE_MUX_N(2), udphy->lane_mux_sel[2]) | in rk_udphy_init()
817 FIELD_PREP(CMN_DP_LANE_MUX_N(1), udphy->lane_mux_sel[1]) | in rk_udphy_init()
818 FIELD_PREP(CMN_DP_LANE_MUX_N(0), udphy->lane_mux_sel[0]) | in rk_udphy_init()
822 if (udphy->mode & UDPHY_MODE_USB) in rk_udphy_init()
825 if (udphy->mode & UDPHY_MODE_DP) { in rk_udphy_init()
826 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, in rk_udphy_init()
833 /* Step 5: deassert cmn/lane rstn */ in rk_udphy_init()
834 if (udphy->mode & UDPHY_MODE_USB) { in rk_udphy_init()
836 rk_udphy_reset_deassert(udphy, "lane"); in rk_udphy_init()
855 ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks); in rk_udphy_setup()
857 dev_err(udphy->dev, "failed to enable clk\n"); in rk_udphy_setup()
863 dev_err(udphy->dev, "failed to init combophy\n"); in rk_udphy_setup()
864 clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks); in rk_udphy_setup()
873 clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks); in rk_udphy_disable()
881 num_lanes = device_property_count_u32(udphy->dev, "rockchip,dp-lane-mux"); in rk_udphy_parse_lane_mux_data()
883 dev_dbg(udphy->dev, "no dp-lane-mux, following dp alt mode\n"); in rk_udphy_parse_lane_mux_data()
884 udphy->mode = UDPHY_MODE_USB; in rk_udphy_parse_lane_mux_data()
889 return dev_err_probe(udphy->dev, -EINVAL, in rk_udphy_parse_lane_mux_data()
890 "invalid number of lane mux\n"); in rk_udphy_parse_lane_mux_data()
892 ret = device_property_read_u32_array(udphy->dev, "rockchip,dp-lane-mux", in rk_udphy_parse_lane_mux_data()
893 udphy->dp_lane_sel, num_lanes); in rk_udphy_parse_lane_mux_data()
895 return dev_err_probe(udphy->dev, ret, "get dp lane mux failed\n"); in rk_udphy_parse_lane_mux_data()
900 if (udphy->dp_lane_sel[i] > 3) in rk_udphy_parse_lane_mux_data()
901 return dev_err_probe(udphy->dev, -EINVAL, in rk_udphy_parse_lane_mux_data()
902 "lane mux between 0 and 3, exceeding the range\n"); in rk_udphy_parse_lane_mux_data()
904 udphy->lane_mux_sel[udphy->dp_lane_sel[i]] = PHY_LANE_MUX_DP; in rk_udphy_parse_lane_mux_data()
907 if (udphy->dp_lane_sel[i] == udphy->dp_lane_sel[j]) in rk_udphy_parse_lane_mux_data()
908 return dev_err_probe(udphy->dev, -EINVAL, in rk_udphy_parse_lane_mux_data()
909 "set repeat lane mux value\n"); in rk_udphy_parse_lane_mux_data()
913 udphy->mode = UDPHY_MODE_DP; in rk_udphy_parse_lane_mux_data()
915 udphy->mode |= UDPHY_MODE_USB; in rk_udphy_parse_lane_mux_data()
916 udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP); in rk_udphy_parse_lane_mux_data()
927 ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks); in rk_udphy_get_initial_status()
929 dev_err(udphy->dev, "failed to enable clk\n"); in rk_udphy_get_initial_status()
935 regmap_read(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, &value); in rk_udphy_get_initial_status()
937 udphy->status = UDPHY_MODE_DP; in rk_udphy_get_initial_status()
946 struct device *dev = udphy->dev; in rk_udphy_parse_dt()
951 udphy->u2phygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,u2phy-grf"); in rk_udphy_parse_dt()
952 if (IS_ERR(udphy->u2phygrf)) in rk_udphy_parse_dt()
953 return dev_err_probe(dev, PTR_ERR(udphy->u2phygrf), "failed to get u2phy-grf\n"); in rk_udphy_parse_dt()
955 udphy->udphygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbdpphy-grf"); in rk_udphy_parse_dt()
956 if (IS_ERR(udphy->udphygrf)) in rk_udphy_parse_dt()
957 return dev_err_probe(dev, PTR_ERR(udphy->udphygrf), "failed to get usbdpphy-grf\n"); in rk_udphy_parse_dt()
959 udphy->usbgrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usb-grf"); in rk_udphy_parse_dt()
960 if (IS_ERR(udphy->usbgrf)) in rk_udphy_parse_dt()
961 return dev_err_probe(dev, PTR_ERR(udphy->usbgrf), "failed to get usb-grf\n"); in rk_udphy_parse_dt()
963 udphy->vogrf = syscon_regmap_lookup_by_phandle(np, "rockchip,vo-grf"); in rk_udphy_parse_dt()
964 if (IS_ERR(udphy->vogrf)) in rk_udphy_parse_dt()
965 return dev_err_probe(dev, PTR_ERR(udphy->vogrf), "failed to get vo-grf\n"); in rk_udphy_parse_dt()
971 udphy->sbu1_dc_gpio = devm_gpiod_get_optional(dev, "sbu1-dc", GPIOD_OUT_LOW); in rk_udphy_parse_dt()
972 if (IS_ERR(udphy->sbu1_dc_gpio)) in rk_udphy_parse_dt()
973 return PTR_ERR(udphy->sbu1_dc_gpio); in rk_udphy_parse_dt()
975 udphy->sbu2_dc_gpio = devm_gpiod_get_optional(dev, "sbu2-dc", GPIOD_OUT_LOW); in rk_udphy_parse_dt()
976 if (IS_ERR(udphy->sbu2_dc_gpio)) in rk_udphy_parse_dt()
977 return PTR_ERR(udphy->sbu2_dc_gpio); in rk_udphy_parse_dt()
979 if (device_property_present(dev, "maximum-speed")) { in rk_udphy_parse_dt()
981 udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false; in rk_udphy_parse_dt()
995 if (!(udphy->mode & mode)) { in rk_udphy_power_on()
996 dev_info(udphy->dev, "mode 0x%02x is not support\n", mode); in rk_udphy_power_on()
1000 if (udphy->status == UDPHY_MODE_NONE) { in rk_udphy_power_on()
1001 udphy->mode_change = false; in rk_udphy_power_on()
1006 if (udphy->mode & UDPHY_MODE_USB) in rk_udphy_power_on()
1008 } else if (udphy->mode_change) { in rk_udphy_power_on()
1009 udphy->mode_change = false; in rk_udphy_power_on()
1010 udphy->status = UDPHY_MODE_NONE; in rk_udphy_power_on()
1011 if (udphy->mode == UDPHY_MODE_DP) in rk_udphy_power_on()
1020 udphy->status |= mode; in rk_udphy_power_on()
1027 if (!(udphy->mode & mode)) { in rk_udphy_power_off()
1028 dev_info(udphy->dev, "mode 0x%02x is not support\n", mode); in rk_udphy_power_off()
1032 if (!udphy->status) in rk_udphy_power_off()
1035 udphy->status &= ~mode; in rk_udphy_power_off()
1037 if (udphy->status == UDPHY_MODE_NONE) in rk_udphy_power_off()
1045 mutex_lock(&udphy->mutex); in rk_udphy_dp_phy_init()
1047 udphy->dp_in_use = true; in rk_udphy_dp_phy_init()
1048 rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg); in rk_udphy_dp_phy_init()
1050 mutex_unlock(&udphy->mutex); in rk_udphy_dp_phy_init()
1059 mutex_lock(&udphy->mutex); in rk_udphy_dp_phy_exit()
1060 udphy->dp_in_use = false; in rk_udphy_dp_phy_exit()
1061 mutex_unlock(&udphy->mutex); in rk_udphy_dp_phy_exit()
1070 mutex_lock(&udphy->mutex); in rk_udphy_dp_phy_power_on()
1084 mutex_unlock(&udphy->mutex); in rk_udphy_dp_phy_power_on()
1098 mutex_lock(&udphy->mutex); in rk_udphy_dp_phy_power_off()
1101 mutex_unlock(&udphy->mutex); in rk_udphy_dp_phy_power_off()
1116 return -EINVAL; in rk_udphy_dp_phy_verify_link_rate()
1123 struct phy_configure_opts_dp *dp) in rk_udphy_dp_phy_verify_config() argument
1128 ret = rk_udphy_dp_phy_verify_link_rate(dp->link_rate); in rk_udphy_dp_phy_verify_config()
1132 /* Verify lane count. */ in rk_udphy_dp_phy_verify_config()
1133 switch (dp->lanes) { in rk_udphy_dp_phy_verify_config()
1137 /* valid lane count. */ in rk_udphy_dp_phy_verify_config()
1141 return -EINVAL; in rk_udphy_dp_phy_verify_config()
1145 * If changing voltages is required, check swing and pre-emphasis in rk_udphy_dp_phy_verify_config()
1146 * levels, per-lane. in rk_udphy_dp_phy_verify_config()
1148 if (dp->set_voltages) { in rk_udphy_dp_phy_verify_config()
1149 /* Lane count verified previously. */ in rk_udphy_dp_phy_verify_config()
1150 for (i = 0; i < dp->lanes; i++) { in rk_udphy_dp_phy_verify_config()
1151 if (dp->voltage[i] > 3 || dp->pre[i] > 3) in rk_udphy_dp_phy_verify_config()
1152 return -EINVAL; in rk_udphy_dp_phy_verify_config()
1155 * Sum of voltage swing and pre-emphasis levels cannot in rk_udphy_dp_phy_verify_config()
1158 if (dp->voltage[i] + dp->pre[i] > 3) in rk_udphy_dp_phy_verify_config()
1159 return -EINVAL; in rk_udphy_dp_phy_verify_config()
1167 u32 voltage, u32 pre, u32 lane) in rk_udphy_dp_set_voltage() argument
1169 const struct rk_udphy_cfg *cfg = udphy->cfgs; in rk_udphy_dp_set_voltage()
1171 u32 offset = 0x800 * lane; in rk_udphy_dp_set_voltage()
1174 if (udphy->mux) in rk_udphy_dp_set_voltage()
1175 dp_ctrl = cfg->dp_tx_ctrl_cfg_typec[bw]; in rk_udphy_dp_set_voltage()
1177 dp_ctrl = cfg->dp_tx_ctrl_cfg[bw]; in rk_udphy_dp_set_voltage()
1180 regmap_write(udphy->pma_regmap, 0x0810 + offset, val); in rk_udphy_dp_set_voltage()
1183 regmap_write(udphy->pma_regmap, 0x0814 + offset, val); in rk_udphy_dp_set_voltage()
1186 regmap_write(udphy->pma_regmap, 0x0818 + offset, val); in rk_udphy_dp_set_voltage()
1189 regmap_write(udphy->pma_regmap, 0x081c + offset, val); in rk_udphy_dp_set_voltage()
1196 struct phy_configure_opts_dp *dp = &opts->dp; in rk_udphy_dp_phy_configure() local
1197 u32 i, val, lane; in rk_udphy_dp_phy_configure() local
1200 ret = rk_udphy_dp_phy_verify_config(udphy, dp); in rk_udphy_dp_phy_configure()
1204 if (dp->set_rate) { in rk_udphy_dp_phy_configure()
1205 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, in rk_udphy_dp_phy_configure()
1208 switch (dp->link_rate) { in rk_udphy_dp_phy_configure()
1210 udphy->bw = DP_BW_RBR; in rk_udphy_dp_phy_configure()
1214 udphy->bw = DP_BW_HBR; in rk_udphy_dp_phy_configure()
1218 udphy->bw = DP_BW_HBR2; in rk_udphy_dp_phy_configure()
1222 udphy->bw = DP_BW_HBR3; in rk_udphy_dp_phy_configure()
1226 return -EINVAL; in rk_udphy_dp_phy_configure()
1229 regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW, in rk_udphy_dp_phy_configure()
1230 FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw)); in rk_udphy_dp_phy_configure()
1231 regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN, in rk_udphy_dp_phy_configure()
1232 FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc)); in rk_udphy_dp_phy_configure()
1233 regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN, in rk_udphy_dp_phy_configure()
1236 ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_ROPLL_DONE_OFFSET, val, in rk_udphy_dp_phy_configure()
1241 dev_err(udphy->dev, "ROPLL is not lock, set_rate failed\n"); in rk_udphy_dp_phy_configure()
1246 if (dp->set_voltages) { in rk_udphy_dp_phy_configure()
1247 for (i = 0; i < dp->lanes; i++) { in rk_udphy_dp_phy_configure()
1248 lane = udphy->dp_lane_sel[i]; in rk_udphy_dp_phy_configure()
1249 switch (dp->link_rate) { in rk_udphy_dp_phy_configure()
1252 regmap_update_bits(udphy->pma_regmap, in rk_udphy_dp_phy_configure()
1253 TRSV_ANA_TX_CLK_OFFSET_N(lane), in rk_udphy_dp_phy_configure()
1256 udphy->lane_mux_sel[lane])); in rk_udphy_dp_phy_configure()
1261 regmap_update_bits(udphy->pma_regmap, in rk_udphy_dp_phy_configure()
1262 TRSV_ANA_TX_CLK_OFFSET_N(lane), in rk_udphy_dp_phy_configure()
1268 rk_udphy_dp_set_voltage(udphy, udphy->bw, dp->voltage[i], in rk_udphy_dp_phy_configure()
1269 dp->pre[i], lane); in rk_udphy_dp_phy_configure()
1290 mutex_lock(&udphy->mutex); in rk_udphy_usb3_phy_init()
1291 /* DP only or high-speed, disable U3 port */ in rk_udphy_usb3_phy_init()
1292 if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) { in rk_udphy_usb3_phy_init()
1300 mutex_unlock(&udphy->mutex); in rk_udphy_usb3_phy_init()
1308 mutex_lock(&udphy->mutex); in rk_udphy_usb3_phy_exit()
1309 /* DP only or high-speed */ in rk_udphy_usb3_phy_exit()
1310 if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) in rk_udphy_usb3_phy_exit()
1316 mutex_unlock(&udphy->mutex); in rk_udphy_usb3_phy_exit()
1326 static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux, in rk_udphy_typec_mux_set() argument
1329 struct rk_udphy *udphy = typec_mux_get_drvdata(mux); in rk_udphy_typec_mux_set()
1332 mutex_lock(&udphy->mutex); in rk_udphy_typec_mux_set()
1334 switch (state->mode) { in rk_udphy_typec_mux_set()
1337 udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1338 udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1339 udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1340 udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1346 if (udphy->flip) { in rk_udphy_typec_mux_set()
1347 udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1348 udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1349 udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB; in rk_udphy_typec_mux_set()
1350 udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB; in rk_udphy_typec_mux_set()
1352 udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB; in rk_udphy_typec_mux_set()
1353 udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB; in rk_udphy_typec_mux_set()
1354 udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1355 udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP; in rk_udphy_typec_mux_set()
1361 if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) { in rk_udphy_typec_mux_set()
1362 struct typec_displayport_data *data = state->data; in rk_udphy_typec_mux_set()
1366 } else if (data->status & DP_STATUS_IRQ_HPD) { in rk_udphy_typec_mux_set()
1370 } else if (data->status & DP_STATUS_HPD_STATE) { in rk_udphy_typec_mux_set()
1371 if (udphy->mode != mode) { in rk_udphy_typec_mux_set()
1372 udphy->mode = mode; in rk_udphy_typec_mux_set()
1373 udphy->mode_change = true; in rk_udphy_typec_mux_set()
1381 mutex_unlock(&udphy->mutex); in rk_udphy_typec_mux_set()
1389 typec_mux_unregister(udphy->mux); in rk_udphy_typec_mux_unregister()
1397 mux_desc.fwnode = dev_fwnode(udphy->dev); in rk_udphy_setup_typec_mux()
1400 udphy->mux = typec_mux_register(udphy->dev, &mux_desc); in rk_udphy_setup_typec_mux()
1401 if (IS_ERR(udphy->mux)) { in rk_udphy_setup_typec_mux()
1402 dev_err(udphy->dev, "Error register typec mux: %ld\n", in rk_udphy_setup_typec_mux()
1403 PTR_ERR(udphy->mux)); in rk_udphy_setup_typec_mux()
1404 return PTR_ERR(udphy->mux); in rk_udphy_setup_typec_mux()
1407 return devm_add_action_or_reset(udphy->dev, rk_udphy_typec_mux_unregister, in rk_udphy_setup_typec_mux()
1423 if (args->args_count == 0) in rk_udphy_phy_xlate()
1424 return ERR_PTR(-EINVAL); in rk_udphy_phy_xlate()
1426 switch (args->args[0]) { in rk_udphy_phy_xlate()
1428 return udphy->phy_u3; in rk_udphy_phy_xlate()
1430 return udphy->phy_dp; in rk_udphy_phy_xlate()
1433 return ERR_PTR(-EINVAL); in rk_udphy_phy_xlate()
1438 struct device *dev = &pdev->dev; in rk_udphy_probe()
1447 return -ENOMEM; in rk_udphy_probe()
1449 udphy->cfgs = device_get_match_data(dev); in rk_udphy_probe()
1450 if (!udphy->cfgs) in rk_udphy_probe()
1451 return dev_err_probe(dev, -EINVAL, "missing match data\n"); in rk_udphy_probe()
1457 /* find the phy-id from the io address */ in rk_udphy_probe()
1458 udphy->id = -ENODEV; in rk_udphy_probe()
1459 for (id = 0; id < udphy->cfgs->num_phys; id++) { in rk_udphy_probe()
1460 if (res->start == udphy->cfgs->phy_ids[id]) { in rk_udphy_probe()
1461 udphy->id = id; in rk_udphy_probe()
1466 if (udphy->id < 0) in rk_udphy_probe()
1467 return dev_err_probe(dev, -ENODEV, "no matching device found\n"); in rk_udphy_probe()
1469 udphy->pma_regmap = devm_regmap_init_mmio(dev, base + UDPHY_PMA, in rk_udphy_probe()
1471 if (IS_ERR(udphy->pma_regmap)) in rk_udphy_probe()
1472 return PTR_ERR(udphy->pma_regmap); in rk_udphy_probe()
1474 udphy->dev = dev; in rk_udphy_probe()
1483 mutex_init(&udphy->mutex); in rk_udphy_probe()
1486 if (device_property_present(dev, "orientation-switch")) { in rk_udphy_probe()
1492 if (device_property_present(dev, "mode-switch")) { in rk_udphy_probe()
1498 udphy->phy_u3 = devm_phy_create(dev, dev->of_node, &rk_udphy_usb3_phy_ops); in rk_udphy_probe()
1499 if (IS_ERR(udphy->phy_u3)) { in rk_udphy_probe()
1500 ret = PTR_ERR(udphy->phy_u3); in rk_udphy_probe()
1503 phy_set_drvdata(udphy->phy_u3, udphy); in rk_udphy_probe()
1505 udphy->phy_dp = devm_phy_create(dev, dev->of_node, &rk_udphy_dp_phy_ops); in rk_udphy_probe()
1506 if (IS_ERR(udphy->phy_dp)) { in rk_udphy_probe()
1507 ret = PTR_ERR(udphy->phy_dp); in rk_udphy_probe()
1508 return dev_err_probe(dev, ret, "failed to create DP phy\n"); in rk_udphy_probe()
1510 phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy)); in rk_udphy_probe()
1511 udphy->phy_dp->attrs.max_link_rate = 8100; in rk_udphy_probe()
1512 phy_set_drvdata(udphy->phy_dp, udphy); in rk_udphy_probe()
1527 if (udphy->dp_sink_hpd_sel) in rk_udphy_resume()
1528 rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg); in rk_udphy_resume()
1538 "init", "cmn", "lane", "pcs_apb", "pma_apb"
1550 /* u2phy-grf */
1554 /* usb-grf */
1558 /* usbdpphy-grf */
1588 .compatible = "rockchip,rk3588-usbdp-phy",
1598 .name = "rockchip-usbdp-phy",
1605 MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
1606 MODULE_AUTHOR("Zhang Yubing <yubing.zhang@rock-chips.com>");