hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/phy/rockchip/phy-rockchip-typec.c
....@@ -56,7 +56,8 @@
5656
5757 #include <linux/mfd/syscon.h>
5858 #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>
6061
6162 #define CMN_SSM_BANDGAP (0x21 << 2)
6263 #define CMN_SSM_BIAS (0x22 << 2)
....@@ -844,78 +845,62 @@
844845 writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
845846 }
846847
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)
849849 {
850
- u16 val;
851
-
852850 writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
853851 writel(0x6799, tcphy->base + TX_PSC_A0(lane));
854852 writel(0x6798, tcphy->base + TX_PSC_A1(lane));
855853 writel(0x98, tcphy->base + TX_PSC_A2(lane));
856854 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));
884855 }
885856
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)
888859 {
889
- struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
890
- u8 i;
860
+ u8 i, j, lane;
861
+ u32 val;
891862
892
- if (!phy->power_count)
893
- return -EPERM;
894863
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;
898867 } else {
899868 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;
902871 } 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;
905874 }
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));
906895 }
907896
908897 return 0;
909898 }
910
-EXPORT_SYMBOL(tcphy_dp_set_phy_config);
911899
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)
913902 {
914
- struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
915903 u32 reg;
916
-
917
- if (!phy->power_count)
918
- return -EPERM;
919904
920905 /*
921906 * In cases where fewer than the configured number of DP lanes are
....@@ -927,7 +912,7 @@
927912 reg = readl(tcphy->base + PHY_DP_MODE_CTL);
928913 reg |= PHY_DP_LANE_DISABLE;
929914
930
- switch (lane_count) {
915
+ switch (dp->lanes) {
931916 case 4:
932917 reg &= ~(PHY_DP_LANE_3_DISABLE | PHY_DP_LANE_2_DISABLE |
933918 PHY_DP_LANE_1_DISABLE | PHY_DP_LANE_0_DISABLE);
....@@ -946,18 +931,14 @@
946931
947932 return 0;
948933 }
949
-EXPORT_SYMBOL(tcphy_dp_set_lane_count);
950934
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)
952937 {
953
- struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
954938 const struct phy_reg *phy_cfg;
955939 u32 cmn_diag_hsclk_sel, phy_dp_clk_ctl, reg;
956940 u32 i, cfg_size;
957941 int ret;
958
-
959
- if (!phy->power_count)
960
- return -EPERM;
961942
962943 /* Place the PHY lanes in the A3 power state. */
963944 ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A3);
....@@ -1001,29 +982,29 @@
1001982 phy_dp_clk_ctl = readl(tcphy->base + PHY_DP_CLK_CTL);
1002983 phy_dp_clk_ctl &= ~(GENMASK(15, 12) | GENMASK(11, 8));
1003984
1004
- switch (link_rate) {
1005
- case 162000:
985
+ switch (dp->link_rate) {
986
+ case 1620:
1006987 cmn_diag_hsclk_sel |= (3 << 4) | (0 << 0);
1007988 phy_dp_clk_ctl |= (2 << 12) | (4 << 8);
1008989
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) :
1011992 ARRAY_SIZE(dp_pll_rbr_cfg);
1012993 break;
1013
- case 270000:
994
+ case 2700:
1014995 cmn_diag_hsclk_sel |= (3 << 4) | (0 << 0);
1015996 phy_dp_clk_ctl |= (2 << 12) | (4 << 8);
1016997
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) :
10191000 ARRAY_SIZE(dp_pll_hbr_cfg);
10201001 break;
1021
- case 540000:
1002
+ case 5400:
10221003 cmn_diag_hsclk_sel |= (2 << 4) | (0 << 0);
10231004 phy_dp_clk_ctl |= (1 << 12) | (2 << 8);
10241005
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) :
10271008 ARRAY_SIZE(dp_pll_hbr2_cfg);
10281009 break;
10291010 default:
....@@ -1081,7 +1062,6 @@
10811062
10821063 return 0;
10831064 }
1084
-EXPORT_SYMBOL(tcphy_dp_set_link_rate);
10851065
10861066 static inline int property_enable(struct rockchip_typec_phy *tcphy,
10871067 const struct usb3phy_reg *reg, bool en)
....@@ -1287,20 +1267,20 @@
12871267 tcphy_cfg_usb3_to_usb2_only(tcphy, true);
12881268 tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE);
12891269 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);
12911271 } else {
12921272 tcphy_cfg_usb3_pll(tcphy);
12931273 tcphy_cfg_dp_pll(tcphy, DP_DEFAULT_RATE);
12941274 if (tcphy->flip) {
12951275 tcphy_tx_usb3_cfg_lane(tcphy, 3);
12961276 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);
12991279 } else {
13001280 tcphy_tx_usb3_cfg_lane(tcphy, 0);
13011281 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);
13041284 }
13051285 }
13061286
....@@ -1578,9 +1558,102 @@
15781558 return 0;
15791559 }
15801560
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
+
15811653 static const struct phy_ops rockchip_dp_phy_ops = {
15821654 .power_on = rockchip_dp_phy_power_on,
15831655 .power_off = rockchip_dp_phy_power_off,
1656
+ .configure = rockchip_dp_phy_configure,
15841657 .owner = THIS_MODULE,
15851658 };
15861659