.. | .. |
---|
56 | 56 | |
---|
57 | 57 | #include <linux/mfd/syscon.h> |
---|
58 | 58 | #include <linux/phy/phy.h> |
---|
59 | | -#include <linux/phy/phy-rockchip-typec.h> |
---|
| 59 | +#include <linux/usb/typec_mux.h> |
---|
| 60 | +#include <linux/usb/typec_dp.h> |
---|
60 | 61 | |
---|
61 | 62 | #define CMN_SSM_BANDGAP (0x21 << 2) |
---|
62 | 63 | #define CMN_SSM_BIAS (0x22 << 2) |
---|
.. | .. |
---|
844 | 845 | writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane)); |
---|
845 | 846 | } |
---|
846 | 847 | |
---|
847 | | -static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, int link_rate, |
---|
848 | | - u8 swing, u8 pre_emp, u32 lane) |
---|
| 848 | +static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane) |
---|
849 | 849 | { |
---|
850 | | - u16 val; |
---|
851 | | - |
---|
852 | 850 | writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane)); |
---|
853 | 851 | writel(0x6799, tcphy->base + TX_PSC_A0(lane)); |
---|
854 | 852 | writel(0x6798, tcphy->base + TX_PSC_A1(lane)); |
---|
855 | 853 | writel(0x98, tcphy->base + TX_PSC_A2(lane)); |
---|
856 | 854 | writel(0x98, tcphy->base + TX_PSC_A3(lane)); |
---|
857 | | - |
---|
858 | | - writel(tcphy->config[swing][pre_emp].swing, |
---|
859 | | - tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); |
---|
860 | | - writel(tcphy->config[swing][pre_emp].pe, |
---|
861 | | - tcphy->base + TX_TXCC_CPOST_MULT_00(lane)); |
---|
862 | | - |
---|
863 | | - if (swing == 2 && pre_emp == 0 && link_rate != 540000) { |
---|
864 | | - writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane)); |
---|
865 | | - writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); |
---|
866 | | - } else { |
---|
867 | | - writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); |
---|
868 | | - writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane)); |
---|
869 | | - } |
---|
870 | | - |
---|
871 | | - val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); |
---|
872 | | - val = val & 0x8fff; |
---|
873 | | - switch (link_rate) { |
---|
874 | | - case 540000: |
---|
875 | | - val |= (5 << 12); |
---|
876 | | - break; |
---|
877 | | - case 162000: |
---|
878 | | - case 270000: |
---|
879 | | - default: |
---|
880 | | - val |= (6 << 12); |
---|
881 | | - break; |
---|
882 | | - } |
---|
883 | | - writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); |
---|
884 | 855 | } |
---|
885 | 856 | |
---|
886 | | -int tcphy_dp_set_phy_config(struct phy *phy, int link_rate, |
---|
887 | | - int lane_count, u8 swing, u8 pre_emp) |
---|
| 857 | +static int rockchip_dp_phy_set_voltages(struct rockchip_typec_phy *tcphy, |
---|
| 858 | + struct phy_configure_opts_dp *dp) |
---|
888 | 859 | { |
---|
889 | | - struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); |
---|
890 | | - u8 i; |
---|
| 860 | + u8 i, j, lane; |
---|
| 861 | + u32 val; |
---|
891 | 862 | |
---|
892 | | - if (!phy->power_count) |
---|
893 | | - return -EPERM; |
---|
894 | 863 | |
---|
895 | | - if (tcphy->mode == MODE_DFP_DP) { |
---|
896 | | - for (i = 0; i < 4; i++) |
---|
897 | | - tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, i); |
---|
| 864 | + if (dp->lanes == 4) { |
---|
| 865 | + i = 0; |
---|
| 866 | + j = 3; |
---|
898 | 867 | } else { |
---|
899 | 868 | if (tcphy->flip) { |
---|
900 | | - tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 0); |
---|
901 | | - tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 1); |
---|
| 869 | + i = 0; |
---|
| 870 | + j = 1; |
---|
902 | 871 | } else { |
---|
903 | | - tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 2); |
---|
904 | | - tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 3); |
---|
| 872 | + i = 2; |
---|
| 873 | + j = 3; |
---|
905 | 874 | } |
---|
| 875 | + } |
---|
| 876 | + |
---|
| 877 | + for (lane = i; lane <= j; lane++) { |
---|
| 878 | + writel(tcphy->config[dp->voltage[lane]][dp->pre[lane]].swing, |
---|
| 879 | + tcphy->base + TX_TXCC_MGNFS_MULT_000(lane)); |
---|
| 880 | + writel(tcphy->config[dp->voltage[lane]][dp->pre[lane]].pe, |
---|
| 881 | + tcphy->base + TX_TXCC_CPOST_MULT_00(lane)); |
---|
| 882 | + |
---|
| 883 | + if (dp->voltage[lane] == 2 && dp->pre[lane] == 0 && dp->link_rate != 540000) { |
---|
| 884 | + writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane)); |
---|
| 885 | + writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); |
---|
| 886 | + } else { |
---|
| 887 | + writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane)); |
---|
| 888 | + writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane)); |
---|
| 889 | + } |
---|
| 890 | + |
---|
| 891 | + val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); |
---|
| 892 | + val &= ~GENMASK(14, 12); |
---|
| 893 | + val |= ((dp->link_rate == 540000) ? 0x5 : 0x6) << 12; |
---|
| 894 | + writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane)); |
---|
906 | 895 | } |
---|
907 | 896 | |
---|
908 | 897 | return 0; |
---|
909 | 898 | } |
---|
910 | | -EXPORT_SYMBOL(tcphy_dp_set_phy_config); |
---|
911 | 899 | |
---|
912 | | -int tcphy_dp_set_lane_count(struct phy *phy, u8 lane_count) |
---|
| 900 | +static int rockchip_dp_phy_set_lanes(struct rockchip_typec_phy *tcphy, |
---|
| 901 | + struct phy_configure_opts_dp *dp) |
---|
913 | 902 | { |
---|
914 | | - struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); |
---|
915 | 903 | u32 reg; |
---|
916 | | - |
---|
917 | | - if (!phy->power_count) |
---|
918 | | - return -EPERM; |
---|
919 | 904 | |
---|
920 | 905 | /* |
---|
921 | 906 | * In cases where fewer than the configured number of DP lanes are |
---|
.. | .. |
---|
927 | 912 | reg = readl(tcphy->base + PHY_DP_MODE_CTL); |
---|
928 | 913 | reg |= PHY_DP_LANE_DISABLE; |
---|
929 | 914 | |
---|
930 | | - switch (lane_count) { |
---|
| 915 | + switch (dp->lanes) { |
---|
931 | 916 | case 4: |
---|
932 | 917 | reg &= ~(PHY_DP_LANE_3_DISABLE | PHY_DP_LANE_2_DISABLE | |
---|
933 | 918 | PHY_DP_LANE_1_DISABLE | PHY_DP_LANE_0_DISABLE); |
---|
.. | .. |
---|
946 | 931 | |
---|
947 | 932 | return 0; |
---|
948 | 933 | } |
---|
949 | | -EXPORT_SYMBOL(tcphy_dp_set_lane_count); |
---|
950 | 934 | |
---|
951 | | -int tcphy_dp_set_link_rate(struct phy *phy, int link_rate, bool ssc_on) |
---|
| 935 | +static int rockchip_dp_phy_set_rate(struct rockchip_typec_phy *tcphy, |
---|
| 936 | + struct phy_configure_opts_dp *dp) |
---|
952 | 937 | { |
---|
953 | | - struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); |
---|
954 | 938 | const struct phy_reg *phy_cfg; |
---|
955 | 939 | u32 cmn_diag_hsclk_sel, phy_dp_clk_ctl, reg; |
---|
956 | 940 | u32 i, cfg_size; |
---|
957 | 941 | int ret; |
---|
958 | | - |
---|
959 | | - if (!phy->power_count) |
---|
960 | | - return -EPERM; |
---|
961 | 942 | |
---|
962 | 943 | /* Place the PHY lanes in the A3 power state. */ |
---|
963 | 944 | ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A3); |
---|
.. | .. |
---|
1001 | 982 | phy_dp_clk_ctl = readl(tcphy->base + PHY_DP_CLK_CTL); |
---|
1002 | 983 | phy_dp_clk_ctl &= ~(GENMASK(15, 12) | GENMASK(11, 8)); |
---|
1003 | 984 | |
---|
1004 | | - switch (link_rate) { |
---|
1005 | | - case 162000: |
---|
| 985 | + switch (dp->link_rate) { |
---|
| 986 | + case 1620: |
---|
1006 | 987 | cmn_diag_hsclk_sel |= (3 << 4) | (0 << 0); |
---|
1007 | 988 | phy_dp_clk_ctl |= (2 << 12) | (4 << 8); |
---|
1008 | 989 | |
---|
1009 | | - phy_cfg = ssc_on ? dp_pll_rbr_ssc_cfg : dp_pll_rbr_cfg; |
---|
1010 | | - cfg_size = ssc_on ? ARRAY_SIZE(dp_pll_rbr_ssc_cfg) : |
---|
| 990 | + phy_cfg = dp->ssc ? dp_pll_rbr_ssc_cfg : dp_pll_rbr_cfg; |
---|
| 991 | + cfg_size = dp->ssc ? ARRAY_SIZE(dp_pll_rbr_ssc_cfg) : |
---|
1011 | 992 | ARRAY_SIZE(dp_pll_rbr_cfg); |
---|
1012 | 993 | break; |
---|
1013 | | - case 270000: |
---|
| 994 | + case 2700: |
---|
1014 | 995 | cmn_diag_hsclk_sel |= (3 << 4) | (0 << 0); |
---|
1015 | 996 | phy_dp_clk_ctl |= (2 << 12) | (4 << 8); |
---|
1016 | 997 | |
---|
1017 | | - phy_cfg = ssc_on ? dp_pll_hbr_ssc_cfg : dp_pll_hbr_cfg; |
---|
1018 | | - cfg_size = ssc_on ? ARRAY_SIZE(dp_pll_hbr_ssc_cfg) : |
---|
| 998 | + phy_cfg = dp->ssc ? dp_pll_hbr_ssc_cfg : dp_pll_hbr_cfg; |
---|
| 999 | + cfg_size = dp->ssc ? ARRAY_SIZE(dp_pll_hbr_ssc_cfg) : |
---|
1019 | 1000 | ARRAY_SIZE(dp_pll_hbr_cfg); |
---|
1020 | 1001 | break; |
---|
1021 | | - case 540000: |
---|
| 1002 | + case 5400: |
---|
1022 | 1003 | cmn_diag_hsclk_sel |= (2 << 4) | (0 << 0); |
---|
1023 | 1004 | phy_dp_clk_ctl |= (1 << 12) | (2 << 8); |
---|
1024 | 1005 | |
---|
1025 | | - phy_cfg = ssc_on ? dp_pll_hbr2_ssc_cfg : dp_pll_hbr2_cfg; |
---|
1026 | | - cfg_size = ssc_on ? ARRAY_SIZE(dp_pll_hbr2_ssc_cfg) : |
---|
| 1006 | + phy_cfg = dp->ssc ? dp_pll_hbr2_ssc_cfg : dp_pll_hbr2_cfg; |
---|
| 1007 | + cfg_size = dp->ssc ? ARRAY_SIZE(dp_pll_hbr2_ssc_cfg) : |
---|
1027 | 1008 | ARRAY_SIZE(dp_pll_hbr2_cfg); |
---|
1028 | 1009 | break; |
---|
1029 | 1010 | default: |
---|
.. | .. |
---|
1081 | 1062 | |
---|
1082 | 1063 | return 0; |
---|
1083 | 1064 | } |
---|
1084 | | -EXPORT_SYMBOL(tcphy_dp_set_link_rate); |
---|
1085 | 1065 | |
---|
1086 | 1066 | static inline int property_enable(struct rockchip_typec_phy *tcphy, |
---|
1087 | 1067 | const struct usb3phy_reg *reg, bool en) |
---|
.. | .. |
---|
1287 | 1267 | tcphy_cfg_usb3_to_usb2_only(tcphy, true); |
---|
1288 | 1268 | tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE); |
---|
1289 | 1269 | for (i = 0; i < 4; i++) |
---|
1290 | | - tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, i); |
---|
| 1270 | + tcphy_dp_cfg_lane(tcphy, i); |
---|
1291 | 1271 | } else { |
---|
1292 | 1272 | tcphy_cfg_usb3_pll(tcphy); |
---|
1293 | 1273 | tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE); |
---|
1294 | 1274 | if (tcphy->flip) { |
---|
1295 | 1275 | tcphy_tx_usb3_cfg_lane(tcphy, 3); |
---|
1296 | 1276 | tcphy_rx_usb3_cfg_lane(tcphy, 2); |
---|
1297 | | - tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 0); |
---|
1298 | | - tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 1); |
---|
| 1277 | + tcphy_dp_cfg_lane(tcphy, 0); |
---|
| 1278 | + tcphy_dp_cfg_lane(tcphy, 1); |
---|
1299 | 1279 | } else { |
---|
1300 | 1280 | tcphy_tx_usb3_cfg_lane(tcphy, 0); |
---|
1301 | 1281 | tcphy_rx_usb3_cfg_lane(tcphy, 1); |
---|
1302 | | - tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 2); |
---|
1303 | | - tcphy_dp_cfg_lane(tcphy, DP_DEFAULT_RATE, 0, 0, 3); |
---|
| 1282 | + tcphy_dp_cfg_lane(tcphy, 2); |
---|
| 1283 | + tcphy_dp_cfg_lane(tcphy, 3); |
---|
1304 | 1284 | } |
---|
1305 | 1285 | } |
---|
1306 | 1286 | |
---|
.. | .. |
---|
1578 | 1558 | return 0; |
---|
1579 | 1559 | } |
---|
1580 | 1560 | |
---|
| 1561 | +static int rockchip_dp_phy_verify_config(struct rockchip_typec_phy *tcphy, |
---|
| 1562 | + struct phy_configure_opts_dp *dp) |
---|
| 1563 | +{ |
---|
| 1564 | + u8 i; |
---|
| 1565 | + |
---|
| 1566 | + /* If changing link rate was required, verify it's supported. */ |
---|
| 1567 | + if (dp->set_rate) { |
---|
| 1568 | + switch (dp->link_rate) { |
---|
| 1569 | + case 1620: |
---|
| 1570 | + case 2700: |
---|
| 1571 | + case 5400: |
---|
| 1572 | + /* valid bit rate */ |
---|
| 1573 | + break; |
---|
| 1574 | + default: |
---|
| 1575 | + return -EINVAL; |
---|
| 1576 | + } |
---|
| 1577 | + } |
---|
| 1578 | + |
---|
| 1579 | + /* Verify lane count. */ |
---|
| 1580 | + switch (dp->lanes) { |
---|
| 1581 | + case 1: |
---|
| 1582 | + case 2: |
---|
| 1583 | + case 4: |
---|
| 1584 | + /* valid lane count. */ |
---|
| 1585 | + break; |
---|
| 1586 | + default: |
---|
| 1587 | + return -EINVAL; |
---|
| 1588 | + } |
---|
| 1589 | + |
---|
| 1590 | + /* |
---|
| 1591 | + * If changing voltages is required, check swing and pre-emphasis |
---|
| 1592 | + * levels, per-lane. |
---|
| 1593 | + */ |
---|
| 1594 | + if (dp->set_voltages) { |
---|
| 1595 | + /* Lane count verified previously. */ |
---|
| 1596 | + for (i = 0; i < dp->lanes; i++) { |
---|
| 1597 | + if (dp->voltage[i] > 3 || dp->pre[i] > 3) |
---|
| 1598 | + return -EINVAL; |
---|
| 1599 | + |
---|
| 1600 | + /* Sum of voltage swing and pre-emphasis levels cannot |
---|
| 1601 | + * exceed 3. |
---|
| 1602 | + */ |
---|
| 1603 | + if (dp->voltage[i] + dp->pre[i] > 3) |
---|
| 1604 | + return -EINVAL; |
---|
| 1605 | + } |
---|
| 1606 | + } |
---|
| 1607 | + |
---|
| 1608 | + return 0; |
---|
| 1609 | +} |
---|
| 1610 | + |
---|
| 1611 | +static int rockchip_dp_phy_configure(struct phy *phy, |
---|
| 1612 | + union phy_configure_opts *opts) |
---|
| 1613 | +{ |
---|
| 1614 | + struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy); |
---|
| 1615 | + int ret; |
---|
| 1616 | + |
---|
| 1617 | + if (!phy->power_count) |
---|
| 1618 | + return -EPERM; |
---|
| 1619 | + |
---|
| 1620 | + ret = rockchip_dp_phy_verify_config(tcphy, &opts->dp); |
---|
| 1621 | + if (ret) { |
---|
| 1622 | + dev_err(&phy->dev, "invalid params for phy configure\n"); |
---|
| 1623 | + return ret; |
---|
| 1624 | + } |
---|
| 1625 | + |
---|
| 1626 | + if (opts->dp.set_lanes) { |
---|
| 1627 | + ret = rockchip_dp_phy_set_lanes(tcphy, &opts->dp); |
---|
| 1628 | + if (ret) { |
---|
| 1629 | + dev_err(&phy->dev, "rockchip_dp_phy_set_lanes failed\n"); |
---|
| 1630 | + return ret; |
---|
| 1631 | + } |
---|
| 1632 | + } |
---|
| 1633 | + |
---|
| 1634 | + if (opts->dp.set_rate) { |
---|
| 1635 | + ret = rockchip_dp_phy_set_rate(tcphy, &opts->dp); |
---|
| 1636 | + if (ret) { |
---|
| 1637 | + dev_err(&phy->dev, "rockchip_dp_phy_set_rate failed\n"); |
---|
| 1638 | + return ret; |
---|
| 1639 | + } |
---|
| 1640 | + } |
---|
| 1641 | + |
---|
| 1642 | + if (opts->dp.set_voltages) { |
---|
| 1643 | + ret = rockchip_dp_phy_set_voltages(tcphy, &opts->dp); |
---|
| 1644 | + if (ret) { |
---|
| 1645 | + dev_err(&phy->dev, "rockchip_dp_phy_set_voltages failed\n"); |
---|
| 1646 | + return ret; |
---|
| 1647 | + } |
---|
| 1648 | + } |
---|
| 1649 | + |
---|
| 1650 | + return 0; |
---|
| 1651 | +} |
---|
| 1652 | + |
---|
1581 | 1653 | static const struct phy_ops rockchip_dp_phy_ops = { |
---|
1582 | 1654 | .power_on = rockchip_dp_phy_power_on, |
---|
1583 | 1655 | .power_off = rockchip_dp_phy_power_off, |
---|
| 1656 | + .configure = rockchip_dp_phy_configure, |
---|
1584 | 1657 | .owner = THIS_MODULE, |
---|
1585 | 1658 | }; |
---|
1586 | 1659 | |
---|