blob: da92a39c6854dc88b7f0de5c107746013cd4f2bd [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From 3ef64d448a36853279de5324f9bf00041b9f3ce5 Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:06:25 +0800
4Subject: [PATCH]
developer3de3aca2023-06-07 20:44:59 +08005 [high-speed-io][999-2610-tphy-support-type-switch-by-pericfg.patch]
developerc66d4ac2021-09-17 16:27:09 +08006
developerc66d4ac2021-09-17 16:27:09 +08007---
developer8cdcb262022-10-27 14:36:15 +08008 drivers/phy/mediatek/phy-mtk-tphy.c | 83 ++++++++++++++++++++++++++++-
9 1 file changed, 81 insertions(+), 2 deletions(-)
developerc66d4ac2021-09-17 16:27:09 +080010
11diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
developer5d148cb2023-06-02 13:08:11 +080012index d1ecf0880..c6e073401 100644
developerc66d4ac2021-09-17 16:27:09 +080013--- a/drivers/phy/mediatek/phy-mtk-tphy.c
14+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
developer8cdcb262022-10-27 14:36:15 +080015@@ -10,6 +10,7 @@
developerc66d4ac2021-09-17 16:27:09 +080016 #include <linux/delay.h>
17 #include <linux/io.h>
18 #include <linux/iopoll.h>
19+#include <linux/mfd/syscon.h>
20 #include <linux/module.h>
21 #include <linux/of_address.h>
22 #include <linux/of_device.h>
developer5d148cb2023-06-02 13:08:11 +080023@@ -268,6 +269,14 @@
24 #define HIF_SYSCFG1 0x14
25 #define HIF_SYSCFG1_PHY2_MASK (0x3 << 20)
developerc66d4ac2021-09-17 16:27:09 +080026
27+/* PHY switch between pcie/usb3/sgmii/sata */
28+#define USB_PHY_SWITCH_CTRL 0x0
29+#define RG_PHY_SW_TYPE GENMASK(3, 0)
30+#define RG_PHY_SW_PCIE 0x0
31+#define RG_PHY_SW_USB3 0x1
32+#define RG_PHY_SW_SGMII 0x2
33+#define RG_PHY_SW_SATA 0x3
34+
35 enum mtk_phy_version {
36 MTK_PHY_V1 = 1,
37 MTK_PHY_V2,
developer5d148cb2023-06-02 13:08:11 +080038@@ -301,7 +310,10 @@ struct mtk_phy_instance {
developerc66d4ac2021-09-17 16:27:09 +080039 };
40 struct clk *ref_clk; /* reference clock of anolog phy */
41 u32 index;
42- u8 type;
43+ u32 type;
44+ struct regmap *type_sw;
45+ u32 type_sw_reg;
46+ u32 type_sw_index;
47 int eye_src;
48 int eye_vrt;
49 int eye_term;
developer5d148cb2023-06-02 13:08:11 +080050@@ -900,6 +912,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
developerc66d4ac2021-09-17 16:27:09 +080051 }
52 }
53
54+/* type switch for usb3/pcie/sgmii/sata */
55+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
56+ struct device_node *dn)
57+{
58+ struct of_phandle_args args;
59+ int ret;
60+
61+ /* type switch function is optional */
62+ if (!of_property_read_bool(dn, "mediatek,syscon-type"))
63+ return 0;
64+
65+ ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
66+ 2, 0, &args);
67+ if (ret)
68+ return ret;
69+
70+ instance->type_sw_reg = args.args[0];
71+ instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
72+ instance->type_sw = syscon_node_to_regmap(args.np);
73+ of_node_put(args.np);
74+ dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
75+ instance->type_sw_reg, instance->type_sw_index);
76+
77+ return PTR_ERR_OR_ZERO(instance->type_sw);
78+}
79+
80+static int phy_type_set(struct mtk_phy_instance *instance)
81+{
82+ int type;
83+ u32 mask;
84+
85+ if (!instance->type_sw)
86+ return 0;
87+
88+ switch (instance->type) {
89+ case PHY_TYPE_USB3:
90+ type = RG_PHY_SW_USB3;
91+ break;
92+ case PHY_TYPE_PCIE:
93+ type = RG_PHY_SW_PCIE;
94+ break;
95+ case PHY_TYPE_SGMII:
96+ type = RG_PHY_SW_SGMII;
97+ break;
98+ case PHY_TYPE_SATA:
99+ type = RG_PHY_SW_SATA;
100+ break;
101+ case PHY_TYPE_USB2:
102+ default:
103+ return 0;
104+ }
105+
106+ mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
107+ regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
108+
109+ return 0;
110+}
111+
112 static int mtk_phy_init(struct phy *phy)
113 {
114 struct mtk_phy_instance *instance = phy_get_drvdata(phy);
developer5d148cb2023-06-02 13:08:11 +0800115@@ -932,6 +1002,9 @@ static int mtk_phy_init(struct phy *phy)
developerc66d4ac2021-09-17 16:27:09 +0800116 case PHY_TYPE_SATA:
117 sata_phy_instance_init(tphy, instance);
118 break;
119+ case PHY_TYPE_SGMII:
120+ /* nothing to do, only used to set type */
121+ break;
122 default:
123 dev_err(tphy->dev, "incompatible PHY type\n");
124 return -EINVAL;
developer5d148cb2023-06-02 13:08:11 +0800125@@ -1020,7 +1093,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
developerc66d4ac2021-09-17 16:27:09 +0800126 if (!(instance->type == PHY_TYPE_USB2 ||
127 instance->type == PHY_TYPE_USB3 ||
128 instance->type == PHY_TYPE_PCIE ||
129- instance->type == PHY_TYPE_SATA)) {
130+ instance->type == PHY_TYPE_SATA ||
131+ instance->type == PHY_TYPE_SGMII)) {
132 dev_err(dev, "unsupported device type: %d\n", instance->type);
133 return ERR_PTR(-EINVAL);
134 }
developer5d148cb2023-06-02 13:08:11 +0800135@@ -1035,6 +1109,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
developerc66d4ac2021-09-17 16:27:09 +0800136 }
137
138 phy_parse_property(tphy, instance);
139+ phy_type_set(instance);
140
141 return instance->phy;
142 }
developer5d148cb2023-06-02 13:08:11 +0800143@@ -1183,6 +1258,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
developerc66d4ac2021-09-17 16:27:09 +0800144 retval = PTR_ERR(instance->ref_clk);
145 goto put_child;
146 }
147+
148+ retval = phy_type_syscon_get(instance, child_np);
149+ if (retval)
150+ goto put_child;
151 }
152
153 provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
154--
developer5d148cb2023-06-02 13:08:11 +08001552.34.1
developerc66d4ac2021-09-17 16:27:09 +0800156