These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / fsl-mc / bus / dpbp.c
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
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  */
54 int dpbp_open(struct fsl_mc_io *mc_io,
55               u32 cmd_flags,
56               int dpbp_id,
57               u16 *token)
58 {
59         struct mc_command cmd = { 0 };
60         int err;
61
62         /* prepare command */
63         cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
64                                           cmd_flags, 0);
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 }
77 EXPORT_SYMBOL(dpbp_open);
78
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  */
90 int dpbp_close(struct fsl_mc_io *mc_io,
91                u32 cmd_flags,
92                u16 token)
93 {
94         struct mc_command cmd = { 0 };
95
96         /* prepare command */
97         cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags,
98                                           token);
99
100         /* send command to mc*/
101         return mc_send_command(mc_io, &cmd);
102 }
103 EXPORT_SYMBOL(dpbp_close);
104
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  */
126 int dpbp_create(struct fsl_mc_io *mc_io,
127                 u32 cmd_flags,
128                 const struct dpbp_cfg *cfg,
129                 u16 *token)
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,
138                                           cmd_flags, 0);
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
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  */
159 int dpbp_destroy(struct fsl_mc_io *mc_io,
160                  u32 cmd_flags,
161                  u16 token)
162 {
163         struct mc_command cmd = { 0 };
164
165         /* prepare command */
166         cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY,
167                                           cmd_flags, token);
168
169         /* send command to mc*/
170         return mc_send_command(mc_io, &cmd);
171 }
172
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  */
181 int dpbp_enable(struct fsl_mc_io *mc_io,
182                 u32 cmd_flags,
183                 u16 token)
184 {
185         struct mc_command cmd = { 0 };
186
187         /* prepare command */
188         cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags,
189                                           token);
190
191         /* send command to mc*/
192         return mc_send_command(mc_io, &cmd);
193 }
194 EXPORT_SYMBOL(dpbp_enable);
195
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  */
204 int dpbp_disable(struct fsl_mc_io *mc_io,
205                  u32 cmd_flags,
206                  u16 token)
207 {
208         struct mc_command cmd = { 0 };
209
210         /* prepare command */
211         cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
212                                           cmd_flags, token);
213
214         /* send command to mc*/
215         return mc_send_command(mc_io, &cmd);
216 }
217 EXPORT_SYMBOL(dpbp_disable);
218
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  */
228 int dpbp_is_enabled(struct fsl_mc_io *mc_io,
229                     u32 cmd_flags,
230                     u16 token,
231                     int *en)
232 {
233         struct mc_command cmd = { 0 };
234         int err;
235         /* prepare command */
236         cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags,
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
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  */
258 int dpbp_reset(struct fsl_mc_io *mc_io,
259                u32 cmd_flags,
260                u16 token)
261 {
262         struct mc_command cmd = { 0 };
263
264         /* prepare command */
265         cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
266                                           cmd_flags, token);
267
268         /* send command to mc*/
269         return mc_send_command(mc_io, &cmd);
270 }
271
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  */
282 int dpbp_set_irq(struct fsl_mc_io *mc_io,
283                  u32 cmd_flags,
284                  u16 token,
285                  u8 irq_index,
286                  struct dpbp_irq_cfg *irq_cfg)
287 {
288         struct mc_command cmd = { 0 };
289
290         /* prepare command */
291         cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ,
292                                           cmd_flags, token);
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->user_irq_id);
297
298         /* send command to mc*/
299         return mc_send_command(mc_io, &cmd);
300 }
301
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  */
314 int dpbp_get_irq(struct fsl_mc_io *mc_io,
315                  u32 cmd_flags,
316                  u16 token,
317                  u8 irq_index,
318                  int *type,
319                  struct dpbp_irq_cfg *irq_cfg)
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,
326                                           cmd_flags, token);
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 */
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->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
338         *type = (int)mc_dec(cmd.params[2], 32, 32);
339         return 0;
340 }
341
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  */
357 int dpbp_set_irq_enable(struct fsl_mc_io *mc_io,
358                         u32 cmd_flags,
359                         u16 token,
360                         u8 irq_index,
361                         u8 en)
362 {
363         struct mc_command cmd = { 0 };
364
365         /* prepare command */
366         cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE,
367                                           cmd_flags, token);
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
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  */
385 int dpbp_get_irq_enable(struct fsl_mc_io *mc_io,
386                         u32 cmd_flags,
387                         u16 token,
388                         u8 irq_index,
389                         u8 *en)
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,
396                                           cmd_flags, token);
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 */
405         *en = (u8)mc_dec(cmd.params[0], 0, 8);
406         return 0;
407 }
408
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  */
425 int dpbp_set_irq_mask(struct fsl_mc_io *mc_io,
426                       u32 cmd_flags,
427                       u16 token,
428                       u8 irq_index,
429                       u32 mask)
430 {
431         struct mc_command cmd = { 0 };
432
433         /* prepare command */
434         cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK,
435                                           cmd_flags, token);
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
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  */
456 int dpbp_get_irq_mask(struct fsl_mc_io *mc_io,
457                       u32 cmd_flags,
458                       u16 token,
459                       u8 irq_index,
460                       u32 *mask)
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,
467                                           cmd_flags, token);
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 */
476         *mask = (u32)mc_dec(cmd.params[0], 0, 32);
477         return 0;
478 }
479
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  */
493 int dpbp_get_irq_status(struct fsl_mc_io *mc_io,
494                         u32 cmd_flags,
495                         u16 token,
496                         u8 irq_index,
497                         u32 *status)
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,
504                                           cmd_flags, token);
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 */
513         *status = (u32)mc_dec(cmd.params[0], 0, 32);
514         return 0;
515 }
516
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  */
530 int dpbp_clear_irq_status(struct fsl_mc_io *mc_io,
531                           u32 cmd_flags,
532                           u16 token,
533                           u8 irq_index,
534                           u32 status)
535 {
536         struct mc_command cmd = { 0 };
537
538         /* prepare command */
539         cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS,
540                                           cmd_flags, token);
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
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  */
558 int dpbp_get_attributes(struct fsl_mc_io *mc_io,
559                         u32 cmd_flags,
560                         u16 token,
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,
568                                           cmd_flags, token);
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 */
576         attr->bpid = (u16)mc_dec(cmd.params[0], 16, 16);
577         attr->id = (int)mc_dec(cmd.params[0], 32, 32);
578         attr->version.major = (u16)mc_dec(cmd.params[1], 0, 16);
579         attr->version.minor = (u16)mc_dec(cmd.params[1], 16, 16);
580         return 0;
581 }
582 EXPORT_SYMBOL(dpbp_get_attributes);