Skip to content

Commit bcdc86e

Browse files
committed
realtek: add xhci usb and phy-rtk-usb3 support for rtl9607
This commit adds support for XHCI controller on RTL9607 with the help of generic-xhci driver. There is also a patch that adds support for rtl9607 to the existing phy-rtk-usb3 driver. Signed-off-by: Rustam Adilov <adilov@tutamail.com>
1 parent bba6205 commit bcdc86e

3 files changed

Lines changed: 225 additions & 1 deletion

File tree

target/linux/realtek/dts/rtl960x.dtsi

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,25 @@
264264
force-little-endian;
265265
};
266266

267+
usb3_phy: usb-phy@18140100 {
268+
compatible = "realtek,rtl9607-usb3phy";
269+
reg = <0x18140100 0x10>;
270+
#phy-cells = <0>;
271+
resets = <&ip_en_rst1 31>, <&ip_en_rst1 26>, <&ip_en_rst 29>, <&ip_en_rst 30>;
272+
reset-names = "usb3-sel-axi", "usb3-axi", "usb3-phy", "p0-usb2phy";
273+
};
274+
275+
xhci: xhci@18060000 {
276+
compatible = "generic-xhci";
277+
reg = <0x18060000 0xf000>;
278+
phys = <&usb3_phy>;
279+
phy-names = "usb3-phy";
280+
interrupt-parent = <&gic>;
281+
interrupts = <GIC_SHARED 52 IRQ_TYPE_LEVEL_HIGH>;
282+
resets = <&ip_en_rst1 30>, <&ip_en_rst 4>, <&ip_en_rst 5>;
283+
reset-names = "usb2host-mux", "p0-usbhost0", "p0-usbhost1";
284+
};
285+
267286
i2cclock: i2cclock {
268287
#clock-cells = <0>;
269288
compatible = "fixed-clock";
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
--- a/drivers/phy/realtek/phy-rtk-usb3.c
2+
+++ b/drivers/phy/realtek/phy-rtk-usb3.c
3+
@@ -17,12 +17,14 @@
4+
#include <linux/sys_soc.h>
5+
#include <linux/mfd/syscon.h>
6+
#include <linux/phy/phy.h>
7+
+#include <linux/reset.h>
8+
#include <linux/usb.h>
9+
10+
#define USB_MDIO_CTRL_PHY_BUSY BIT(7)
11+
#define USB_MDIO_CTRL_PHY_WRITE BIT(0)
12+
#define USB_MDIO_CTRL_PHY_ADDR_SHIFT 8
13+
#define USB_MDIO_CTRL_PHY_DATA_SHIFT 16
14+
+#define USB_MDIO_CTRL_9607_PHY_BUSY BIT(4)
15+
16+
#define MAX_USB_PHY_DATA_SIZE 0x30
17+
#define PHY_ADDR_0X09 0x09
18+
@@ -51,8 +53,15 @@
19+
#define PHY_ADDR_MAP_ARRAY_INDEX(addr) (addr)
20+
#define ARRAY_INDEX_MAP_PHY_ADDR(index) (index)
21+
22+
+#define USB_U3_IPCFG 0x8
23+
+#define USB_U3_IPCFG_HOST_ORDER BIT(6)
24+
+#define USB_U3_IPCFG_U2_WAKE BIT(1)
25+
+#define USB_U3_IPCFG_RX50T BIT(27)
26+
+
27+
struct phy_reg {
28+
void __iomem *reg_mdio_ctl;
29+
+ u32 busy_bit;
30+
+ u32 poll_result;
31+
};
32+
33+
struct phy_data {
34+
@@ -69,6 +78,9 @@ struct phy_cfg {
35+
bool do_toggle_once;
36+
bool use_default_parameter;
37+
bool check_rx_front_end_offset;
38+
+ u32 busy_bit;
39+
+ u32 poll_result;
40+
+ bool do_ip_config;
41+
};
42+
43+
struct phy_parameter {
44+
@@ -88,6 +100,7 @@ struct rtk_phy {
45+
struct phy_cfg *phy_cfg;
46+
int num_phy;
47+
struct phy_parameter *phy_parameter;
48+
+ struct reset_control *phy_rst;
49+
50+
struct dentry *debug_dir;
51+
};
52+
@@ -112,7 +125,7 @@ static inline int utmi_wait_register(voi
53+
54+
static int rtk_phy3_wait_vbusy(struct phy_reg *phy_reg)
55+
{
56+
- return utmi_wait_register(phy_reg->reg_mdio_ctl, USB_MDIO_CTRL_PHY_BUSY, 0);
57+
+ return utmi_wait_register(phy_reg->reg_mdio_ctl, phy_reg->busy_bit, phy_reg->poll_result);
58+
}
59+
60+
static u16 rtk_phy_read(struct phy_reg *phy_reg, char addr)
61+
@@ -191,6 +204,26 @@ static int do_rtk_phy_init(struct rtk_ph
62+
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
63+
phy_reg = &phy_parameter->phy_reg;
64+
65+
+ reset_control_deassert(rtk_phy->phy_rst);
66+
+
67+
+ mdelay(10);
68+
+
69+
+ if (phy_cfg->do_ip_config) {
70+
+ void __iomem *ipcfg_reg = phy_reg->reg_mdio_ctl + USB_U3_IPCFG;
71+
+ u32 value;
72+
+
73+
+ mdelay(10);
74+
+
75+
+ value = readl(ipcfg_reg);
76+
+ value &= ~USB_U3_IPCFG_HOST_ORDER; /* host-order */
77+
+ value |= USB_U3_IPCFG_U2_WAKE | USB_U3_IPCFG_RX50T; /* wake u2 && disable RX50T */
78+
+ writel(value, ipcfg_reg);
79+
+
80+
+ mdelay(10);
81+
+
82+
+ writel(value & ~USB_U3_IPCFG_RX50T, ipcfg_reg); /* put it back RX50T */
83+
+ }
84+
+
85+
if (phy_cfg->use_default_parameter)
86+
goto do_toggle;
87+
88+
@@ -523,6 +556,7 @@ static void update_amplitude_control_val
89+
90+
static int parse_phy_data(struct rtk_phy *rtk_phy)
91+
{
92+
+ struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;
93+
struct device *dev = rtk_phy->dev;
94+
struct phy_parameter *phy_parameter;
95+
int ret = 0;
96+
@@ -537,6 +571,8 @@ static int parse_phy_data(struct rtk_phy
97+
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
98+
99+
phy_parameter->phy_reg.reg_mdio_ctl = of_iomap(dev->of_node, 0) + index;
100+
+ phy_parameter->phy_reg.busy_bit = phy_cfg->busy_bit;
101+
+ phy_parameter->phy_reg.poll_result = phy_cfg->poll_result;
102+
103+
/* Amplitude control address 0x20 bit 0 to bit 7 */
104+
if (of_property_read_u32(dev->of_node, "realtek,amplitude-control-coarse-tuning",
105+
@@ -584,6 +620,12 @@ static int rtk_usb3phy_probe(struct plat
106+
107+
rtk_phy->num_phy = 1;
108+
109+
+ rtk_phy->phy_rst = devm_reset_control_array_get_optional_exclusive(dev);
110+
+ if (IS_ERR(rtk_phy->phy_rst)) {
111+
+ dev_err(dev, "usb3 phy resets are not working\n");
112+
+ return PTR_ERR(rtk_phy->phy_rst);
113+
+ }
114+
+
115+
ret = parse_phy_data(rtk_phy);
116+
if (ret)
117+
goto err;
118+
@@ -644,6 +686,9 @@ static const struct phy_cfg rtd1295_phy_
119+
.do_toggle_once = false,
120+
.use_default_parameter = false,
121+
.check_rx_front_end_offset = false,
122+
+ .busy_bit = USB_MDIO_CTRL_PHY_BUSY,
123+
+ .poll_result = 0,
124+
+ .do_ip_config = false,
125+
};
126+
127+
static const struct phy_cfg rtd1619_phy_cfg = {
128+
@@ -656,6 +701,9 @@ static const struct phy_cfg rtd1619_phy_
129+
.do_toggle_once = false,
130+
.use_default_parameter = false,
131+
.check_rx_front_end_offset = false,
132+
+ .busy_bit = USB_MDIO_CTRL_PHY_BUSY,
133+
+ .poll_result = 0,
134+
+ .do_ip_config = false,
135+
};
136+
137+
static const struct phy_cfg rtd1319_phy_cfg = {
138+
@@ -676,6 +724,9 @@ static const struct phy_cfg rtd1319_phy_
139+
.do_toggle_once = false,
140+
.use_default_parameter = false,
141+
.check_rx_front_end_offset = false,
142+
+ .busy_bit = USB_MDIO_CTRL_PHY_BUSY,
143+
+ .poll_result = 0,
144+
+ .do_ip_config = false,
145+
};
146+
147+
static const struct phy_cfg rtd1619b_phy_cfg = {
148+
@@ -699,6 +750,9 @@ static const struct phy_cfg rtd1619b_phy
149+
.do_toggle_once = true,
150+
.use_default_parameter = false,
151+
.check_rx_front_end_offset = false,
152+
+ .busy_bit = USB_MDIO_CTRL_PHY_BUSY,
153+
+ .poll_result = 0,
154+
+ .do_ip_config = false,
155+
};
156+
157+
static const struct phy_cfg rtd1319d_phy_cfg = {
158+
@@ -722,6 +776,37 @@ static const struct phy_cfg rtd1319d_ph
159+
.do_toggle_once = true,
160+
.use_default_parameter = false,
161+
.check_rx_front_end_offset = true,
162+
+ .busy_bit = USB_MDIO_CTRL_PHY_BUSY,
163+
+ .poll_result = 0,
164+
+ .do_ip_config = false,
165+
+};
166+
+
167+
+static const struct phy_cfg rtl9607_phy_cfg = {
168+
+ .param_size = MAX_USB_PHY_DATA_SIZE,
169+
+ .param = { [1] = {0x01, 0xac89},
170+
+ [6] = {0x06, 0x0019},
171+
+ [7] = {0x07, 0x0600},
172+
+ [8] = {0x08, 0x3261},
173+
+ [9] = {0x09, 0x424c},
174+
+ [10] = {0x0a, 0xb210},
175+
+ [11] = {0x0b, 0xb90d},
176+
+ [13] = {0x0d, 0xe718},
177+
+ [14] = {0x0e, 0x1010},
178+
+ [15] = {0x0f, 0x8d50},
179+
+ [32] = {0x20, 0x7025},
180+
+ [33] = {0x21, 0x88a0},
181+
+ [35] = {0x23, 0x0b66},
182+
+ [39] = {0x27, 0x01e1},
183+
+ [41] = {0x29, 0xf0f2},
184+
+ [43] = {0x2b, 0x80a8}, },
185+
+ .check_efuse = false,
186+
+ .do_toggle = true,
187+
+ .do_toggle_once = false,
188+
+ .use_default_parameter = false,
189+
+ .check_rx_front_end_offset = false,
190+
+ .busy_bit = USB_MDIO_CTRL_9607_PHY_BUSY,
191+
+ .poll_result = USB_MDIO_CTRL_9607_PHY_BUSY,
192+
+ .do_ip_config = true,
193+
};
194+
195+
static const struct of_device_id usbphy_rtk_dt_match[] = {
196+
@@ -730,6 +815,7 @@ static const struct of_device_id usbphy_
197+
{ .compatible = "realtek,rtd1319d-usb3phy", .data = &rtd1319d_phy_cfg },
198+
{ .compatible = "realtek,rtd1619-usb3phy", .data = &rtd1619_phy_cfg },
199+
{ .compatible = "realtek,rtd1619b-usb3phy", .data = &rtd1619b_phy_cfg },
200+
+ { .compatible = "realtek,rtl9607-usb3phy", .data = &rtl9607_phy_cfg },
201+
{},
202+
};
203+
MODULE_DEVICE_TABLE(of, usbphy_rtk_dt_match);

target/linux/realtek/rtl960x/config-6.12

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ CONFIG_PGTABLE_LEVELS=2
211211
CONFIG_PHYLIB=y
212212
CONFIG_PHYLIB_LEDS=y
213213
CONFIG_PHY_RTK_RTD_USB2PHY=y
214-
# CONFIG_PHY_RTK_RTD_USB3PHY is not set
214+
CONFIG_PHY_RTK_RTD_USB3PHY=y
215215
CONFIG_PINCTRL=y
216216
CONFIG_POWER_RESET=y
217217
CONFIG_POWER_RESET_SYSCON=y
@@ -288,6 +288,8 @@ CONFIG_USB_OHCI_HCD=y
288288
CONFIG_USB_OHCI_HCD_PLATFORM=y
289289
CONFIG_USB_PHY=y
290290
CONFIG_USB_SUPPORT=y
291+
CONFIG_USB_XHCI_HCD=y
292+
CONFIG_USB_XHCI_PLATFORM=y
291293
CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
292294
CONFIG_USE_OF=y
293295
CONFIG_WATCHDOG_CORE=y

0 commit comments

Comments
 (0)