OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 354655aaf0f71ce2b567cbc02afb0664c99e434e Mon Sep 17 00:00:00 2001 |
2 | From: Chunfeng Yun <chunfeng.yun@mediatek.com> |
||
3 | Date: Wed, 3 Jan 2018 16:53:18 +0800 |
||
4 | Subject: [PATCH 188/224] usb: mtu3: supports remote wakeup for mt2712 with two |
||
5 | SSUSB IPs |
||
6 | |||
7 | The old way of usb wakeup only supports platform with single SSUSB IP, |
||
8 | such as mt8173, but mt2712 has two SSUSB IPs, so rebuild its flow and |
||
9 | also supports the new glue layer of usb wakeup on mt2712 which is |
||
10 | different from mt8173. |
||
11 | |||
12 | Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> |
||
13 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
||
14 | --- |
||
15 | drivers/usb/mtu3/mtu3.h | 11 +++-- |
||
16 | drivers/usb/mtu3/mtu3_dr.h | 3 +- |
||
17 | drivers/usb/mtu3/mtu3_host.c | 115 +++++++++++++++++++++---------------------- |
||
18 | drivers/usb/mtu3/mtu3_plat.c | 8 +-- |
||
19 | 4 files changed, 70 insertions(+), 67 deletions(-) |
||
20 | |||
21 | --- a/drivers/usb/mtu3/mtu3.h |
||
22 | +++ b/drivers/usb/mtu3/mtu3.h |
||
23 | @@ -238,7 +238,10 @@ struct otg_switch_mtk { |
||
24 | * @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to |
||
25 | * disable u3port0, bit1==1 to disable u3port1,... etc |
||
26 | * @dbgfs_root: only used when supports manual dual-role switch via debugfs |
||
27 | - * @wakeup_en: it's true when supports remote wakeup in host mode |
||
28 | + * @uwk_en: it's true when supports remote wakeup in host mode |
||
29 | + * @uwk: syscon including usb wakeup glue layer between SSUSB IP and SPM |
||
30 | + * @uwk_reg_base: the base address of the wakeup glue layer in @uwk |
||
31 | + * @uwk_vers: the version of the wakeup glue layer |
||
32 | */ |
||
33 | struct ssusb_mtk { |
||
34 | struct device *dev; |
||
35 | @@ -262,8 +265,10 @@ struct ssusb_mtk { |
||
36 | int u3p_dis_msk; |
||
37 | struct dentry *dbgfs_root; |
||
38 | /* usb wakeup for host mode */ |
||
39 | - bool wakeup_en; |
||
40 | - struct regmap *pericfg; |
||
41 | + bool uwk_en; |
||
42 | + struct regmap *uwk; |
||
43 | + u32 uwk_reg_base; |
||
44 | + u32 uwk_vers; |
||
45 | }; |
||
46 | |||
47 | /** |
||
48 | --- a/drivers/usb/mtu3/mtu3_dr.h |
||
49 | +++ b/drivers/usb/mtu3/mtu3_dr.h |
||
50 | @@ -27,8 +27,7 @@ int ssusb_wakeup_of_property_parse(struc |
||
51 | struct device_node *dn); |
||
52 | int ssusb_host_enable(struct ssusb_mtk *ssusb); |
||
53 | int ssusb_host_disable(struct ssusb_mtk *ssusb, bool suspend); |
||
54 | -int ssusb_wakeup_enable(struct ssusb_mtk *ssusb); |
||
55 | -void ssusb_wakeup_disable(struct ssusb_mtk *ssusb); |
||
56 | +void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable); |
||
57 | |||
58 | #else |
||
59 | |||
60 | --- a/drivers/usb/mtu3/mtu3_host.c |
||
61 | +++ b/drivers/usb/mtu3/mtu3_host.c |
||
62 | @@ -27,66 +27,77 @@ |
||
63 | #include "mtu3.h" |
||
64 | #include "mtu3_dr.h" |
||
65 | |||
66 | -#define PERI_WK_CTRL1 0x404 |
||
67 | -#define UWK_CTL1_IS_C(x) (((x) & 0xf) << 26) |
||
68 | -#define UWK_CTL1_IS_E BIT(25) |
||
69 | -#define UWK_CTL1_IDDIG_C(x) (((x) & 0xf) << 11) /* cycle debounce */ |
||
70 | -#define UWK_CTL1_IDDIG_E BIT(10) /* enable debounce */ |
||
71 | -#define UWK_CTL1_IDDIG_P BIT(9) /* polarity */ |
||
72 | -#define UWK_CTL1_IS_P BIT(6) /* polarity for ip sleep */ |
||
73 | +/* mt8173 etc */ |
||
74 | +#define PERI_WK_CTRL1 0x4 |
||
75 | +#define WC1_IS_C(x) (((x) & 0xf) << 26) /* cycle debounce */ |
||
76 | +#define WC1_IS_EN BIT(25) |
||
77 | +#define WC1_IS_P BIT(6) /* polarity for ip sleep */ |
||
78 | + |
||
79 | +/* mt2712 etc */ |
||
80 | +#define PERI_SSUSB_SPM_CTRL 0x0 |
||
81 | +#define SSC_IP_SLEEP_EN BIT(4) |
||
82 | +#define SSC_SPM_INT_EN BIT(1) |
||
83 | + |
||
84 | +enum ssusb_uwk_vers { |
||
85 | + SSUSB_UWK_V1 = 1, |
||
86 | + SSUSB_UWK_V2, |
||
87 | +}; |
||
88 | |||
89 | /* |
||
90 | * ip-sleep wakeup mode: |
||
91 | * all clocks can be turn off, but power domain should be kept on |
||
92 | */ |
||
93 | -static void ssusb_wakeup_ip_sleep_en(struct ssusb_mtk *ssusb) |
||
94 | +static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable) |
||
95 | { |
||
96 | - u32 tmp; |
||
97 | - struct regmap *pericfg = ssusb->pericfg; |
||
98 | + u32 reg, msk, val; |
||
99 | |||
100 | - regmap_read(pericfg, PERI_WK_CTRL1, &tmp); |
||
101 | - tmp &= ~UWK_CTL1_IS_P; |
||
102 | - tmp &= ~(UWK_CTL1_IS_C(0xf)); |
||
103 | - tmp |= UWK_CTL1_IS_C(0x8); |
||
104 | - regmap_write(pericfg, PERI_WK_CTRL1, tmp); |
||
105 | - regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E); |
||
106 | - |
||
107 | - regmap_read(pericfg, PERI_WK_CTRL1, &tmp); |
||
108 | - dev_dbg(ssusb->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n", |
||
109 | - __func__, tmp); |
||
110 | -} |
||
111 | - |
||
112 | -static void ssusb_wakeup_ip_sleep_dis(struct ssusb_mtk *ssusb) |
||
113 | -{ |
||
114 | - u32 tmp; |
||
115 | - |
||
116 | - regmap_read(ssusb->pericfg, PERI_WK_CTRL1, &tmp); |
||
117 | - tmp &= ~UWK_CTL1_IS_E; |
||
118 | - regmap_write(ssusb->pericfg, PERI_WK_CTRL1, tmp); |
||
119 | + switch (ssusb->uwk_vers) { |
||
120 | + case SSUSB_UWK_V1: |
||
121 | + reg = ssusb->uwk_reg_base + PERI_WK_CTRL1; |
||
122 | + msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P; |
||
123 | + val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0; |
||
124 | + break; |
||
125 | + case SSUSB_UWK_V2: |
||
126 | + reg = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL; |
||
127 | + msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN; |
||
128 | + val = enable ? msk : 0; |
||
129 | + break; |
||
130 | + default: |
||
131 | + return; |
||
132 | + }; |
||
133 | + regmap_update_bits(ssusb->uwk, reg, msk, val); |
||
134 | } |
||
135 | |||
136 | int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb, |
||
137 | struct device_node *dn) |
||
138 | { |
||
139 | - struct device *dev = ssusb->dev; |
||
140 | + struct of_phandle_args args; |
||
141 | + int ret; |
||
142 | |||
143 | - /* |
||
144 | - * Wakeup function is optional, so it is not an error if this property |
||
145 | - * does not exist, and in such case, no need to get relative |
||
146 | - * properties anymore. |
||
147 | - */ |
||
148 | - ssusb->wakeup_en = of_property_read_bool(dn, "mediatek,enable-wakeup"); |
||
149 | - if (!ssusb->wakeup_en) |
||
150 | + /* wakeup function is optional */ |
||
151 | + ssusb->uwk_en = of_property_read_bool(dn, "wakeup-source"); |
||
152 | + if (!ssusb->uwk_en) |
||
153 | return 0; |
||
154 | |||
155 | - ssusb->pericfg = syscon_regmap_lookup_by_phandle(dn, |
||
156 | - "mediatek,syscon-wakeup"); |
||
157 | - if (IS_ERR(ssusb->pericfg)) { |
||
158 | - dev_err(dev, "fail to get pericfg regs\n"); |
||
159 | - return PTR_ERR(ssusb->pericfg); |
||
160 | - } |
||
161 | + ret = of_parse_phandle_with_fixed_args(dn, |
||
162 | + "mediatek,syscon-wakeup", 2, 0, &args); |
||
163 | + if (ret) |
||
164 | + return ret; |
||
165 | |||
166 | - return 0; |
||
167 | + ssusb->uwk_reg_base = args.args[0]; |
||
168 | + ssusb->uwk_vers = args.args[1]; |
||
169 | + ssusb->uwk = syscon_node_to_regmap(args.np); |
||
170 | + of_node_put(args.np); |
||
171 | + dev_info(ssusb->dev, "uwk - reg:0x%x, version:%d\n", |
||
172 | + ssusb->uwk_reg_base, ssusb->uwk_vers); |
||
173 | + |
||
174 | + return PTR_ERR_OR_ZERO(ssusb->uwk); |
||
175 | +} |
||
176 | + |
||
177 | +void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable) |
||
178 | +{ |
||
179 | + if (ssusb->uwk_en) |
||
180 | + ssusb_wakeup_ip_sleep_set(ssusb, enable); |
||
181 | } |
||
182 | |||
183 | static void host_ports_num_get(struct ssusb_mtk *ssusb) |
||
184 | @@ -244,17 +255,3 @@ void ssusb_host_exit(struct ssusb_mtk *s |
||
185 | of_platform_depopulate(ssusb->dev); |
||
186 | ssusb_host_cleanup(ssusb); |
||
187 | } |
||
188 | - |
||
189 | -int ssusb_wakeup_enable(struct ssusb_mtk *ssusb) |
||
190 | -{ |
||
191 | - if (ssusb->wakeup_en) |
||
192 | - ssusb_wakeup_ip_sleep_en(ssusb); |
||
193 | - |
||
194 | - return 0; |
||
195 | -} |
||
196 | - |
||
197 | -void ssusb_wakeup_disable(struct ssusb_mtk *ssusb) |
||
198 | -{ |
||
199 | - if (ssusb->wakeup_en) |
||
200 | - ssusb_wakeup_ip_sleep_dis(ssusb); |
||
201 | -} |
||
202 | --- a/drivers/usb/mtu3/mtu3_plat.c |
||
203 | +++ b/drivers/usb/mtu3/mtu3_plat.c |
||
204 | @@ -291,8 +291,10 @@ static int get_ssusb_rscs(struct platfor |
||
205 | |||
206 | /* if host role is supported */ |
||
207 | ret = ssusb_wakeup_of_property_parse(ssusb, node); |
||
208 | - if (ret) |
||
209 | + if (ret) { |
||
210 | + dev_err(dev, "failed to parse uwk property\n"); |
||
211 | return ret; |
||
212 | + } |
||
213 | |||
214 | /* optional property, ignore the error if it does not exist */ |
||
215 | of_property_read_u32(node, "mediatek,u3p-dis-msk", |
||
216 | @@ -466,7 +468,7 @@ static int __maybe_unused mtu3_suspend(s |
||
217 | ssusb_host_disable(ssusb, true); |
||
218 | ssusb_phy_power_off(ssusb); |
||
219 | ssusb_clks_disable(ssusb); |
||
220 | - ssusb_wakeup_enable(ssusb); |
||
221 | + ssusb_wakeup_set(ssusb, true); |
||
222 | |||
223 | return 0; |
||
224 | } |
||
225 | @@ -482,7 +484,7 @@ static int __maybe_unused mtu3_resume(st |
||
226 | if (!ssusb->is_host) |
||
227 | return 0; |
||
228 | |||
229 | - ssusb_wakeup_disable(ssusb); |
||
230 | + ssusb_wakeup_set(ssusb, false); |
||
231 | ret = ssusb_clks_enable(ssusb); |
||
232 | if (ret) |
||
233 | goto clks_err; |