b3cd492d05381224d020edd6cac1c3ad0b80390a
[openwrt/staging/linusw.git] /
1 From 6c66dff196cbba8515380110dd3599cde31dd896 Mon Sep 17 00:00:00 2001
2 From: Ziyang Huang <hzyitc@outlook.com>
3 Date: Sun, 8 Sep 2024 16:40:12 +0800
4 Subject: [PATCH 1/2] rproc: qcom_q6v5_mpd: split q6_wcss to rootpd and
5 userpd
6
7 Split the q6_wcss structure and create a separate userpd struct to clearly
8 differentiate between the process to bring up the QDSP6 processor vs
9 process(es) to bring up the Wifi radio(s) (WCSS) for better readability.
10
11 Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
12 Signed-off-by: George Moussalem <george.moussalem@outlook.com>
13 ---
14 drivers/remoteproc/qcom_q6v5_mpd.c | 126 +++++++++++++----------------
15 1 file changed, 56 insertions(+), 70 deletions(-)
16
17 --- a/drivers/remoteproc/qcom_q6v5_mpd.c
18 +++ b/drivers/remoteproc/qcom_q6v5_mpd.c
19 @@ -44,10 +44,6 @@
20 #define VERSION2 2
21
22 static LIST_HEAD(upd_rproc_list);
23 -enum {
24 - Q6_IPQ,
25 - WCSS_IPQ,
26 -};
27
28 /**
29 * struct userpd_boot_info_header - header of user pd bootinfo
30 @@ -82,10 +78,15 @@ struct q6_wcss {
31 phys_addr_t mem_reloc;
32 void *mem_region;
33 size_t mem_size;
34 - u8 pd_asid;
35 const struct wcss_data *desc;
36 const char **firmware;
37 - u32 version;
38 +};
39 +
40 +struct userpd {
41 + u8 pd_asid;
42 + struct device *dev;
43 + struct qcom_rproc_ssr ssr_subdev;
44 + struct qcom_q6v5 q6;
45 };
46
47 struct wcss_data {
48 @@ -101,8 +102,8 @@ struct wcss_data {
49 */
50 static u8 qcom_get_pd_asid(struct rproc *rproc)
51 {
52 - struct q6_wcss *wcss = rproc->priv;
53 - u8 bit = wcss->q6.spawn_bit;
54 + struct userpd *upd = rproc->priv;
55 + u8 bit = upd->q6.spawn_bit;
56
57 return bit / 8;
58 }
59 @@ -131,37 +132,37 @@ static int q6_wcss_start(struct rproc *r
60 static int q6_wcss_spawn_pd(struct rproc *rproc)
61 {
62 int ret;
63 - struct q6_wcss *wcss = rproc->priv;
64 + struct userpd *upd = rproc->priv;
65
66 - ret = qcom_q6v5_request_spawn(&wcss->q6);
67 + ret = qcom_q6v5_request_spawn(&upd->q6);
68 if (ret == -ETIMEDOUT) {
69 - dev_err(wcss->dev, "%s spawn timedout\n", rproc->name);
70 + dev_err(upd->dev, "%s spawn timedout\n", rproc->name);
71 return ret;
72 }
73
74 - ret = qcom_q6v5_wait_for_start(&wcss->q6, msecs_to_jiffies(10000));
75 + ret = qcom_q6v5_wait_for_start(&upd->q6, msecs_to_jiffies(10000));
76 if (ret == -ETIMEDOUT) {
77 - dev_err(wcss->dev, "%s start timedout\n", rproc->name);
78 - wcss->q6.running = false;
79 + dev_err(upd->dev, "%s start timedout\n", rproc->name);
80 + upd->q6.running = false;
81 return ret;
82 }
83 - wcss->q6.running = true;
84 + upd->q6.running = true;
85 return ret;
86 }
87
88 static int wcss_pd_start(struct rproc *rproc)
89 {
90 - struct q6_wcss *wcss = rproc->priv;
91 - u32 pasid = (wcss->pd_asid << 8) | UPD_SWID;
92 + struct userpd *upd = rproc->priv;
93 + u32 pasid = (upd->pd_asid << 8) | UPD_SWID;
94 int ret;
95
96 ret = qcom_scm_msa_lock(pasid);
97 if (ret) {
98 - dev_err(wcss->dev, "failed to power up pd\n");
99 + dev_err(upd->dev, "failed to power up pd\n");
100 return ret;
101 }
102
103 - if (wcss->q6.spawn_bit) {
104 + if (upd->q6.spawn_bit) {
105 ret = q6_wcss_spawn_pd(rproc);
106 if (ret)
107 return ret;
108 @@ -213,22 +214,22 @@ static int q6_wcss_stop(struct rproc *rp
109 */
110 static int wcss_pd_stop(struct rproc *rproc)
111 {
112 - struct q6_wcss *wcss = rproc->priv;
113 - struct rproc *rpd_rproc = dev_get_drvdata(wcss->dev->parent);
114 - u32 pasid = (wcss->pd_asid << 8) | UPD_SWID;
115 + struct userpd *upd = rproc->priv;
116 + struct rproc *rpd_rproc = dev_get_drvdata(upd->dev->parent);
117 + u32 pasid = (upd->pd_asid << 8) | UPD_SWID;
118 int ret;
119
120 - if (rproc->state != RPROC_CRASHED && wcss->q6.stop_bit) {
121 - ret = qcom_q6v5_request_stop(&wcss->q6, NULL);
122 + if (rproc->state != RPROC_CRASHED && upd->q6.stop_bit) {
123 + ret = qcom_q6v5_request_stop(&upd->q6, NULL);
124 if (ret) {
125 - dev_err(&rproc->dev, "pd not stopped\n");
126 + dev_err(upd->dev, "pd not stopped\n");
127 return ret;
128 }
129 }
130
131 ret = qcom_scm_msa_unlock(pasid);
132 if (ret) {
133 - dev_err(wcss->dev, "failed to power down pd\n");
134 + dev_err(upd->dev, "failed to power down pd\n");
135 return ret;
136 }
137
138 @@ -273,7 +274,8 @@ static int share_upd_bootinfo_to_q6(stru
139 size_t size;
140 u16 cnt = 0, version;
141 void *ptr;
142 - struct q6_wcss *wcss = rproc->priv, *upd_wcss;
143 + struct q6_wcss *wcss = rproc->priv;
144 + struct userpd *upd;
145 struct rproc *upd_rproc;
146 struct userpd_boot_info upd_bootinfo = {0};
147 const struct firmware *fw;
148 @@ -308,7 +310,7 @@ static int share_upd_bootinfo_to_q6(stru
149 ptr += sizeof(u16);
150
151 list_for_each_entry(upd_rproc, &upd_rproc_list, node) {
152 - upd_wcss = upd_rproc->priv;
153 + upd = upd_rproc->priv;
154
155 /* TYPE */
156 upd_bootinfo.header.type = UPD_BOOT_INFO_HEADER_TYPE;
157 @@ -318,11 +320,11 @@ static int share_upd_bootinfo_to_q6(stru
158 sizeof(upd_bootinfo) - sizeof(upd_bootinfo.header);
159
160 /* Process ID */
161 - upd_bootinfo.pid = upd_wcss->pd_asid + 1;
162 + upd_bootinfo.pid = upd->pd_asid + 1;
163
164 - ret = request_firmware(&fw, upd_rproc->firmware, upd_wcss->dev);
165 + ret = request_firmware(&fw, upd_rproc->firmware, upd->dev);
166 if (ret < 0) {
167 - dev_err(upd_wcss->dev, "request_firmware failed: %d\n", ret);
168 + dev_err(upd->dev, "request_firmware failed: %d\n", ret);
169 return ret;
170 }
171
172 @@ -421,19 +423,20 @@ static int q6_wcss_load(struct rproc *rp
173 */
174 static int wcss_pd_load(struct rproc *rproc, const struct firmware *fw)
175 {
176 - struct q6_wcss *wcss = rproc->priv;
177 - struct rproc *rpd_rproc = dev_get_drvdata(wcss->dev->parent);
178 - u32 pasid = (wcss->pd_asid << 8) | UPD_SWID;
179 + struct userpd *upd = rproc->priv;
180 + struct rproc *rpd_rproc = dev_get_drvdata(upd->dev->parent);
181 + struct q6_wcss *wcss = rpd_rproc->priv;
182 + u32 pasid = (upd->pd_asid << 8) | UPD_SWID;
183 int ret;
184
185 ret = rproc_boot(rpd_rproc);
186 if (ret)
187 return ret;
188
189 - return qcom_mdt_load(wcss->dev, fw, rproc->firmware,
190 + return qcom_mdt_load(upd->dev, fw, rproc->firmware,
191 pasid, wcss->mem_region,
192 wcss->mem_phys, wcss->mem_size,
193 - &wcss->mem_reloc);
194 + NULL);
195 }
196
197 static unsigned long q6_wcss_panic(struct rproc *rproc)
198 @@ -465,26 +468,15 @@ static int q6_alloc_memory_region(struct
199 struct device_node *node;
200 struct device *dev = wcss->dev;
201
202 - if (wcss->version == Q6_IPQ) {
203 - node = of_parse_phandle(dev->of_node, "memory-region", 0);
204 - if (node)
205 - rmem = of_reserved_mem_lookup(node);
206 -
207 - of_node_put(node);
208 -
209 - if (!rmem) {
210 - dev_err(dev, "unable to acquire memory-region\n");
211 - return -EINVAL;
212 - }
213 - } else {
214 - struct rproc *rpd_rproc = dev_get_drvdata(dev->parent);
215 - struct q6_wcss *rpd_wcss = rpd_rproc->priv;
216 -
217 - wcss->mem_phys = rpd_wcss->mem_phys;
218 - wcss->mem_reloc = rpd_wcss->mem_reloc;
219 - wcss->mem_size = rpd_wcss->mem_size;
220 - wcss->mem_region = rpd_wcss->mem_region;
221 - return 0;
222 + node = of_parse_phandle(dev->of_node, "memory-region", 0);
223 + if (node)
224 + rmem = of_reserved_mem_lookup(node);
225 +
226 + of_node_put(node);
227 +
228 + if (!rmem) {
229 + dev_err(dev, "unable to acquire memory-region\n");
230 + return -EINVAL;
231 }
232
233 wcss->mem_phys = rmem->base;
234 @@ -508,7 +500,7 @@ static int q6_get_inbound_irq(struct qco
235 {
236 int ret, irq;
237 char *interrupt, *tmp = (char *)int_name;
238 - struct q6_wcss *wcss = q6->rproc->priv;
239 + struct userpd *upd = q6->rproc->priv;
240
241 irq = platform_get_irq(pdev, index);
242 if (irq < 0)
243 @@ -520,7 +512,7 @@ static int q6_get_inbound_irq(struct qco
244 if (!interrupt)
245 return -ENOMEM;
246
247 - snprintf(interrupt, BUF_SIZE, "q6v5_wcss_userpd%d_%s", wcss->pd_asid, tmp);
248 + snprintf(interrupt, BUF_SIZE, "q6v5_wcss_userpd%d_%s", upd->pd_asid, tmp);
249
250 ret = devm_request_threaded_irq(&pdev->dev, *pirq,
251 NULL, handler,
252 @@ -561,7 +553,7 @@ static int init_irq(struct qcom_q6v5 *q6
253 void (*handover)(struct qcom_q6v5 *q6))
254 {
255 int ret;
256 - struct q6_wcss *wcss = rproc->priv;
257 + struct userpd *upd = rproc->priv;
258
259 q6->rproc = rproc;
260 q6->dev = &pdev->dev;
261 @@ -581,7 +573,7 @@ static int init_irq(struct qcom_q6v5 *q6
262 return ret;
263
264 /* Get pd_asid to prepare interrupt names */
265 - wcss->pd_asid = qcom_get_pd_asid(rproc);
266 + upd->pd_asid = qcom_get_pd_asid(rproc);
267
268 ret = q6_get_inbound_irq(q6, pdev, "fatal", 0, &q6->fatal_irq,
269 q6v5_fatal_interrupt);
270 @@ -619,7 +611,7 @@ static void q6_release_resources(void)
271 static int q6_register_userpd(struct platform_device *pdev,
272 struct device_node *userpd_np)
273 {
274 - struct q6_wcss *wcss;
275 + struct userpd *upd;
276 struct rproc *rproc = NULL;
277 int ret;
278 struct platform_device *userpd_pdev;
279 @@ -652,21 +644,16 @@ static int q6_register_userpd(struct pla
280
281 userpd_pdev->dev.driver = pdev->dev.driver;
282 rproc = rproc_alloc(&userpd_pdev->dev, userpd_pdev->name, &wcss_ops,
283 - firmware_name, sizeof(*wcss));
284 + firmware_name, sizeof(*upd));
285 if (!rproc) {
286 ret = -ENOMEM;
287 goto free_rproc;
288 }
289
290 - wcss = rproc->priv;
291 - wcss->dev = &userpd_pdev->dev;
292 - wcss->version = WCSS_IPQ;
293 -
294 - ret = q6_alloc_memory_region(wcss);
295 - if (ret)
296 - goto free_rproc;
297 + upd = rproc->priv;
298 + upd->dev = &userpd_pdev->dev;
299
300 - ret = init_irq(&wcss->q6, userpd_pdev, rproc,
301 + ret = init_irq(&upd->q6, userpd_pdev, rproc,
302 WCSS_CRASH_REASON, NULL, NULL);
303 if (ret)
304 goto free_rproc;
305 @@ -678,7 +665,7 @@ static int q6_register_userpd(struct pla
306
307 list_add(&rproc->node, &upd_rproc_list);
308 platform_set_drvdata(userpd_pdev, rproc);
309 - qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, userpd_pdev->name);
310 + qcom_add_ssr_subdev(rproc, &upd->ssr_subdev, userpd_pdev->name);
311 return 0;
312
313 free_rproc:
314 @@ -719,7 +706,6 @@ static int q6_wcss_probe(struct platform
315 wcss->dev = &pdev->dev;
316 wcss->desc = desc;
317 wcss->firmware = firmware;
318 - wcss->version = Q6_IPQ;
319
320 ret = q6_alloc_memory_region(wcss);
321 if (ret)