Merge branch 'fix/rt5645' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-block.git] / drivers / staging / fsl-mc / bus / dpbp.c
CommitLineData
197f4d6a
GR
1/* Copyright 2013-2014 Freescale Semiconductor Inc.
2*
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.
13*
14*
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
18* later version.
19*
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.
31*/
32#include "../include/mc-sys.h"
33#include "../include/mc-cmd.h"
34#include "../include/dpbp.h"
35#include "../include/dpbp-cmd.h"
36
e9bf3f20
GR
37/**
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
43 *
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
51 *
52 * Return: '0' on Success; Error code otherwise.
53 */
c4d88721 54int dpbp_open(struct fsl_mc_io *mc_io,
ba72f25b 55 u32 cmd_flags,
c4d88721 56 int dpbp_id,
ba72f25b 57 u16 *token)
197f4d6a
GR
58{
59 struct mc_command cmd = { 0 };
60 int err;
61
62 /* prepare command */
63 cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
c4d88721 64 cmd_flags, 0);
197f4d6a
GR
65 cmd.params[0] |= mc_enc(0, 32, dpbp_id);
66
67 /* send command to mc*/
68 err = mc_send_command(mc_io, &cmd);
69 if (err)
70 return err;
71
72 /* retrieve response parameters */
73 *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
74
75 return err;
76}
77EXPORT_SYMBOL(dpbp_open);
78
e9bf3f20
GR
79/**
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
84 *
85 * After this function is called, no further operations are
86 * allowed on the object without opening a new control session.
87 *
88 * Return: '0' on Success; Error code otherwise.
89 */
c4d88721 90int dpbp_close(struct fsl_mc_io *mc_io,
ba72f25b
GR
91 u32 cmd_flags,
92 u16 token)
197f4d6a
GR
93{
94 struct mc_command cmd = { 0 };
95
96 /* prepare command */
c4d88721 97 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
197f4d6a
GR
98 token);
99
100 /* send command to mc*/
101 return mc_send_command(mc_io, &cmd);
102}
103EXPORT_SYMBOL(dpbp_close);
104
e9bf3f20
GR
105/**
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
111 *
112 * Create the DPBP object, allocate required resources and
113 * perform required initialization.
114 *
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
122 * token first.
123 *
124 * Return: '0' on Success; Error code otherwise.
125 */
197f4d6a 126int dpbp_create(struct fsl_mc_io *mc_io,
ba72f25b 127 u32 cmd_flags,
197f4d6a 128 const struct dpbp_cfg *cfg,
ba72f25b 129 u16 *token)
197f4d6a
GR
130{
131 struct mc_command cmd = { 0 };
132 int err;
133
134 (void)(cfg); /* unused */
135
136 /* prepare command */
137 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE,
c4d88721 138 cmd_flags, 0);
197f4d6a
GR
139
140 /* send command to mc*/
141 err = mc_send_command(mc_io, &cmd);
142 if (err)
143 return err;
144
145 /* retrieve response parameters */
146 *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
147
148 return 0;
149}
150
e9bf3f20
GR
151/**
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
156 *
157 * Return: '0' on Success; error code otherwise.
158 */
c4d88721 159int dpbp_destroy(struct fsl_mc_io *mc_io,
ba72f25b
GR
160 u32 cmd_flags,
161 u16 token)
197f4d6a
GR
162{
163 struct mc_command cmd = { 0 };
164
165 /* prepare command */
166 cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
c4d88721 167 cmd_flags, token);
197f4d6a
GR
168
169 /* send command to mc*/
170 return mc_send_command(mc_io, &cmd);
171}
172
e9bf3f20
GR
173/**
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
178 *
179 * Return: '0' on Success; Error code otherwise.
180 */
c4d88721 181int dpbp_enable(struct fsl_mc_io *mc_io,
ba72f25b
GR
182 u32 cmd_flags,
183 u16 token)
197f4d6a
GR
184{
185 struct mc_command cmd = { 0 };
186
187 /* prepare command */
c4d88721 188 cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
197f4d6a
GR
189 token);
190
191 /* send command to mc*/
192 return mc_send_command(mc_io, &cmd);
193}
194EXPORT_SYMBOL(dpbp_enable);
195
e9bf3f20
GR
196/**
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
201 *
202 * Return: '0' on Success; Error code otherwise.
203 */
c4d88721 204int dpbp_disable(struct fsl_mc_io *mc_io,
ba72f25b
GR
205 u32 cmd_flags,
206 u16 token)
197f4d6a
GR
207{
208 struct mc_command cmd = { 0 };
209
210 /* prepare command */
211 cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
c4d88721 212 cmd_flags, token);
197f4d6a
GR
213
214 /* send command to mc*/
215 return mc_send_command(mc_io, &cmd);
216}
217EXPORT_SYMBOL(dpbp_disable);
218
e9bf3f20
GR
219/**
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
225 *
226 * Return: '0' on Success; Error code otherwise.
227 */
c4d88721 228int dpbp_is_enabled(struct fsl_mc_io *mc_io,
ba72f25b
GR
229 u32 cmd_flags,
230 u16 token,
c4d88721 231 int *en)
197f4d6a
GR
232{
233 struct mc_command cmd = { 0 };
234 int err;
235 /* prepare command */
c4d88721 236 cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
197f4d6a
GR
237 token);
238
239 /* send command to mc*/
240 err = mc_send_command(mc_io, &cmd);
241 if (err)
242 return err;
243
244 /* retrieve response parameters */
245 *en = (int)mc_dec(cmd.params[0], 0, 1);
246
247 return 0;
248}
249
e9bf3f20
GR
250/**
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
255 *
256 * Return: '0' on Success; Error code otherwise.
257 */
c4d88721 258int dpbp_reset(struct fsl_mc_io *mc_io,
ba72f25b
GR
259 u32 cmd_flags,
260 u16 token)
197f4d6a
GR
261{
262 struct mc_command cmd = { 0 };
263
264 /* prepare command */
265 cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
c4d88721 266 cmd_flags, token);
197f4d6a
GR
267
268 /* send command to mc*/
269 return mc_send_command(mc_io, &cmd);
270}
271
e9bf3f20
GR
272/**
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
279 *
280 * Return: '0' on Success; Error code otherwise.
281 */
197f4d6a 282int dpbp_set_irq(struct fsl_mc_io *mc_io,
ba72f25b
GR
283 u32 cmd_flags,
284 u16 token,
285 u8 irq_index,
c4d88721 286 struct dpbp_irq_cfg *irq_cfg)
197f4d6a
GR
287{
288 struct mc_command cmd = { 0 };
289
290 /* prepare command */
291 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ,
c4d88721 292 cmd_flags, token);
197f4d6a 293 cmd.params[0] |= mc_enc(0, 8, irq_index);
c4d88721
GR
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->user_irq_id);
197f4d6a
GR
297
298 /* send command to mc*/
299 return mc_send_command(mc_io, &cmd);
300}
301
e9bf3f20
GR
302/**
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
311 *
312 * Return: '0' on Success; Error code otherwise.
313 */
197f4d6a 314int dpbp_get_irq(struct fsl_mc_io *mc_io,
ba72f25b
GR
315 u32 cmd_flags,
316 u16 token,
317 u8 irq_index,
197f4d6a 318 int *type,
c4d88721 319 struct dpbp_irq_cfg *irq_cfg)
197f4d6a
GR
320{
321 struct mc_command cmd = { 0 };
322 int err;
323
324 /* prepare command */
325 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ,
c4d88721 326 cmd_flags, token);
197f4d6a
GR
327 cmd.params[0] |= mc_enc(32, 8, irq_index);
328
329 /* send command to mc*/
330 err = mc_send_command(mc_io, &cmd);
331 if (err)
332 return err;
333
334 /* retrieve response parameters */
ba72f25b
GR
335 irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32);
336 irq_cfg->addr = (u64)mc_dec(cmd.params[1], 0, 64);
c4d88721 337 irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
197f4d6a
GR
338 *type = (int)mc_dec(cmd.params[2], 32, 32);
339 return 0;
340}
341
e9bf3f20
GR
342/**
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
349 *
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
353 * an interrupt.
354 *
355 * Return: '0' on Success; Error code otherwise.
356 */
197f4d6a 357int dpbp_set_irq_enable(struct fsl_mc_io *mc_io,
ba72f25b
GR
358 u32 cmd_flags,
359 u16 token,
360 u8 irq_index,
361 u8 en)
197f4d6a
GR
362{
363 struct mc_command cmd = { 0 };
364
365 /* prepare command */
366 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE,
c4d88721 367 cmd_flags, token);
197f4d6a
GR
368 cmd.params[0] |= mc_enc(0, 8, en);
369 cmd.params[0] |= mc_enc(32, 8, irq_index);
370
371 /* send command to mc*/
372 return mc_send_command(mc_io, &cmd);
373}
374
e9bf3f20
GR
375/**
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
382 *
383 * Return: '0' on Success; Error code otherwise.
384 */
197f4d6a 385int dpbp_get_irq_enable(struct fsl_mc_io *mc_io,
ba72f25b
GR
386 u32 cmd_flags,
387 u16 token,
388 u8 irq_index,
389 u8 *en)
197f4d6a
GR
390{
391 struct mc_command cmd = { 0 };
392 int err;
393
394 /* prepare command */
395 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE,
c4d88721 396 cmd_flags, token);
197f4d6a
GR
397 cmd.params[0] |= mc_enc(32, 8, irq_index);
398
399 /* send command to mc*/
400 err = mc_send_command(mc_io, &cmd);
401 if (err)
402 return err;
403
404 /* retrieve response parameters */
ba72f25b 405 *en = (u8)mc_dec(cmd.params[0], 0, 8);
197f4d6a
GR
406 return 0;
407}
408
e9bf3f20
GR
409/**
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;
416 * each bit:
417 * 0 = ignore event
418 * 1 = consider event for asserting IRQ
419 *
420 * Every interrupt can have up to 32 causes and the interrupt model supports
421 * masking/unmasking each cause independently
422 *
423 * Return: '0' on Success; Error code otherwise.
424 */
197f4d6a 425int dpbp_set_irq_mask(struct fsl_mc_io *mc_io,
ba72f25b
GR
426 u32 cmd_flags,
427 u16 token,
428 u8 irq_index,
429 u32 mask)
197f4d6a
GR
430{
431 struct mc_command cmd = { 0 };
432
433 /* prepare command */
434 cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK,
c4d88721 435 cmd_flags, token);
197f4d6a
GR
436 cmd.params[0] |= mc_enc(0, 32, mask);
437 cmd.params[0] |= mc_enc(32, 8, irq_index);
438
439 /* send command to mc*/
440 return mc_send_command(mc_io, &cmd);
441}
442
e9bf3f20
GR
443/**
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
450 *
451 * Every interrupt can have up to 32 causes and the interrupt model supports
452 * masking/unmasking each cause independently
453 *
454 * Return: '0' on Success; Error code otherwise.
455 */
197f4d6a 456int dpbp_get_irq_mask(struct fsl_mc_io *mc_io,
ba72f25b
GR
457 u32 cmd_flags,
458 u16 token,
459 u8 irq_index,
460 u32 *mask)
197f4d6a
GR
461{
462 struct mc_command cmd = { 0 };
463 int err;
464
465 /* prepare command */
466 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK,
c4d88721 467 cmd_flags, token);
197f4d6a
GR
468 cmd.params[0] |= mc_enc(32, 8, irq_index);
469
470 /* send command to mc*/
471 err = mc_send_command(mc_io, &cmd);
472 if (err)
473 return err;
474
475 /* retrieve response parameters */
ba72f25b 476 *mask = (u32)mc_dec(cmd.params[0], 0, 32);
197f4d6a
GR
477 return 0;
478}
479
e9bf3f20
GR
480/**
481 * dpbp_get_irq_status() - Get the current status of any pending interrupts.
482 *
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
490 *
491 * Return: '0' on Success; Error code otherwise.
492 */
197f4d6a 493int dpbp_get_irq_status(struct fsl_mc_io *mc_io,
ba72f25b
GR
494 u32 cmd_flags,
495 u16 token,
496 u8 irq_index,
497 u32 *status)
197f4d6a
GR
498{
499 struct mc_command cmd = { 0 };
500 int err;
501
502 /* prepare command */
503 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS,
c4d88721 504 cmd_flags, token);
197f4d6a
GR
505 cmd.params[0] |= mc_enc(32, 8, irq_index);
506
507 /* send command to mc*/
508 err = mc_send_command(mc_io, &cmd);
509 if (err)
510 return err;
511
512 /* retrieve response parameters */
ba72f25b 513 *status = (u32)mc_dec(cmd.params[0], 0, 32);
197f4d6a
GR
514 return 0;
515}
516
e9bf3f20
GR
517/**
518 * dpbp_clear_irq_status() - Clear a pending interrupt's status
519 *
520 * @mc_io: Pointer to MC portal's I/O object
521 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
522 * @token: Token of DPBP object
523 * @irq_index: The interrupt index to configure
524 * @status: Bits to clear (W1C) - one bit per cause:
525 * 0 = don't change
526 * 1 = clear status bit
527 *
528 * Return: '0' on Success; Error code otherwise.
529 */
197f4d6a 530int dpbp_clear_irq_status(struct fsl_mc_io *mc_io,
ba72f25b
GR
531 u32 cmd_flags,
532 u16 token,
533 u8 irq_index,
534 u32 status)
197f4d6a
GR
535{
536 struct mc_command cmd = { 0 };
537
538 /* prepare command */
539 cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS,
c4d88721 540 cmd_flags, token);
197f4d6a
GR
541 cmd.params[0] |= mc_enc(0, 32, status);
542 cmd.params[0] |= mc_enc(32, 8, irq_index);
543
544 /* send command to mc*/
545 return mc_send_command(mc_io, &cmd);
546}
547
e9bf3f20
GR
548/**
549 * dpbp_get_attributes - Retrieve DPBP attributes.
550 *
551 * @mc_io: Pointer to MC portal's I/O object
552 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
553 * @token: Token of DPBP object
554 * @attr: Returned object's attributes
555 *
556 * Return: '0' on Success; Error code otherwise.
557 */
197f4d6a 558int dpbp_get_attributes(struct fsl_mc_io *mc_io,
ba72f25b
GR
559 u32 cmd_flags,
560 u16 token,
197f4d6a
GR
561 struct dpbp_attr *attr)
562{
563 struct mc_command cmd = { 0 };
564 int err;
565
566 /* prepare command */
567 cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
c4d88721 568 cmd_flags, token);
197f4d6a
GR
569
570 /* send command to mc*/
571 err = mc_send_command(mc_io, &cmd);
572 if (err)
573 return err;
574
575 /* retrieve response parameters */
ba72f25b 576 attr->bpid = (u16)mc_dec(cmd.params[0], 16, 16);
197f4d6a 577 attr->id = (int)mc_dec(cmd.params[0], 32, 32);
ba72f25b
GR
578 attr->version.major = (u16)mc_dec(cmd.params[1], 0, 16);
579 attr->version.minor = (u16)mc_dec(cmd.params[1], 16, 16);
197f4d6a
GR
580 return 0;
581}
582EXPORT_SYMBOL(dpbp_get_attributes);