• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
35 #include "dpmcp.h"
36 #include "dpmcp-cmd.h"
37 
38 /**
39  * dpmcp_open() - Open a control session for the specified object.
40  * @mc_io:	Pointer to MC portal's I/O object
41  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
42  * @dpmcp_id:	DPMCP unique ID
43  * @token:	Returned token; use in subsequent API calls
44  *
45  * This function can be used to open a control session for an
46  * already created object; an object may have been declared in
47  * the DPL or by calling the dpmcp_create function.
48  * This function returns a unique authentication token,
49  * associated with the specific object ID and the specific MC
50  * portal; this token must be used in all subsequent commands for
51  * this specific object
52  *
53  * Return:	'0' on Success; Error code otherwise.
54  */
dpmcp_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int dpmcp_id,u16 * token)55 int dpmcp_open(struct fsl_mc_io *mc_io,
56 	       u32 cmd_flags,
57 	       int dpmcp_id,
58 	       u16 *token)
59 {
60 	struct mc_command cmd = { 0 };
61 	struct dpmcp_cmd_open *cmd_params;
62 	int err;
63 
64 	/* prepare command */
65 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN,
66 					  cmd_flags, 0);
67 	cmd_params = (struct dpmcp_cmd_open *)cmd.params;
68 	cmd_params->dpmcp_id = cpu_to_le32(dpmcp_id);
69 
70 	/* send command to mc*/
71 	err = mc_send_command(mc_io, &cmd);
72 	if (err)
73 		return err;
74 
75 	/* retrieve response parameters */
76 	*token = mc_cmd_hdr_read_token(&cmd);
77 
78 	return err;
79 }
80 
81 /**
82  * dpmcp_close() - Close the control session of the object
83  * @mc_io:	Pointer to MC portal's I/O object
84  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
85  * @token:	Token of DPMCP object
86  *
87  * After this function is called, no further operations are
88  * allowed on the object without opening a new control session.
89  *
90  * Return:	'0' on Success; Error code otherwise.
91  */
dpmcp_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)92 int dpmcp_close(struct fsl_mc_io *mc_io,
93 		u32 cmd_flags,
94 		u16 token)
95 {
96 	struct mc_command cmd = { 0 };
97 
98 	/* prepare command */
99 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE,
100 					  cmd_flags, token);
101 
102 	/* send command to mc*/
103 	return mc_send_command(mc_io, &cmd);
104 }
105 
106 /**
107  * dpmcp_create() - Create the DPMCP object.
108  * @mc_io:	Pointer to MC portal's I/O object
109  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
110  * @cfg:	Configuration structure
111  * @token:	Returned token; use in subsequent API calls
112  *
113  * Create the DPMCP object, allocate required resources and
114  * perform required initialization.
115  *
116  * The object can be created either by declaring it in the
117  * DPL file, or by calling this function.
118  * This function returns a unique authentication token,
119  * associated with the specific object ID and the specific MC
120  * portal; this token must be used in all subsequent calls to
121  * this specific object. For objects that are created using the
122  * DPL file, call dpmcp_open function to get an authentication
123  * token first.
124  *
125  * Return:	'0' on Success; Error code otherwise.
126  */
dpmcp_create(struct fsl_mc_io * mc_io,u32 cmd_flags,const struct dpmcp_cfg * cfg,u16 * token)127 int dpmcp_create(struct fsl_mc_io *mc_io,
128 		 u32 cmd_flags,
129 		 const struct dpmcp_cfg *cfg,
130 		 u16 *token)
131 {
132 	struct mc_command cmd = { 0 };
133 	struct dpmcp_cmd_create *cmd_params;
134 
135 	int err;
136 
137 	/* prepare command */
138 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE,
139 					  cmd_flags, 0);
140 	cmd_params = (struct dpmcp_cmd_create *)cmd.params;
141 	cmd_params->portal_id = cpu_to_le32(cfg->portal_id);
142 
143 	/* send command to mc*/
144 	err = mc_send_command(mc_io, &cmd);
145 	if (err)
146 		return err;
147 
148 	/* retrieve response parameters */
149 	*token = mc_cmd_hdr_read_token(&cmd);
150 
151 	return 0;
152 }
153 
154 /**
155  * dpmcp_destroy() - Destroy the DPMCP object and release all its resources.
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 DPMCP object
159  *
160  * Return:	'0' on Success; error code otherwise.
161  */
dpmcp_destroy(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)162 int dpmcp_destroy(struct fsl_mc_io *mc_io,
163 		  u32 cmd_flags,
164 		  u16 token)
165 {
166 	struct mc_command cmd = { 0 };
167 
168 	/* prepare command */
169 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY,
170 					  cmd_flags, token);
171 
172 	/* send command to mc*/
173 	return mc_send_command(mc_io, &cmd);
174 }
175 
176 /**
177  * dpmcp_reset() - Reset the DPMCP, returns the object to initial state.
178  * @mc_io:	Pointer to MC portal's I/O object
179  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
180  * @token:	Token of DPMCP object
181  *
182  * Return:	'0' on Success; Error code otherwise.
183  */
dpmcp_reset(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)184 int dpmcp_reset(struct fsl_mc_io *mc_io,
185 		u32 cmd_flags,
186 		u16 token)
187 {
188 	struct mc_command cmd = { 0 };
189 
190 	/* prepare command */
191 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET,
192 					  cmd_flags, token);
193 
194 	/* send command to mc*/
195 	return mc_send_command(mc_io, &cmd);
196 }
197 
198 /**
199  * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt.
200  * @mc_io:	Pointer to MC portal's I/O object
201  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
202  * @token:	Token of DPMCP object
203  * @irq_index:	Identifies the interrupt index to configure
204  * @irq_cfg:	IRQ configuration
205  *
206  * Return:	'0' on Success; Error code otherwise.
207  */
dpmcp_set_irq(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,struct dpmcp_irq_cfg * irq_cfg)208 int dpmcp_set_irq(struct fsl_mc_io *mc_io,
209 		  u32 cmd_flags,
210 		  u16 token,
211 		  u8 irq_index,
212 		  struct dpmcp_irq_cfg	*irq_cfg)
213 {
214 	struct mc_command cmd = { 0 };
215 	struct dpmcp_cmd_set_irq *cmd_params;
216 
217 	/* prepare command */
218 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ,
219 					  cmd_flags, token);
220 	cmd_params = (struct dpmcp_cmd_set_irq *)cmd.params;
221 	cmd_params->irq_index = irq_index;
222 	cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
223 	cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
224 	cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
225 
226 	/* send command to mc*/
227 	return mc_send_command(mc_io, &cmd);
228 }
229 
230 /**
231  * dpmcp_get_irq() - Get IRQ information from the DPMCP.
232  * @mc_io:	Pointer to MC portal's I/O object
233  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
234  * @token:	Token of DPMCP object
235  * @irq_index:	The interrupt index to configure
236  * @type:	Interrupt type: 0 represents message interrupt
237  *		type (both irq_addr and irq_val are valid)
238  * @irq_cfg:	IRQ attributes
239  *
240  * Return:	'0' on Success; Error code otherwise.
241  */
dpmcp_get_irq(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,int * type,struct dpmcp_irq_cfg * irq_cfg)242 int dpmcp_get_irq(struct fsl_mc_io *mc_io,
243 		  u32 cmd_flags,
244 		  u16 token,
245 		  u8 irq_index,
246 		  int *type,
247 		  struct dpmcp_irq_cfg	*irq_cfg)
248 {
249 	struct mc_command cmd = { 0 };
250 	struct dpmcp_cmd_get_irq *cmd_params;
251 	struct dpmcp_rsp_get_irq *rsp_params;
252 	int err;
253 
254 	/* prepare command */
255 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ,
256 					  cmd_flags, token);
257 	cmd_params = (struct dpmcp_cmd_get_irq *)cmd.params;
258 	cmd_params->irq_index = irq_index;
259 
260 	/* send command to mc*/
261 	err = mc_send_command(mc_io, &cmd);
262 	if (err)
263 		return err;
264 
265 	/* retrieve response parameters */
266 	rsp_params = (struct dpmcp_rsp_get_irq *)cmd.params;
267 	irq_cfg->val = le32_to_cpu(rsp_params->irq_val);
268 	irq_cfg->paddr = le64_to_cpu(rsp_params->irq_paddr);
269 	irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num);
270 	*type = le32_to_cpu(rsp_params->type);
271 	return 0;
272 }
273 
274 /**
275  * dpmcp_set_irq_enable() - Set overall interrupt state.
276  * @mc_io:	Pointer to MC portal's I/O object
277  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
278  * @token:	Token of DPMCP object
279  * @irq_index:	The interrupt index to configure
280  * @en:	Interrupt state - enable = 1, disable = 0
281  *
282  * Allows GPP software to control when interrupts are generated.
283  * Each interrupt can have up to 32 causes.  The enable/disable control's the
284  * overall interrupt state. if the interrupt is disabled no causes will cause
285  * an interrupt.
286  *
287  * Return:	'0' on Success; Error code otherwise.
288  */
dpmcp_set_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 en)289 int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io,
290 			 u32 cmd_flags,
291 			 u16 token,
292 			 u8 irq_index,
293 			 u8 en)
294 {
295 	struct mc_command cmd = { 0 };
296 	struct dpmcp_cmd_set_irq_enable *cmd_params;
297 
298 	/* prepare command */
299 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE,
300 					  cmd_flags, token);
301 	cmd_params = (struct dpmcp_cmd_set_irq_enable *)cmd.params;
302 	cmd_params->enable = en & DPMCP_ENABLE;
303 	cmd_params->irq_index = irq_index;
304 
305 	/* send command to mc*/
306 	return mc_send_command(mc_io, &cmd);
307 }
308 
309 /**
310  * dpmcp_get_irq_enable() - Get overall interrupt state
311  * @mc_io:	Pointer to MC portal's I/O object
312  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
313  * @token:	Token of DPMCP object
314  * @irq_index:	The interrupt index to configure
315  * @en:		Returned interrupt state - enable = 1, disable = 0
316  *
317  * Return:	'0' on Success; Error code otherwise.
318  */
dpmcp_get_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 * en)319 int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io,
320 			 u32 cmd_flags,
321 			 u16 token,
322 			 u8 irq_index,
323 			 u8 *en)
324 {
325 	struct mc_command cmd = { 0 };
326 	struct dpmcp_cmd_get_irq_enable *cmd_params;
327 	struct dpmcp_rsp_get_irq_enable *rsp_params;
328 	int err;
329 
330 	/* prepare command */
331 	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE,
332 					  cmd_flags, token);
333 	cmd_params = (struct dpmcp_cmd_get_irq_enable *)cmd.params;
334 	cmd_params->irq_index = irq_index;
335 
336 	/* send command to mc*/
337 	err = mc_send_command(mc_io, &cmd);
338 	if (err)
339 		return err;
340 
341 	/* retrieve response parameters */
342 	rsp_params = (struct dpmcp_rsp_get_irq_enable *)cmd.params;
343 	*en = rsp_params->enabled & DPMCP_ENABLE;
344 	return 0;
345 }
346 
347 /**
348  * dpmcp_set_irq_mask() - Set interrupt mask.
349  * @mc_io:	Pointer to MC portal's I/O object
350  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
351  * @token:	Token of DPMCP object
352  * @irq_index:	The interrupt index to configure
353  * @mask:	Event mask to trigger interrupt;
354  *			each bit:
355  *				0 = ignore event
356  *				1 = consider event for asserting IRQ
357  *
358  * Every interrupt can have up to 32 causes and the interrupt model supports
359  * masking/unmasking each cause independently
360  *
361  * Return:	'0' on Success; Error code otherwise.
362  */
dpmcp_set_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 mask)363 int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
364 		       u32 cmd_flags,
365 		       u16 token,
366 		       u8 irq_index,
367 		       u32 mask)
368 {
369 	struct mc_command cmd = { 0 };
370 	struct dpmcp_cmd_set_irq_mask *cmd_params;
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  */
dpmcp_get_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * mask)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  */
dpmcp_get_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * status)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  */
dpmcp_get_attributes(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,struct dpmcp_attr * attr)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 }
505