1 | // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) |
2 | /* |
3 | * Copyright 2013-2016 Freescale Semiconductor Inc. |
4 | * Copyright 2020 NXP |
5 | * |
6 | */ |
7 | #include <linux/kernel.h> |
8 | #include <linux/fsl/mc.h> |
9 | |
10 | #include "fsl-mc-private.h" |
11 | |
12 | /* |
13 | * cache the DPRC version to reduce the number of commands |
14 | * towards the mc firmware |
15 | */ |
16 | static u16 dprc_major_ver; |
17 | static u16 dprc_minor_ver; |
18 | |
19 | /** |
20 | * dprc_open() - Open DPRC object for use |
21 | * @mc_io: Pointer to MC portal's I/O object |
22 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
23 | * @container_id: Container ID to open |
24 | * @token: Returned token of DPRC object |
25 | * |
26 | * Return: '0' on Success; Error code otherwise. |
27 | * |
28 | * @warning Required before any operation on the object. |
29 | */ |
30 | int dprc_open(struct fsl_mc_io *mc_io, |
31 | u32 cmd_flags, |
32 | int container_id, |
33 | u16 *token) |
34 | { |
35 | struct fsl_mc_command cmd = { 0 }; |
36 | struct dprc_cmd_open *cmd_params; |
37 | int err; |
38 | |
39 | /* prepare command */ |
40 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags, |
41 | token: 0); |
42 | cmd_params = (struct dprc_cmd_open *)cmd.params; |
43 | cmd_params->container_id = cpu_to_le32(container_id); |
44 | |
45 | /* send command to mc*/ |
46 | err = mc_send_command(mc_io, cmd: &cmd); |
47 | if (err) |
48 | return err; |
49 | |
50 | /* retrieve response parameters */ |
51 | *token = mc_cmd_hdr_read_token(cmd: &cmd); |
52 | |
53 | return 0; |
54 | } |
55 | EXPORT_SYMBOL_GPL(dprc_open); |
56 | |
57 | /** |
58 | * dprc_close() - Close the control session of the object |
59 | * @mc_io: Pointer to MC portal's I/O object |
60 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
61 | * @token: Token of DPRC object |
62 | * |
63 | * After this function is called, no further operations are |
64 | * allowed on the object without opening a new control session. |
65 | * |
66 | * Return: '0' on Success; Error code otherwise. |
67 | */ |
68 | int dprc_close(struct fsl_mc_io *mc_io, |
69 | u32 cmd_flags, |
70 | u16 token) |
71 | { |
72 | struct fsl_mc_command cmd = { 0 }; |
73 | |
74 | /* prepare command */ |
75 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags, |
76 | token); |
77 | |
78 | /* send command to mc*/ |
79 | return mc_send_command(mc_io, cmd: &cmd); |
80 | } |
81 | EXPORT_SYMBOL_GPL(dprc_close); |
82 | |
83 | /** |
84 | * dprc_reset_container - Reset child container. |
85 | * @mc_io: Pointer to MC portal's I/O object |
86 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
87 | * @token: Token of DPRC object |
88 | * @child_container_id: ID of the container to reset |
89 | * @options: 32 bit options: |
90 | * - 0 (no bits set) - all the objects inside the container are |
91 | * reset. The child containers are entered recursively and the |
92 | * objects reset. All the objects (including the child containers) |
93 | * are closed. |
94 | * - bit 0 set - all the objects inside the container are reset. |
95 | * However the child containers are not entered recursively. |
96 | * This option is supported for API versions >= 6.5 |
97 | * In case a software context crashes or becomes non-responsive, the parent |
98 | * may wish to reset its resources container before the software context is |
99 | * restarted. |
100 | * |
101 | * This routine informs all objects assigned to the child container that the |
102 | * container is being reset, so they may perform any cleanup operations that are |
103 | * needed. All objects handles that were owned by the child container shall be |
104 | * closed. |
105 | * |
106 | * Note that such request may be submitted even if the child software context |
107 | * has not crashed, but the resulting object cleanup operations will not be |
108 | * aware of that. |
109 | * |
110 | * Return: '0' on Success; Error code otherwise. |
111 | */ |
112 | int dprc_reset_container(struct fsl_mc_io *mc_io, |
113 | u32 cmd_flags, |
114 | u16 token, |
115 | int child_container_id, |
116 | u32 options) |
117 | { |
118 | struct fsl_mc_command cmd = { 0 }; |
119 | struct dprc_cmd_reset_container *cmd_params; |
120 | u32 cmdid = DPRC_CMDID_RESET_CONT; |
121 | int err; |
122 | |
123 | /* |
124 | * If the DPRC object version was not yet cached, cache it now. |
125 | * Otherwise use the already cached value. |
126 | */ |
127 | if (!dprc_major_ver && !dprc_minor_ver) { |
128 | err = dprc_get_api_version(mc_io, cmd_flags: 0, |
129 | major_ver: &dprc_major_ver, |
130 | minor_ver: &dprc_minor_ver); |
131 | if (err) |
132 | return err; |
133 | } |
134 | |
135 | /* |
136 | * MC API 6.5 introduced a new field in the command used to pass |
137 | * some flags. |
138 | * Bit 0 indicates that the child containers are not recursively reset. |
139 | */ |
140 | if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 5)) |
141 | cmdid = DPRC_CMDID_RESET_CONT_V2; |
142 | |
143 | /* prepare command */ |
144 | cmd.header = mc_encode_cmd_header(cmd_id: cmdid, cmd_flags, token); |
145 | cmd_params = (struct dprc_cmd_reset_container *)cmd.params; |
146 | cmd_params->child_container_id = cpu_to_le32(child_container_id); |
147 | cmd_params->options = cpu_to_le32(options); |
148 | |
149 | /* send command to mc*/ |
150 | return mc_send_command(mc_io, cmd: &cmd); |
151 | } |
152 | EXPORT_SYMBOL_GPL(dprc_reset_container); |
153 | |
154 | /** |
155 | * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. |
156 | * @mc_io: Pointer to MC portal's I/O object |
157 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
158 | * @token: Token of DPRC object |
159 | * @irq_index: Identifies the interrupt index to configure |
160 | * @irq_cfg: IRQ configuration |
161 | * |
162 | * Return: '0' on Success; Error code otherwise. |
163 | */ |
164 | int dprc_set_irq(struct fsl_mc_io *mc_io, |
165 | u32 cmd_flags, |
166 | u16 token, |
167 | u8 irq_index, |
168 | struct dprc_irq_cfg *irq_cfg) |
169 | { |
170 | struct fsl_mc_command cmd = { 0 }; |
171 | struct dprc_cmd_set_irq *cmd_params; |
172 | |
173 | /* prepare command */ |
174 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ, |
175 | cmd_flags, |
176 | token); |
177 | cmd_params = (struct dprc_cmd_set_irq *)cmd.params; |
178 | cmd_params->irq_val = cpu_to_le32(irq_cfg->val); |
179 | cmd_params->irq_index = irq_index; |
180 | cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); |
181 | cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); |
182 | |
183 | /* send command to mc*/ |
184 | return mc_send_command(mc_io, cmd: &cmd); |
185 | } |
186 | |
187 | /** |
188 | * dprc_set_irq_enable() - Set overall interrupt state. |
189 | * @mc_io: Pointer to MC portal's I/O object |
190 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
191 | * @token: Token of DPRC object |
192 | * @irq_index: The interrupt index to configure |
193 | * @en: Interrupt state - enable = 1, disable = 0 |
194 | * |
195 | * Allows GPP software to control when interrupts are generated. |
196 | * Each interrupt can have up to 32 causes. The enable/disable control's the |
197 | * overall interrupt state. if the interrupt is disabled no causes will cause |
198 | * an interrupt. |
199 | * |
200 | * Return: '0' on Success; Error code otherwise. |
201 | */ |
202 | int dprc_set_irq_enable(struct fsl_mc_io *mc_io, |
203 | u32 cmd_flags, |
204 | u16 token, |
205 | u8 irq_index, |
206 | u8 en) |
207 | { |
208 | struct fsl_mc_command cmd = { 0 }; |
209 | struct dprc_cmd_set_irq_enable *cmd_params; |
210 | |
211 | /* prepare command */ |
212 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE, |
213 | cmd_flags, token); |
214 | cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params; |
215 | cmd_params->enable = en & DPRC_ENABLE; |
216 | cmd_params->irq_index = irq_index; |
217 | |
218 | /* send command to mc*/ |
219 | return mc_send_command(mc_io, cmd: &cmd); |
220 | } |
221 | |
222 | /** |
223 | * dprc_set_irq_mask() - Set interrupt mask. |
224 | * @mc_io: Pointer to MC portal's I/O object |
225 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
226 | * @token: Token of DPRC object |
227 | * @irq_index: The interrupt index to configure |
228 | * @mask: event mask to trigger interrupt; |
229 | * each bit: |
230 | * 0 = ignore event |
231 | * 1 = consider event for asserting irq |
232 | * |
233 | * Every interrupt can have up to 32 causes and the interrupt model supports |
234 | * masking/unmasking each cause independently |
235 | * |
236 | * Return: '0' on Success; Error code otherwise. |
237 | */ |
238 | int dprc_set_irq_mask(struct fsl_mc_io *mc_io, |
239 | u32 cmd_flags, |
240 | u16 token, |
241 | u8 irq_index, |
242 | u32 mask) |
243 | { |
244 | struct fsl_mc_command cmd = { 0 }; |
245 | struct dprc_cmd_set_irq_mask *cmd_params; |
246 | |
247 | /* prepare command */ |
248 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK, |
249 | cmd_flags, token); |
250 | cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params; |
251 | cmd_params->mask = cpu_to_le32(mask); |
252 | cmd_params->irq_index = irq_index; |
253 | |
254 | /* send command to mc*/ |
255 | return mc_send_command(mc_io, cmd: &cmd); |
256 | } |
257 | |
258 | /** |
259 | * dprc_get_irq_status() - Get the current status of any pending interrupts. |
260 | * @mc_io: Pointer to MC portal's I/O object |
261 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
262 | * @token: Token of DPRC object |
263 | * @irq_index: The interrupt index to configure |
264 | * @status: Returned interrupts status - one bit per cause: |
265 | * 0 = no interrupt pending |
266 | * 1 = interrupt pending |
267 | * |
268 | * Return: '0' on Success; Error code otherwise. |
269 | */ |
270 | int dprc_get_irq_status(struct fsl_mc_io *mc_io, |
271 | u32 cmd_flags, |
272 | u16 token, |
273 | u8 irq_index, |
274 | u32 *status) |
275 | { |
276 | struct fsl_mc_command cmd = { 0 }; |
277 | struct dprc_cmd_get_irq_status *cmd_params; |
278 | struct dprc_rsp_get_irq_status *rsp_params; |
279 | int err; |
280 | |
281 | /* prepare command */ |
282 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS, |
283 | cmd_flags, token); |
284 | cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params; |
285 | cmd_params->status = cpu_to_le32(*status); |
286 | cmd_params->irq_index = irq_index; |
287 | |
288 | /* send command to mc*/ |
289 | err = mc_send_command(mc_io, cmd: &cmd); |
290 | if (err) |
291 | return err; |
292 | |
293 | /* retrieve response parameters */ |
294 | rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params; |
295 | *status = le32_to_cpu(rsp_params->status); |
296 | |
297 | return 0; |
298 | } |
299 | |
300 | /** |
301 | * dprc_clear_irq_status() - Clear a pending interrupt's status |
302 | * @mc_io: Pointer to MC portal's I/O object |
303 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
304 | * @token: Token of DPRC object |
305 | * @irq_index: The interrupt index to configure |
306 | * @status: bits to clear (W1C) - one bit per cause: |
307 | * 0 = don't change |
308 | * 1 = clear status bit |
309 | * |
310 | * Return: '0' on Success; Error code otherwise. |
311 | */ |
312 | int dprc_clear_irq_status(struct fsl_mc_io *mc_io, |
313 | u32 cmd_flags, |
314 | u16 token, |
315 | u8 irq_index, |
316 | u32 status) |
317 | { |
318 | struct fsl_mc_command cmd = { 0 }; |
319 | struct dprc_cmd_clear_irq_status *cmd_params; |
320 | |
321 | /* prepare command */ |
322 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS, |
323 | cmd_flags, token); |
324 | cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params; |
325 | cmd_params->status = cpu_to_le32(status); |
326 | cmd_params->irq_index = irq_index; |
327 | |
328 | /* send command to mc*/ |
329 | return mc_send_command(mc_io, cmd: &cmd); |
330 | } |
331 | |
332 | /** |
333 | * dprc_get_attributes() - Obtains container attributes |
334 | * @mc_io: Pointer to MC portal's I/O object |
335 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
336 | * @token: Token of DPRC object |
337 | * @attr: Returned container attributes |
338 | * |
339 | * Return: '0' on Success; Error code otherwise. |
340 | */ |
341 | int dprc_get_attributes(struct fsl_mc_io *mc_io, |
342 | u32 cmd_flags, |
343 | u16 token, |
344 | struct dprc_attributes *attr) |
345 | { |
346 | struct fsl_mc_command cmd = { 0 }; |
347 | struct dprc_rsp_get_attributes *rsp_params; |
348 | int err; |
349 | |
350 | /* prepare command */ |
351 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR, |
352 | cmd_flags, |
353 | token); |
354 | |
355 | /* send command to mc*/ |
356 | err = mc_send_command(mc_io, cmd: &cmd); |
357 | if (err) |
358 | return err; |
359 | |
360 | /* retrieve response parameters */ |
361 | rsp_params = (struct dprc_rsp_get_attributes *)cmd.params; |
362 | attr->container_id = le32_to_cpu(rsp_params->container_id); |
363 | attr->icid = le32_to_cpu(rsp_params->icid); |
364 | attr->options = le32_to_cpu(rsp_params->options); |
365 | attr->portal_id = le32_to_cpu(rsp_params->portal_id); |
366 | |
367 | return 0; |
368 | } |
369 | |
370 | /** |
371 | * dprc_get_obj_count() - Obtains the number of objects in the DPRC |
372 | * @mc_io: Pointer to MC portal's I/O object |
373 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
374 | * @token: Token of DPRC object |
375 | * @obj_count: Number of objects assigned to the DPRC |
376 | * |
377 | * Return: '0' on Success; Error code otherwise. |
378 | */ |
379 | int dprc_get_obj_count(struct fsl_mc_io *mc_io, |
380 | u32 cmd_flags, |
381 | u16 token, |
382 | int *obj_count) |
383 | { |
384 | struct fsl_mc_command cmd = { 0 }; |
385 | struct dprc_rsp_get_obj_count *rsp_params; |
386 | int err; |
387 | |
388 | /* prepare command */ |
389 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT, |
390 | cmd_flags, token); |
391 | |
392 | /* send command to mc*/ |
393 | err = mc_send_command(mc_io, cmd: &cmd); |
394 | if (err) |
395 | return err; |
396 | |
397 | /* retrieve response parameters */ |
398 | rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params; |
399 | *obj_count = le32_to_cpu(rsp_params->obj_count); |
400 | |
401 | return 0; |
402 | } |
403 | EXPORT_SYMBOL_GPL(dprc_get_obj_count); |
404 | |
405 | /** |
406 | * dprc_get_obj() - Get general information on an object |
407 | * @mc_io: Pointer to MC portal's I/O object |
408 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
409 | * @token: Token of DPRC object |
410 | * @obj_index: Index of the object to be queried (< obj_count) |
411 | * @obj_desc: Returns the requested object descriptor |
412 | * |
413 | * The object descriptors are retrieved one by one by incrementing |
414 | * obj_index up to (not including) the value of obj_count returned |
415 | * from dprc_get_obj_count(). dprc_get_obj_count() must |
416 | * be called prior to dprc_get_obj(). |
417 | * |
418 | * Return: '0' on Success; Error code otherwise. |
419 | */ |
420 | int dprc_get_obj(struct fsl_mc_io *mc_io, |
421 | u32 cmd_flags, |
422 | u16 token, |
423 | int obj_index, |
424 | struct fsl_mc_obj_desc *obj_desc) |
425 | { |
426 | struct fsl_mc_command cmd = { 0 }; |
427 | struct dprc_cmd_get_obj *cmd_params; |
428 | struct dprc_rsp_get_obj *rsp_params; |
429 | int err; |
430 | |
431 | /* prepare command */ |
432 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ, |
433 | cmd_flags, |
434 | token); |
435 | cmd_params = (struct dprc_cmd_get_obj *)cmd.params; |
436 | cmd_params->obj_index = cpu_to_le32(obj_index); |
437 | |
438 | /* send command to mc*/ |
439 | err = mc_send_command(mc_io, cmd: &cmd); |
440 | if (err) |
441 | return err; |
442 | |
443 | /* retrieve response parameters */ |
444 | rsp_params = (struct dprc_rsp_get_obj *)cmd.params; |
445 | obj_desc->id = le32_to_cpu(rsp_params->id); |
446 | obj_desc->vendor = le16_to_cpu(rsp_params->vendor); |
447 | obj_desc->irq_count = rsp_params->irq_count; |
448 | obj_desc->region_count = rsp_params->region_count; |
449 | obj_desc->state = le32_to_cpu(rsp_params->state); |
450 | obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); |
451 | obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); |
452 | obj_desc->flags = le16_to_cpu(rsp_params->flags); |
453 | strscpy_pad(obj_desc->type, rsp_params->type, 16); |
454 | strscpy_pad(obj_desc->label, rsp_params->label, 16); |
455 | return 0; |
456 | } |
457 | EXPORT_SYMBOL_GPL(dprc_get_obj); |
458 | |
459 | /** |
460 | * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt. |
461 | * @mc_io: Pointer to MC portal's I/O object |
462 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
463 | * @token: Token of DPRC object |
464 | * @obj_type: Type of the object to set its IRQ |
465 | * @obj_id: ID of the object to set its IRQ |
466 | * @irq_index: The interrupt index to configure |
467 | * @irq_cfg: IRQ configuration |
468 | * |
469 | * Return: '0' on Success; Error code otherwise. |
470 | */ |
471 | int dprc_set_obj_irq(struct fsl_mc_io *mc_io, |
472 | u32 cmd_flags, |
473 | u16 token, |
474 | char *obj_type, |
475 | int obj_id, |
476 | u8 irq_index, |
477 | struct dprc_irq_cfg *irq_cfg) |
478 | { |
479 | struct fsl_mc_command cmd = { 0 }; |
480 | struct dprc_cmd_set_obj_irq *cmd_params; |
481 | |
482 | /* prepare command */ |
483 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ, |
484 | cmd_flags, |
485 | token); |
486 | cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params; |
487 | cmd_params->irq_val = cpu_to_le32(irq_cfg->val); |
488 | cmd_params->irq_index = irq_index; |
489 | cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); |
490 | cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); |
491 | cmd_params->obj_id = cpu_to_le32(obj_id); |
492 | strscpy_pad(cmd_params->obj_type, obj_type, 16); |
493 | |
494 | /* send command to mc*/ |
495 | return mc_send_command(mc_io, cmd: &cmd); |
496 | } |
497 | EXPORT_SYMBOL_GPL(dprc_set_obj_irq); |
498 | |
499 | /** |
500 | * dprc_get_obj_region() - Get region information for a specified object. |
501 | * @mc_io: Pointer to MC portal's I/O object |
502 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
503 | * @token: Token of DPRC object |
504 | * @obj_type: Object type as returned in dprc_get_obj() |
505 | * @obj_id: Unique object instance as returned in dprc_get_obj() |
506 | * @region_index: The specific region to query |
507 | * @region_desc: Returns the requested region descriptor |
508 | * |
509 | * Return: '0' on Success; Error code otherwise. |
510 | */ |
511 | int dprc_get_obj_region(struct fsl_mc_io *mc_io, |
512 | u32 cmd_flags, |
513 | u16 token, |
514 | char *obj_type, |
515 | int obj_id, |
516 | u8 region_index, |
517 | struct dprc_region_desc *region_desc) |
518 | { |
519 | struct fsl_mc_command cmd = { 0 }; |
520 | struct dprc_cmd_get_obj_region *cmd_params; |
521 | struct dprc_rsp_get_obj_region *rsp_params; |
522 | int err; |
523 | |
524 | /* |
525 | * If the DPRC object version was not yet cached, cache it now. |
526 | * Otherwise use the already cached value. |
527 | */ |
528 | if (!dprc_major_ver && !dprc_minor_ver) { |
529 | err = dprc_get_api_version(mc_io, cmd_flags: 0, |
530 | major_ver: &dprc_major_ver, |
531 | minor_ver: &dprc_minor_ver); |
532 | if (err) |
533 | return err; |
534 | } |
535 | |
536 | if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 6)) { |
537 | /* |
538 | * MC API version 6.6 changed the size of the MC portals and software |
539 | * portals to 64K (as implemented by hardware). If older API is in use the |
540 | * size reported is less (64 bytes for mc portals and 4K for software |
541 | * portals). |
542 | */ |
543 | |
544 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V3, |
545 | cmd_flags, token); |
546 | |
547 | } else if (dprc_major_ver == 6 && dprc_minor_ver >= 3) { |
548 | /* |
549 | * MC API version 6.3 introduced a new field to the region |
550 | * descriptor: base_address. If the older API is in use then the base |
551 | * address is set to zero to indicate it needs to be obtained elsewhere |
552 | * (typically the device tree). |
553 | */ |
554 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2, |
555 | cmd_flags, token); |
556 | } else { |
557 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, |
558 | cmd_flags, token); |
559 | } |
560 | |
561 | cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; |
562 | cmd_params->obj_id = cpu_to_le32(obj_id); |
563 | cmd_params->region_index = region_index; |
564 | strscpy_pad(cmd_params->obj_type, obj_type, 16); |
565 | |
566 | /* send command to mc*/ |
567 | err = mc_send_command(mc_io, cmd: &cmd); |
568 | if (err) |
569 | return err; |
570 | |
571 | /* retrieve response parameters */ |
572 | rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params; |
573 | region_desc->base_offset = le64_to_cpu(rsp_params->base_offset); |
574 | region_desc->size = le32_to_cpu(rsp_params->size); |
575 | region_desc->type = rsp_params->type; |
576 | region_desc->flags = le32_to_cpu(rsp_params->flags); |
577 | if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3)) |
578 | region_desc->base_address = le64_to_cpu(rsp_params->base_addr); |
579 | else |
580 | region_desc->base_address = 0; |
581 | |
582 | return 0; |
583 | } |
584 | EXPORT_SYMBOL_GPL(dprc_get_obj_region); |
585 | |
586 | /** |
587 | * dprc_get_api_version - Get Data Path Resource Container API version |
588 | * @mc_io: Pointer to Mc portal's I/O object |
589 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
590 | * @major_ver: Major version of Data Path Resource Container API |
591 | * @minor_ver: Minor version of Data Path Resource Container API |
592 | * |
593 | * Return: '0' on Success; Error code otherwise. |
594 | */ |
595 | int dprc_get_api_version(struct fsl_mc_io *mc_io, |
596 | u32 cmd_flags, |
597 | u16 *major_ver, |
598 | u16 *minor_ver) |
599 | { |
600 | struct fsl_mc_command cmd = { 0 }; |
601 | int err; |
602 | |
603 | /* prepare command */ |
604 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION, |
605 | cmd_flags, token: 0); |
606 | |
607 | /* send command to mc */ |
608 | err = mc_send_command(mc_io, cmd: &cmd); |
609 | if (err) |
610 | return err; |
611 | |
612 | /* retrieve response parameters */ |
613 | mc_cmd_read_api_version(cmd: &cmd, major_ver, minor_ver); |
614 | |
615 | return 0; |
616 | } |
617 | |
618 | /** |
619 | * dprc_get_container_id - Get container ID associated with a given portal. |
620 | * @mc_io: Pointer to Mc portal's I/O object |
621 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
622 | * @container_id: Requested container id |
623 | * |
624 | * Return: '0' on Success; Error code otherwise. |
625 | */ |
626 | int dprc_get_container_id(struct fsl_mc_io *mc_io, |
627 | u32 cmd_flags, |
628 | int *container_id) |
629 | { |
630 | struct fsl_mc_command cmd = { 0 }; |
631 | int err; |
632 | |
633 | /* prepare command */ |
634 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID, |
635 | cmd_flags, |
636 | token: 0); |
637 | |
638 | /* send command to mc*/ |
639 | err = mc_send_command(mc_io, cmd: &cmd); |
640 | if (err) |
641 | return err; |
642 | |
643 | /* retrieve response parameters */ |
644 | *container_id = (int)mc_cmd_read_object_id(cmd: &cmd); |
645 | |
646 | return 0; |
647 | } |
648 | |
649 | /** |
650 | * dprc_get_connection() - Get connected endpoint and link status if connection |
651 | * exists. |
652 | * @mc_io: Pointer to MC portal's I/O object |
653 | * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' |
654 | * @token: Token of DPRC object |
655 | * @endpoint1: Endpoint 1 configuration parameters |
656 | * @endpoint2: Returned endpoint 2 configuration parameters |
657 | * @state: Returned link state: |
658 | * 1 - link is up; |
659 | * 0 - link is down; |
660 | * -1 - no connection (endpoint2 information is irrelevant) |
661 | * |
662 | * Return: '0' on Success; -ENOTCONN if connection does not exist. |
663 | */ |
664 | int dprc_get_connection(struct fsl_mc_io *mc_io, |
665 | u32 cmd_flags, |
666 | u16 token, |
667 | const struct dprc_endpoint *endpoint1, |
668 | struct dprc_endpoint *endpoint2, |
669 | int *state) |
670 | { |
671 | struct dprc_cmd_get_connection *cmd_params; |
672 | struct dprc_rsp_get_connection *rsp_params; |
673 | struct fsl_mc_command cmd = { 0 }; |
674 | int err, i; |
675 | |
676 | /* prepare command */ |
677 | cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, |
678 | cmd_flags, |
679 | token); |
680 | cmd_params = (struct dprc_cmd_get_connection *)cmd.params; |
681 | cmd_params->ep1_id = cpu_to_le32(endpoint1->id); |
682 | cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id); |
683 | for (i = 0; i < 16; i++) |
684 | cmd_params->ep1_type[i] = endpoint1->type[i]; |
685 | |
686 | /* send command to mc */ |
687 | err = mc_send_command(mc_io, cmd: &cmd); |
688 | if (err) |
689 | return -ENOTCONN; |
690 | |
691 | /* retrieve response parameters */ |
692 | rsp_params = (struct dprc_rsp_get_connection *)cmd.params; |
693 | endpoint2->id = le32_to_cpu(rsp_params->ep2_id); |
694 | endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id); |
695 | *state = le32_to_cpu(rsp_params->state); |
696 | for (i = 0; i < 16; i++) |
697 | endpoint2->type[i] = rsp_params->ep2_type[i]; |
698 | |
699 | return 0; |
700 | } |
701 | |