]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/fsl-mc/bus/dpmcp.c
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.git] / drivers / staging / fsl-mc / bus / dpmcp.c
1 /* Copyright 2013-2016 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 "dpmcp.h"
35 #include "dpmcp-cmd.h"
36
37 /**
38  * dpmcp_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  * @dpmcp_id:   DPMCP 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 dpmcp_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 dpmcp_open(struct fsl_mc_io *mc_io,
55                u32 cmd_flags,
56                int dpmcp_id,
57                u16 *token)
58 {
59         struct mc_command cmd = { 0 };
60         struct dpmcp_cmd_open *cmd_params;
61         int err;
62
63         /* prepare command */
64         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN,
65                                           cmd_flags, 0);
66         cmd_params = (struct dpmcp_cmd_open *)cmd.params;
67         cmd_params->dpmcp_id = cpu_to_le32(dpmcp_id);
68
69         /* send command to mc*/
70         err = mc_send_command(mc_io, &cmd);
71         if (err)
72                 return err;
73
74         /* retrieve response parameters */
75         *token = mc_cmd_hdr_read_token(&cmd);
76
77         return err;
78 }
79
80 /**
81  * dpmcp_close() - Close the control session of the object
82  * @mc_io:      Pointer to MC portal's I/O object
83  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
84  * @token:      Token of DPMCP object
85  *
86  * After this function is called, no further operations are
87  * allowed on the object without opening a new control session.
88  *
89  * Return:      '0' on Success; Error code otherwise.
90  */
91 int dpmcp_close(struct fsl_mc_io *mc_io,
92                 u32 cmd_flags,
93                 u16 token)
94 {
95         struct mc_command cmd = { 0 };
96
97         /* prepare command */
98         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE,
99                                           cmd_flags, token);
100
101         /* send command to mc*/
102         return mc_send_command(mc_io, &cmd);
103 }
104
105 /**
106  * dpmcp_create() - Create the DPMCP 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 DPMCP 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 dpmcp_open function to get an authentication
122  * token first.
123  *
124  * Return:      '0' on Success; Error code otherwise.
125  */
126 int dpmcp_create(struct fsl_mc_io *mc_io,
127                  u32 cmd_flags,
128                  const struct dpmcp_cfg *cfg,
129                  u16 *token)
130 {
131         struct mc_command cmd = { 0 };
132         struct dpmcp_cmd_create *cmd_params;
133
134         int err;
135
136         /* prepare command */
137         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE,
138                                           cmd_flags, 0);
139         cmd_params = (struct dpmcp_cmd_create *)cmd.params;
140         cmd_params->portal_id = cpu_to_le32(cfg->portal_id);
141
142         /* send command to mc*/
143         err = mc_send_command(mc_io, &cmd);
144         if (err)
145                 return err;
146
147         /* retrieve response parameters */
148         *token = mc_cmd_hdr_read_token(&cmd);
149
150         return 0;
151 }
152
153 /**
154  * dpmcp_destroy() - Destroy the DPMCP object and release all its resources.
155  * @mc_io:      Pointer to MC portal's I/O object
156  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
157  * @token:      Token of DPMCP object
158  *
159  * Return:      '0' on Success; error code otherwise.
160  */
161 int dpmcp_destroy(struct fsl_mc_io *mc_io,
162                   u32 cmd_flags,
163                   u16 token)
164 {
165         struct mc_command cmd = { 0 };
166
167         /* prepare command */
168         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY,
169                                           cmd_flags, token);
170
171         /* send command to mc*/
172         return mc_send_command(mc_io, &cmd);
173 }
174
175 /**
176  * dpmcp_reset() - Reset the DPMCP, returns the object to initial state.
177  * @mc_io:      Pointer to MC portal's I/O object
178  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
179  * @token:      Token of DPMCP object
180  *
181  * Return:      '0' on Success; Error code otherwise.
182  */
183 int dpmcp_reset(struct fsl_mc_io *mc_io,
184                 u32 cmd_flags,
185                 u16 token)
186 {
187         struct mc_command cmd = { 0 };
188
189         /* prepare command */
190         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET,
191                                           cmd_flags, token);
192
193         /* send command to mc*/
194         return mc_send_command(mc_io, &cmd);
195 }
196
197 /**
198  * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt.
199  * @mc_io:      Pointer to MC portal's I/O object
200  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
201  * @token:      Token of DPMCP object
202  * @irq_index:  Identifies the interrupt index to configure
203  * @irq_cfg:    IRQ configuration
204  *
205  * Return:      '0' on Success; Error code otherwise.
206  */
207 int dpmcp_set_irq(struct fsl_mc_io *mc_io,
208                   u32 cmd_flags,
209                   u16 token,
210                   u8 irq_index,
211                   struct dpmcp_irq_cfg  *irq_cfg)
212 {
213         struct mc_command cmd = { 0 };
214         struct dpmcp_cmd_set_irq *cmd_params;
215
216         /* prepare command */
217         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ,
218                                           cmd_flags, token);
219         cmd_params = (struct dpmcp_cmd_set_irq *)cmd.params;
220         cmd_params->irq_index = irq_index;
221         cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
222         cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
223         cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
224
225         /* send command to mc*/
226         return mc_send_command(mc_io, &cmd);
227 }
228
229 /**
230  * dpmcp_get_irq() - Get IRQ information from the DPMCP.
231  * @mc_io:      Pointer to MC portal's I/O object
232  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
233  * @token:      Token of DPMCP object
234  * @irq_index:  The interrupt index to configure
235  * @type:       Interrupt type: 0 represents message interrupt
236  *              type (both irq_addr and irq_val are valid)
237  * @irq_cfg:    IRQ attributes
238  *
239  * Return:      '0' on Success; Error code otherwise.
240  */
241 int dpmcp_get_irq(struct fsl_mc_io *mc_io,
242                   u32 cmd_flags,
243                   u16 token,
244                   u8 irq_index,
245                   int *type,
246                   struct dpmcp_irq_cfg  *irq_cfg)
247 {
248         struct mc_command cmd = { 0 };
249         struct dpmcp_cmd_get_irq *cmd_params;
250         struct dpmcp_rsp_get_irq *rsp_params;
251         int err;
252
253         /* prepare command */
254         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ,
255                                           cmd_flags, token);
256         cmd_params = (struct dpmcp_cmd_get_irq *)cmd.params;
257         cmd_params->irq_index = irq_index;
258
259         /* send command to mc*/
260         err = mc_send_command(mc_io, &cmd);
261         if (err)
262                 return err;
263
264         /* retrieve response parameters */
265         rsp_params = (struct dpmcp_rsp_get_irq *)cmd.params;
266         irq_cfg->val = le32_to_cpu(rsp_params->irq_val);
267         irq_cfg->paddr = le64_to_cpu(rsp_params->irq_paddr);
268         irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num);
269         *type = le32_to_cpu(rsp_params->type);
270         return 0;
271 }
272
273 /**
274  * dpmcp_set_irq_enable() - Set overall interrupt state.
275  * @mc_io:      Pointer to MC portal's I/O object
276  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
277  * @token:      Token of DPMCP object
278  * @irq_index:  The interrupt index to configure
279  * @en: Interrupt state - enable = 1, disable = 0
280  *
281  * Allows GPP software to control when interrupts are generated.
282  * Each interrupt can have up to 32 causes.  The enable/disable control's the
283  * overall interrupt state. if the interrupt is disabled no causes will cause
284  * an interrupt.
285  *
286  * Return:      '0' on Success; Error code otherwise.
287  */
288 int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io,
289                          u32 cmd_flags,
290                          u16 token,
291                          u8 irq_index,
292                          u8 en)
293 {
294         struct mc_command cmd = { 0 };
295         struct dpmcp_cmd_set_irq_enable *cmd_params;
296
297         /* prepare command */
298         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE,
299                                           cmd_flags, token);
300         cmd_params = (struct dpmcp_cmd_set_irq_enable *)cmd.params;
301         cmd_params->enable = en & DPMCP_ENABLE;
302         cmd_params->irq_index = irq_index;
303
304         /* send command to mc*/
305         return mc_send_command(mc_io, &cmd);
306 }
307
308 /**
309  * dpmcp_get_irq_enable() - Get overall interrupt state
310  * @mc_io:      Pointer to MC portal's I/O object
311  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
312  * @token:      Token of DPMCP object
313  * @irq_index:  The interrupt index to configure
314  * @en:         Returned interrupt state - enable = 1, disable = 0
315  *
316  * Return:      '0' on Success; Error code otherwise.
317  */
318 int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io,
319                          u32 cmd_flags,
320                          u16 token,
321                          u8 irq_index,
322                          u8 *en)
323 {
324         struct mc_command cmd = { 0 };
325         struct dpmcp_cmd_get_irq_enable *cmd_params;
326         struct dpmcp_rsp_get_irq_enable *rsp_params;
327         int err;
328
329         /* prepare command */
330         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE,
331                                           cmd_flags, token);
332         cmd_params = (struct dpmcp_cmd_get_irq_enable *)cmd.params;
333         cmd_params->irq_index = irq_index;
334
335         /* send command to mc*/
336         err = mc_send_command(mc_io, &cmd);
337         if (err)
338                 return err;
339
340         /* retrieve response parameters */
341         rsp_params = (struct dpmcp_rsp_get_irq_enable *)cmd.params;
342         *en = rsp_params->enabled & DPMCP_ENABLE;
343         return 0;
344 }
345
346 /**
347  * dpmcp_set_irq_mask() - Set interrupt mask.
348  * @mc_io:      Pointer to MC portal's I/O object
349  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
350  * @token:      Token of DPMCP object
351  * @irq_index:  The interrupt index to configure
352  * @mask:       Event mask to trigger interrupt;
353  *                      each bit:
354  *                              0 = ignore event
355  *                              1 = consider event for asserting IRQ
356  *
357  * Every interrupt can have up to 32 causes and the interrupt model supports
358  * masking/unmasking each cause independently
359  *
360  * Return:      '0' on Success; Error code otherwise.
361  */
362 int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
363                        u32 cmd_flags,
364                        u16 token,
365                        u8 irq_index,
366                        u32 mask)
367 {
368         struct mc_command cmd = { 0 };
369         struct dpmcp_cmd_set_irq_mask *cmd_params;
370
371
372         /* prepare command */
373         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK,
374                                           cmd_flags, token);
375         cmd_params = (struct dpmcp_cmd_set_irq_mask *)cmd.params;
376         cmd_params->mask = cpu_to_le32(mask);
377         cmd_params->irq_index = irq_index;
378
379         /* send command to mc*/
380         return mc_send_command(mc_io, &cmd);
381 }
382
383 /**
384  * dpmcp_get_irq_mask() - Get interrupt mask.
385  * @mc_io:      Pointer to MC portal's I/O object
386  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
387  * @token:      Token of DPMCP object
388  * @irq_index:  The interrupt index to configure
389  * @mask:       Returned event mask to trigger interrupt
390  *
391  * Every interrupt can have up to 32 causes and the interrupt model supports
392  * masking/unmasking each cause independently
393  *
394  * Return:      '0' on Success; Error code otherwise.
395  */
396 int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io,
397                        u32 cmd_flags,
398                        u16 token,
399                        u8 irq_index,
400                        u32 *mask)
401 {
402         struct mc_command cmd = { 0 };
403         struct dpmcp_cmd_get_irq_mask *cmd_params;
404         struct dpmcp_rsp_get_irq_mask *rsp_params;
405
406         int err;
407
408         /* prepare command */
409         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK,
410                                           cmd_flags, token);
411         cmd_params = (struct dpmcp_cmd_get_irq_mask *)cmd.params;
412         cmd_params->irq_index = irq_index;
413
414         /* send command to mc*/
415         err = mc_send_command(mc_io, &cmd);
416         if (err)
417                 return err;
418
419         /* retrieve response parameters */
420         rsp_params = (struct dpmcp_rsp_get_irq_mask *)cmd.params;
421         *mask = le32_to_cpu(rsp_params->mask);
422
423         return 0;
424 }
425
426 /**
427  * dpmcp_get_irq_status() - Get the current status of any pending interrupts.
428  *
429  * @mc_io:      Pointer to MC portal's I/O object
430  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
431  * @token:      Token of DPMCP object
432  * @irq_index:  The interrupt index to configure
433  * @status:     Returned interrupts status - one bit per cause:
434  *                      0 = no interrupt pending
435  *                      1 = interrupt pending
436  *
437  * Return:      '0' on Success; Error code otherwise.
438  */
439 int dpmcp_get_irq_status(struct fsl_mc_io *mc_io,
440                          u32 cmd_flags,
441                          u16 token,
442                          u8 irq_index,
443                          u32 *status)
444 {
445         struct mc_command cmd = { 0 };
446         struct dpmcp_cmd_get_irq_status *cmd_params;
447         struct dpmcp_rsp_get_irq_status *rsp_params;
448         int err;
449
450         /* prepare command */
451         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS,
452                                           cmd_flags, token);
453         cmd_params = (struct dpmcp_cmd_get_irq_status *)cmd.params;
454         cmd_params->status = cpu_to_le32(*status);
455         cmd_params->irq_index = irq_index;
456
457         /* send command to mc*/
458         err = mc_send_command(mc_io, &cmd);
459         if (err)
460                 return err;
461
462         /* retrieve response parameters */
463         rsp_params = (struct dpmcp_rsp_get_irq_status *)cmd.params;
464         *status = le32_to_cpu(rsp_params->status);
465
466         return 0;
467 }
468
469 /**
470  * dpmcp_get_attributes - Retrieve DPMCP attributes.
471  *
472  * @mc_io:      Pointer to MC portal's I/O object
473  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
474  * @token:      Token of DPMCP object
475  * @attr:       Returned object's attributes
476  *
477  * Return:      '0' on Success; Error code otherwise.
478  */
479 int dpmcp_get_attributes(struct fsl_mc_io *mc_io,
480                          u32 cmd_flags,
481                          u16 token,
482                          struct dpmcp_attr *attr)
483 {
484         struct mc_command cmd = { 0 };
485         struct dpmcp_rsp_get_attributes *rsp_params;
486         int err;
487
488         /* prepare command */
489         cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR,
490                                           cmd_flags, token);
491
492         /* send command to mc*/
493         err = mc_send_command(mc_io, &cmd);
494         if (err)
495                 return err;
496
497         /* retrieve response parameters */
498         rsp_params = (struct dpmcp_rsp_get_attributes *)cmd.params;
499         attr->id = le32_to_cpu(rsp_params->id);
500         attr->version.major = le16_to_cpu(rsp_params->version_major);
501         attr->version.minor = le16_to_cpu(rsp_params->version_minor);
502
503         return 0;
504 }