1 /* Copyright 2013-2014 Freescale Semiconductor Inc.
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5 * * Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * * Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 * * Neither the name of the above-listed copyright holders nor the
11 * names of any contributors may be used to endorse or promote products
12 * derived from this software without specific prior written permission.
15 * ALTERNATIVELY, this software may be distributed under the terms of the
16 * GNU General Public License ("GPL") as published by the Free Software
17 * Foundation, either version 2 of that License or (at your option) any
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
32 #include "../include/mc-sys.h"
33 #include "../include/mc-cmd.h"
34 #include "../include/dpbp.h"
35 #include "../include/dpbp-cmd.h"
38 * dpbp_open() - Open a control session for the specified object.
39 * @mc_io: Pointer to MC portal's I/O object
40 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
41 * @dpbp_id: DPBP unique ID
42 * @token: Returned token; use in subsequent API calls
44 * This function can be used to open a control session for an
45 * already created object; an object may have been declared in
46 * the DPL or by calling the dpbp_create function.
47 * This function returns a unique authentication token,
48 * associated with the specific object ID and the specific MC
49 * portal; this token must be used in all subsequent commands for
50 * this specific object
52 * Return: '0' on Success; Error code otherwise.
54 int dpbp_open(struct fsl_mc_io *mc_io,
59 struct mc_command cmd = { 0 };
63 cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
65 cmd.params[0] |= mc_enc(0, 32, dpbp_id);
67 /* send command to mc*/
68 err = mc_send_command(mc_io, &cmd);
72 /* retrieve response parameters */
73 *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
77 EXPORT_SYMBOL(dpbp_open);
80 * dpbp_close() - Close the control session of the object
81 * @mc_io: Pointer to MC portal's I/O object
82 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
83 * @token: Token of DPBP object
85 * After this function is called, no further operations are
86 * allowed on the object without opening a new control session.
88 * Return: '0' on Success; Error code otherwise.
90 int dpbp_close(struct fsl_mc_io *mc_io,
94 struct mc_command cmd = { 0 };
97 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
100 /* send command to mc*/
101 return mc_send_command(mc_io, &cmd);
103 EXPORT_SYMBOL(dpbp_close);
106 * dpbp_create() - Create the DPBP object.
107 * @mc_io: Pointer to MC portal's I/O object
108 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
109 * @cfg: Configuration structure
110 * @token: Returned token; use in subsequent API calls
112 * Create the DPBP object, allocate required resources and
113 * perform required initialization.
115 * The object can be created either by declaring it in the
116 * DPL file, or by calling this function.
117 * This function returns a unique authentication token,
118 * associated with the specific object ID and the specific MC
119 * portal; this token must be used in all subsequent calls to
120 * this specific object. For objects that are created using the
121 * DPL file, call dpbp_open function to get an authentication
124 * Return: '0' on Success; Error code otherwise.
126 int dpbp_create(struct fsl_mc_io *mc_io,
128 const struct dpbp_cfg *cfg,
131 struct mc_command cmd = { 0 };
134 (void)(cfg); /* unused */
136 /* prepare command */
137 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
140 /* send command to mc*/
141 err = mc_send_command(mc_io, &cmd);
145 /* retrieve response parameters */
146 *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
152 * dpbp_destroy() - Destroy the DPBP object and release all its resources.
153 * @mc_io: Pointer to MC portal's I/O object
154 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
155 * @token: Token of DPBP object
157 * Return: '0' on Success; error code otherwise.
159 int dpbp_destroy(struct fsl_mc_io *mc_io,
163 struct mc_command cmd = { 0 };
165 /* prepare command */
166 cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
169 /* send command to mc*/
170 return mc_send_command(mc_io, &cmd);
174 * dpbp_enable() - Enable the DPBP.
175 * @mc_io: Pointer to MC portal's I/O object
176 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
177 * @token: Token of DPBP object
179 * Return: '0' on Success; Error code otherwise.
181 int dpbp_enable(struct fsl_mc_io *mc_io,
185 struct mc_command cmd = { 0 };
187 /* prepare command */
188 cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
191 /* send command to mc*/
192 return mc_send_command(mc_io, &cmd);
194 EXPORT_SYMBOL(dpbp_enable);
197 * dpbp_disable() - Disable the DPBP.
198 * @mc_io: Pointer to MC portal's I/O object
199 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
200 * @token: Token of DPBP object
202 * Return: '0' on Success; Error code otherwise.
204 int dpbp_disable(struct fsl_mc_io *mc_io,
208 struct mc_command cmd = { 0 };
210 /* prepare command */
211 cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
214 /* send command to mc*/
215 return mc_send_command(mc_io, &cmd);
217 EXPORT_SYMBOL(dpbp_disable);
220 * dpbp_is_enabled() - Check if the DPBP is enabled.
221 * @mc_io: Pointer to MC portal's I/O object
222 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
223 * @token: Token of DPBP object
224 * @en: Returns '1' if object is enabled; '0' otherwise
226 * Return: '0' on Success; Error code otherwise.
228 int dpbp_is_enabled(struct fsl_mc_io *mc_io,
233 struct mc_command cmd = { 0 };
235 /* prepare command */
236 cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
239 /* send command to mc*/
240 err = mc_send_command(mc_io, &cmd);
244 /* retrieve response parameters */
245 *en = (int)mc_dec(cmd.params[0], 0, 1);
251 * dpbp_reset() - Reset the DPBP, returns the object to initial state.
252 * @mc_io: Pointer to MC portal's I/O object
253 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
254 * @token: Token of DPBP object
256 * Return: '0' on Success; Error code otherwise.
258 int dpbp_reset(struct fsl_mc_io *mc_io,
262 struct mc_command cmd = { 0 };
264 /* prepare command */
265 cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
268 /* send command to mc*/
269 return mc_send_command(mc_io, &cmd);
273 * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt.
274 * @mc_io: Pointer to MC portal's I/O object
275 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
276 * @token: Token of DPBP object
277 * @irq_index: Identifies the interrupt index to configure
278 * @irq_cfg: IRQ configuration
280 * Return: '0' on Success; Error code otherwise.
282 int dpbp_set_irq(struct fsl_mc_io *mc_io,
286 struct dpbp_irq_cfg *irq_cfg)
288 struct mc_command cmd = { 0 };
290 /* prepare command */
291 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ,
293 cmd.params[0] |= mc_enc(0, 8, irq_index);
294 cmd.params[0] |= mc_enc(32, 32, irq_cfg->val);
295 cmd.params[1] |= mc_enc(0, 64, irq_cfg->addr);
296 cmd.params[2] |= mc_enc(0, 32, irq_cfg->irq_num);
298 /* send command to mc*/
299 return mc_send_command(mc_io, &cmd);
303 * dpbp_get_irq() - Get IRQ information from the DPBP.
304 * @mc_io: Pointer to MC portal's I/O object
305 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
306 * @token: Token of DPBP object
307 * @irq_index: The interrupt index to configure
308 * @type: Interrupt type: 0 represents message interrupt
309 * type (both irq_addr and irq_val are valid)
310 * @irq_cfg: IRQ attributes
312 * Return: '0' on Success; Error code otherwise.
314 int dpbp_get_irq(struct fsl_mc_io *mc_io,
319 struct dpbp_irq_cfg *irq_cfg)
321 struct mc_command cmd = { 0 };
324 /* prepare command */
325 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ,
327 cmd.params[0] |= mc_enc(32, 8, irq_index);
329 /* send command to mc*/
330 err = mc_send_command(mc_io, &cmd);
334 /* retrieve response parameters */
335 irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32);
336 irq_cfg->addr = (u64)mc_dec(cmd.params[1], 0, 64);
337 irq_cfg->irq_num = (int)mc_dec(cmd.params[2], 0, 32);
338 *type = (int)mc_dec(cmd.params[2], 32, 32);
343 * dpbp_set_irq_enable() - Set overall interrupt state.
344 * @mc_io: Pointer to MC portal's I/O object
345 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
346 * @token: Token of DPBP object
347 * @irq_index: The interrupt index to configure
348 * @en: Interrupt state - enable = 1, disable = 0
350 * Allows GPP software to control when interrupts are generated.
351 * Each interrupt can have up to 32 causes. The enable/disable control's the
352 * overall interrupt state. if the interrupt is disabled no causes will cause
355 * Return: '0' on Success; Error code otherwise.
357 int dpbp_set_irq_enable(struct fsl_mc_io *mc_io,
363 struct mc_command cmd = { 0 };
365 /* prepare command */
366 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE,
368 cmd.params[0] |= mc_enc(0, 8, en);
369 cmd.params[0] |= mc_enc(32, 8, irq_index);
371 /* send command to mc*/
372 return mc_send_command(mc_io, &cmd);
376 * dpbp_get_irq_enable() - Get overall interrupt state
377 * @mc_io: Pointer to MC portal's I/O object
378 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
379 * @token: Token of DPBP object
380 * @irq_index: The interrupt index to configure
381 * @en: Returned interrupt state - enable = 1, disable = 0
383 * Return: '0' on Success; Error code otherwise.
385 int dpbp_get_irq_enable(struct fsl_mc_io *mc_io,
391 struct mc_command cmd = { 0 };
394 /* prepare command */
395 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE,
397 cmd.params[0] |= mc_enc(32, 8, irq_index);
399 /* send command to mc*/
400 err = mc_send_command(mc_io, &cmd);
404 /* retrieve response parameters */
405 *en = (u8)mc_dec(cmd.params[0], 0, 8);
410 * dpbp_set_irq_mask() - Set interrupt mask.
411 * @mc_io: Pointer to MC portal's I/O object
412 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
413 * @token: Token of DPBP object
414 * @irq_index: The interrupt index to configure
415 * @mask: Event mask to trigger interrupt;
418 * 1 = consider event for asserting IRQ
420 * Every interrupt can have up to 32 causes and the interrupt model supports
421 * masking/unmasking each cause independently
423 * Return: '0' on Success; Error code otherwise.
425 int dpbp_set_irq_mask(struct fsl_mc_io *mc_io,
431 struct mc_command cmd = { 0 };
433 /* prepare command */
434 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK,
436 cmd.params[0] |= mc_enc(0, 32, mask);
437 cmd.params[0] |= mc_enc(32, 8, irq_index);
439 /* send command to mc*/
440 return mc_send_command(mc_io, &cmd);
444 * dpbp_get_irq_mask() - Get interrupt mask.
445 * @mc_io: Pointer to MC portal's I/O object
446 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
447 * @token: Token of DPBP object
448 * @irq_index: The interrupt index to configure
449 * @mask: Returned event mask to trigger interrupt
451 * Every interrupt can have up to 32 causes and the interrupt model supports
452 * masking/unmasking each cause independently
454 * Return: '0' on Success; Error code otherwise.
456 int dpbp_get_irq_mask(struct fsl_mc_io *mc_io,
462 struct mc_command cmd = { 0 };
465 /* prepare command */
466 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK,
468 cmd.params[0] |= mc_enc(32, 8, irq_index);
470 /* send command to mc*/
471 err = mc_send_command(mc_io, &cmd);
475 /* retrieve response parameters */
476 *mask = (u32)mc_dec(cmd.params[0], 0, 32);
481 * dpbp_get_irq_status() - Get the current status of any pending interrupts.
483 * @mc_io: Pointer to MC portal's I/O object
484 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
485 * @token: Token of DPBP object
486 * @irq_index: The interrupt index to configure
487 * @status: Returned interrupts status - one bit per cause:
488 * 0 = no interrupt pending
489 * 1 = interrupt pending
491 * Return: '0' on Success; Error code otherwise.
493 int dpbp_get_irq_status(struct fsl_mc_io *mc_io,
499 struct mc_command cmd = { 0 };
502 /* prepare command */
503 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS,
505 cmd.params[0] |= mc_enc(0, 32, *status);
506 cmd.params[0] |= mc_enc(32, 8, irq_index);
508 /* send command to mc*/
509 err = mc_send_command(mc_io, &cmd);
513 /* retrieve response parameters */
514 *status = (u32)mc_dec(cmd.params[0], 0, 32);
519 * dpbp_clear_irq_status() - Clear a pending interrupt's status
521 * @mc_io: Pointer to MC portal's I/O object
522 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
523 * @token: Token of DPBP object
524 * @irq_index: The interrupt index to configure
525 * @status: Bits to clear (W1C) - one bit per cause:
527 * 1 = clear status bit
529 * Return: '0' on Success; Error code otherwise.
531 int dpbp_clear_irq_status(struct fsl_mc_io *mc_io,
537 struct mc_command cmd = { 0 };
539 /* prepare command */
540 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS,
542 cmd.params[0] |= mc_enc(0, 32, status);
543 cmd.params[0] |= mc_enc(32, 8, irq_index);
545 /* send command to mc*/
546 return mc_send_command(mc_io, &cmd);
550 * dpbp_get_attributes - Retrieve DPBP attributes.
552 * @mc_io: Pointer to MC portal's I/O object
553 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
554 * @token: Token of DPBP object
555 * @attr: Returned object's attributes
557 * Return: '0' on Success; Error code otherwise.
559 int dpbp_get_attributes(struct fsl_mc_io *mc_io,
562 struct dpbp_attr *attr)
564 struct mc_command cmd = { 0 };
567 /* prepare command */
568 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
571 /* send command to mc*/
572 err = mc_send_command(mc_io, &cmd);
576 /* retrieve response parameters */
577 attr->bpid = (u16)mc_dec(cmd.params[0], 16, 16);
578 attr->id = (int)mc_dec(cmd.params[0], 32, 32);
579 attr->version.major = (u16)mc_dec(cmd.params[1], 0, 16);
580 attr->version.minor = (u16)mc_dec(cmd.params[1], 16, 16);
583 EXPORT_SYMBOL(dpbp_get_attributes);
586 * dpbp_set_notifications() - Set notifications towards software
587 * @mc_io: Pointer to MC portal's I/O object
588 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
589 * @token: Token of DPBP object
590 * @cfg: notifications configuration
592 * Return: '0' on Success; Error code otherwise.
594 int dpbp_set_notifications(struct fsl_mc_io *mc_io,
597 struct dpbp_notification_cfg *cfg)
599 struct mc_command cmd = { 0 };
601 /* prepare command */
602 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_NOTIFICATIONS,
606 cmd.params[0] |= mc_enc(0, 32, cfg->depletion_entry);
607 cmd.params[0] |= mc_enc(32, 32, cfg->depletion_exit);
608 cmd.params[1] |= mc_enc(0, 32, cfg->surplus_entry);
609 cmd.params[1] |= mc_enc(32, 32, cfg->surplus_exit);
610 cmd.params[2] |= mc_enc(0, 16, cfg->options);
611 cmd.params[3] |= mc_enc(0, 64, cfg->message_ctx);
612 cmd.params[4] |= mc_enc(0, 64, cfg->message_iova);
614 /* send command to mc*/
615 return mc_send_command(mc_io, &cmd);
619 * dpbp_get_notifications() - Get the notifications configuration
620 * @mc_io: Pointer to MC portal's I/O object
621 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
622 * @token: Token of DPBP object
623 * @cfg: notifications configuration
625 * Return: '0' on Success; Error code otherwise.
627 int dpbp_get_notifications(struct fsl_mc_io *mc_io,
630 struct dpbp_notification_cfg *cfg)
632 struct mc_command cmd = { 0 };
635 /* prepare command */
636 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_NOTIFICATIONS,
640 /* send command to mc*/
641 err = mc_send_command(mc_io, &cmd);
645 /* retrieve response parameters */
646 cfg->depletion_entry = (u32)mc_dec(cmd.params[0], 0, 32);
647 cfg->depletion_exit = (u32)mc_dec(cmd.params[0], 32, 32);
648 cfg->surplus_entry = (u32)mc_dec(cmd.params[1], 0, 32);
649 cfg->surplus_exit = (u32)mc_dec(cmd.params[1], 32, 32);
650 cfg->options = (u16)mc_dec(cmd.params[2], 0, 16);
651 cfg->message_ctx = (u64)mc_dec(cmd.params[3], 0, 64);
652 cfg->message_iova = (u64)mc_dec(cmd.params[4], 0, 64);