xref: /OK3568_Linux_fs/kernel/drivers/bus/fsl-mc/dprc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright 2013-2016 Freescale Semiconductor Inc.
4*4882a593Smuzhiyun  * Copyright 2020 NXP
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun #include <linux/kernel.h>
8*4882a593Smuzhiyun #include <linux/fsl/mc.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "fsl-mc-private.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /*
13*4882a593Smuzhiyun  * cache the DPRC version to reduce the number of commands
14*4882a593Smuzhiyun  * towards the mc firmware
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun static u16 dprc_major_ver;
17*4882a593Smuzhiyun static u16 dprc_minor_ver;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /**
20*4882a593Smuzhiyun  * dprc_open() - Open DPRC object for use
21*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
22*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
23*4882a593Smuzhiyun  * @container_id: Container ID to open
24*4882a593Smuzhiyun  * @token:	Returned token of DPRC object
25*4882a593Smuzhiyun  *
26*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * @warning	Required before any operation on the object.
29*4882a593Smuzhiyun  */
dprc_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int container_id,u16 * token)30*4882a593Smuzhiyun int dprc_open(struct fsl_mc_io *mc_io,
31*4882a593Smuzhiyun 	      u32 cmd_flags,
32*4882a593Smuzhiyun 	      int container_id,
33*4882a593Smuzhiyun 	      u16 *token)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
36*4882a593Smuzhiyun 	struct dprc_cmd_open *cmd_params;
37*4882a593Smuzhiyun 	int err;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	/* prepare command */
40*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,
41*4882a593Smuzhiyun 					  0);
42*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_open *)cmd.params;
43*4882a593Smuzhiyun 	cmd_params->container_id = cpu_to_le32(container_id);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	/* send command to mc*/
46*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
47*4882a593Smuzhiyun 	if (err)
48*4882a593Smuzhiyun 		return err;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	/* retrieve response parameters */
51*4882a593Smuzhiyun 	*token = mc_cmd_hdr_read_token(&cmd);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	return 0;
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_open);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /**
58*4882a593Smuzhiyun  * dprc_close() - Close the control session of the object
59*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
60*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
61*4882a593Smuzhiyun  * @token:	Token of DPRC object
62*4882a593Smuzhiyun  *
63*4882a593Smuzhiyun  * After this function is called, no further operations are
64*4882a593Smuzhiyun  * allowed on the object without opening a new control session.
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
67*4882a593Smuzhiyun  */
dprc_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)68*4882a593Smuzhiyun int dprc_close(struct fsl_mc_io *mc_io,
69*4882a593Smuzhiyun 	       u32 cmd_flags,
70*4882a593Smuzhiyun 	       u16 token)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	/* prepare command */
75*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,
76*4882a593Smuzhiyun 					  token);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	/* send command to mc*/
79*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_close);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /**
84*4882a593Smuzhiyun  * dprc_reset_container - Reset child container.
85*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
86*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
87*4882a593Smuzhiyun  * @token:	Token of DPRC object
88*4882a593Smuzhiyun  * @child_container_id:	ID of the container to reset
89*4882a593Smuzhiyun  * @options: 32 bit options:
90*4882a593Smuzhiyun  *   - 0 (no bits set) - all the objects inside the container are
91*4882a593Smuzhiyun  *     reset. The child containers are entered recursively and the
92*4882a593Smuzhiyun  *     objects reset. All the objects (including the child containers)
93*4882a593Smuzhiyun  *     are closed.
94*4882a593Smuzhiyun  *   - bit 0 set - all the objects inside the container are reset.
95*4882a593Smuzhiyun  *     However the child containers are not entered recursively.
96*4882a593Smuzhiyun  *     This option is supported for API versions >= 6.5
97*4882a593Smuzhiyun  * In case a software context crashes or becomes non-responsive, the parent
98*4882a593Smuzhiyun  * may wish to reset its resources container before the software context is
99*4882a593Smuzhiyun  * restarted.
100*4882a593Smuzhiyun  *
101*4882a593Smuzhiyun  * This routine informs all objects assigned to the child container that the
102*4882a593Smuzhiyun  * container is being reset, so they may perform any cleanup operations that are
103*4882a593Smuzhiyun  * needed. All objects handles that were owned by the child container shall be
104*4882a593Smuzhiyun  * closed.
105*4882a593Smuzhiyun  *
106*4882a593Smuzhiyun  * Note that such request may be submitted even if the child software context
107*4882a593Smuzhiyun  * has not crashed, but the resulting object cleanup operations will not be
108*4882a593Smuzhiyun  * aware of that.
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
111*4882a593Smuzhiyun  */
dprc_reset_container(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,int child_container_id,u32 options)112*4882a593Smuzhiyun int dprc_reset_container(struct fsl_mc_io *mc_io,
113*4882a593Smuzhiyun 			 u32 cmd_flags,
114*4882a593Smuzhiyun 			 u16 token,
115*4882a593Smuzhiyun 			 int child_container_id,
116*4882a593Smuzhiyun 			 u32 options)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
119*4882a593Smuzhiyun 	struct dprc_cmd_reset_container *cmd_params;
120*4882a593Smuzhiyun 	u32 cmdid = DPRC_CMDID_RESET_CONT;
121*4882a593Smuzhiyun 	int err;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	/*
124*4882a593Smuzhiyun 	 * If the DPRC object version was not yet cached, cache it now.
125*4882a593Smuzhiyun 	 * Otherwise use the already cached value.
126*4882a593Smuzhiyun 	 */
127*4882a593Smuzhiyun 	if (!dprc_major_ver && !dprc_minor_ver) {
128*4882a593Smuzhiyun 		err = dprc_get_api_version(mc_io, 0,
129*4882a593Smuzhiyun 				&dprc_major_ver,
130*4882a593Smuzhiyun 				&dprc_minor_ver);
131*4882a593Smuzhiyun 		if (err)
132*4882a593Smuzhiyun 			return err;
133*4882a593Smuzhiyun 	}
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	/*
136*4882a593Smuzhiyun 	 * MC API 6.5 introduced a new field in the command used to pass
137*4882a593Smuzhiyun 	 * some flags.
138*4882a593Smuzhiyun 	 * Bit 0 indicates that the child containers are not recursively reset.
139*4882a593Smuzhiyun 	 */
140*4882a593Smuzhiyun 	if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 5))
141*4882a593Smuzhiyun 		cmdid = DPRC_CMDID_RESET_CONT_V2;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	/* prepare command */
144*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(cmdid, cmd_flags, token);
145*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_reset_container *)cmd.params;
146*4882a593Smuzhiyun 	cmd_params->child_container_id = cpu_to_le32(child_container_id);
147*4882a593Smuzhiyun 	cmd_params->options = cpu_to_le32(options);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* send command to mc*/
150*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_reset_container);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /**
155*4882a593Smuzhiyun  * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt.
156*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
157*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
158*4882a593Smuzhiyun  * @token:	Token of DPRC object
159*4882a593Smuzhiyun  * @irq_index:	Identifies the interrupt index to configure
160*4882a593Smuzhiyun  * @irq_cfg:	IRQ configuration
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
163*4882a593Smuzhiyun  */
dprc_set_irq(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,struct dprc_irq_cfg * irq_cfg)164*4882a593Smuzhiyun int dprc_set_irq(struct fsl_mc_io *mc_io,
165*4882a593Smuzhiyun 		 u32 cmd_flags,
166*4882a593Smuzhiyun 		 u16 token,
167*4882a593Smuzhiyun 		 u8 irq_index,
168*4882a593Smuzhiyun 		 struct dprc_irq_cfg *irq_cfg)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
171*4882a593Smuzhiyun 	struct dprc_cmd_set_irq *cmd_params;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	/* prepare command */
174*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ,
175*4882a593Smuzhiyun 					  cmd_flags,
176*4882a593Smuzhiyun 					  token);
177*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_set_irq *)cmd.params;
178*4882a593Smuzhiyun 	cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
179*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
180*4882a593Smuzhiyun 	cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
181*4882a593Smuzhiyun 	cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	/* send command to mc*/
184*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /**
188*4882a593Smuzhiyun  * dprc_set_irq_enable() - Set overall interrupt state.
189*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
190*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
191*4882a593Smuzhiyun  * @token:	Token of DPRC object
192*4882a593Smuzhiyun  * @irq_index:	The interrupt index to configure
193*4882a593Smuzhiyun  * @en:		Interrupt state - enable = 1, disable = 0
194*4882a593Smuzhiyun  *
195*4882a593Smuzhiyun  * Allows GPP software to control when interrupts are generated.
196*4882a593Smuzhiyun  * Each interrupt can have up to 32 causes.  The enable/disable control's the
197*4882a593Smuzhiyun  * overall interrupt state. if the interrupt is disabled no causes will cause
198*4882a593Smuzhiyun  * an interrupt.
199*4882a593Smuzhiyun  *
200*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
201*4882a593Smuzhiyun  */
dprc_set_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 en)202*4882a593Smuzhiyun int dprc_set_irq_enable(struct fsl_mc_io *mc_io,
203*4882a593Smuzhiyun 			u32 cmd_flags,
204*4882a593Smuzhiyun 			u16 token,
205*4882a593Smuzhiyun 			u8 irq_index,
206*4882a593Smuzhiyun 			u8 en)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
209*4882a593Smuzhiyun 	struct dprc_cmd_set_irq_enable *cmd_params;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	/* prepare command */
212*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE,
213*4882a593Smuzhiyun 					  cmd_flags, token);
214*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_set_irq_enable *)cmd.params;
215*4882a593Smuzhiyun 	cmd_params->enable = en & DPRC_ENABLE;
216*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/* send command to mc*/
219*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun /**
223*4882a593Smuzhiyun  * dprc_set_irq_mask() - Set interrupt mask.
224*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
225*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
226*4882a593Smuzhiyun  * @token:	Token of DPRC object
227*4882a593Smuzhiyun  * @irq_index:	The interrupt index to configure
228*4882a593Smuzhiyun  * @mask:	event mask to trigger interrupt;
229*4882a593Smuzhiyun  *			each bit:
230*4882a593Smuzhiyun  *				0 = ignore event
231*4882a593Smuzhiyun  *				1 = consider event for asserting irq
232*4882a593Smuzhiyun  *
233*4882a593Smuzhiyun  * Every interrupt can have up to 32 causes and the interrupt model supports
234*4882a593Smuzhiyun  * masking/unmasking each cause independently
235*4882a593Smuzhiyun  *
236*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
237*4882a593Smuzhiyun  */
dprc_set_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 mask)238*4882a593Smuzhiyun int dprc_set_irq_mask(struct fsl_mc_io *mc_io,
239*4882a593Smuzhiyun 		      u32 cmd_flags,
240*4882a593Smuzhiyun 		      u16 token,
241*4882a593Smuzhiyun 		      u8 irq_index,
242*4882a593Smuzhiyun 		      u32 mask)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
245*4882a593Smuzhiyun 	struct dprc_cmd_set_irq_mask *cmd_params;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	/* prepare command */
248*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK,
249*4882a593Smuzhiyun 					  cmd_flags, token);
250*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_set_irq_mask *)cmd.params;
251*4882a593Smuzhiyun 	cmd_params->mask = cpu_to_le32(mask);
252*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	/* send command to mc*/
255*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun /**
259*4882a593Smuzhiyun  * dprc_get_irq_status() - Get the current status of any pending interrupts.
260*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
261*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
262*4882a593Smuzhiyun  * @token:	Token of DPRC object
263*4882a593Smuzhiyun  * @irq_index:	The interrupt index to configure
264*4882a593Smuzhiyun  * @status:	Returned interrupts status - one bit per cause:
265*4882a593Smuzhiyun  *			0 = no interrupt pending
266*4882a593Smuzhiyun  *			1 = interrupt pending
267*4882a593Smuzhiyun  *
268*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
269*4882a593Smuzhiyun  */
dprc_get_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * status)270*4882a593Smuzhiyun int dprc_get_irq_status(struct fsl_mc_io *mc_io,
271*4882a593Smuzhiyun 			u32 cmd_flags,
272*4882a593Smuzhiyun 			u16 token,
273*4882a593Smuzhiyun 			u8 irq_index,
274*4882a593Smuzhiyun 			u32 *status)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
277*4882a593Smuzhiyun 	struct dprc_cmd_get_irq_status *cmd_params;
278*4882a593Smuzhiyun 	struct dprc_rsp_get_irq_status *rsp_params;
279*4882a593Smuzhiyun 	int err;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	/* prepare command */
282*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
283*4882a593Smuzhiyun 					  cmd_flags, token);
284*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_get_irq_status *)cmd.params;
285*4882a593Smuzhiyun 	cmd_params->status = cpu_to_le32(*status);
286*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* send command to mc*/
289*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
290*4882a593Smuzhiyun 	if (err)
291*4882a593Smuzhiyun 		return err;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	/* retrieve response parameters */
294*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_irq_status *)cmd.params;
295*4882a593Smuzhiyun 	*status = le32_to_cpu(rsp_params->status);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	return 0;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun /**
301*4882a593Smuzhiyun  * dprc_clear_irq_status() - Clear a pending interrupt's status
302*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
303*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
304*4882a593Smuzhiyun  * @token:	Token of DPRC object
305*4882a593Smuzhiyun  * @irq_index:	The interrupt index to configure
306*4882a593Smuzhiyun  * @status:	bits to clear (W1C) - one bit per cause:
307*4882a593Smuzhiyun  *					0 = don't change
308*4882a593Smuzhiyun  *					1 = clear status bit
309*4882a593Smuzhiyun  *
310*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
311*4882a593Smuzhiyun  */
dprc_clear_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 status)312*4882a593Smuzhiyun int dprc_clear_irq_status(struct fsl_mc_io *mc_io,
313*4882a593Smuzhiyun 			  u32 cmd_flags,
314*4882a593Smuzhiyun 			  u16 token,
315*4882a593Smuzhiyun 			  u8 irq_index,
316*4882a593Smuzhiyun 			  u32 status)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
319*4882a593Smuzhiyun 	struct dprc_cmd_clear_irq_status *cmd_params;
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	/* prepare command */
322*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS,
323*4882a593Smuzhiyun 					  cmd_flags, token);
324*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_clear_irq_status *)cmd.params;
325*4882a593Smuzhiyun 	cmd_params->status = cpu_to_le32(status);
326*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	/* send command to mc*/
329*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /**
333*4882a593Smuzhiyun  * dprc_get_attributes() - Obtains container attributes
334*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
335*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
336*4882a593Smuzhiyun  * @token:	Token of DPRC object
337*4882a593Smuzhiyun  * @attributes	Returned container attributes
338*4882a593Smuzhiyun  *
339*4882a593Smuzhiyun  * Return:     '0' on Success; Error code otherwise.
340*4882a593Smuzhiyun  */
dprc_get_attributes(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,struct dprc_attributes * attr)341*4882a593Smuzhiyun int dprc_get_attributes(struct fsl_mc_io *mc_io,
342*4882a593Smuzhiyun 			u32 cmd_flags,
343*4882a593Smuzhiyun 			u16 token,
344*4882a593Smuzhiyun 			struct dprc_attributes *attr)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
347*4882a593Smuzhiyun 	struct dprc_rsp_get_attributes *rsp_params;
348*4882a593Smuzhiyun 	int err;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	/* prepare command */
351*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
352*4882a593Smuzhiyun 					  cmd_flags,
353*4882a593Smuzhiyun 					  token);
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	/* send command to mc*/
356*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
357*4882a593Smuzhiyun 	if (err)
358*4882a593Smuzhiyun 		return err;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	/* retrieve response parameters */
361*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_attributes *)cmd.params;
362*4882a593Smuzhiyun 	attr->container_id = le32_to_cpu(rsp_params->container_id);
363*4882a593Smuzhiyun 	attr->icid = le32_to_cpu(rsp_params->icid);
364*4882a593Smuzhiyun 	attr->options = le32_to_cpu(rsp_params->options);
365*4882a593Smuzhiyun 	attr->portal_id = le32_to_cpu(rsp_params->portal_id);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun /**
371*4882a593Smuzhiyun  * dprc_get_obj_count() - Obtains the number of objects in the DPRC
372*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
373*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
374*4882a593Smuzhiyun  * @token:	Token of DPRC object
375*4882a593Smuzhiyun  * @obj_count:	Number of objects assigned to the DPRC
376*4882a593Smuzhiyun  *
377*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
378*4882a593Smuzhiyun  */
dprc_get_obj_count(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,int * obj_count)379*4882a593Smuzhiyun int dprc_get_obj_count(struct fsl_mc_io *mc_io,
380*4882a593Smuzhiyun 		       u32 cmd_flags,
381*4882a593Smuzhiyun 		       u16 token,
382*4882a593Smuzhiyun 		       int *obj_count)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
385*4882a593Smuzhiyun 	struct dprc_rsp_get_obj_count *rsp_params;
386*4882a593Smuzhiyun 	int err;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	/* prepare command */
389*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
390*4882a593Smuzhiyun 					  cmd_flags, token);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	/* send command to mc*/
393*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
394*4882a593Smuzhiyun 	if (err)
395*4882a593Smuzhiyun 		return err;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	/* retrieve response parameters */
398*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_obj_count *)cmd.params;
399*4882a593Smuzhiyun 	*obj_count = le32_to_cpu(rsp_params->obj_count);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	return 0;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_get_obj_count);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun /**
406*4882a593Smuzhiyun  * dprc_get_obj() - Get general information on an object
407*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
408*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
409*4882a593Smuzhiyun  * @token:	Token of DPRC object
410*4882a593Smuzhiyun  * @obj_index:	Index of the object to be queried (< obj_count)
411*4882a593Smuzhiyun  * @obj_desc:	Returns the requested object descriptor
412*4882a593Smuzhiyun  *
413*4882a593Smuzhiyun  * The object descriptors are retrieved one by one by incrementing
414*4882a593Smuzhiyun  * obj_index up to (not including) the value of obj_count returned
415*4882a593Smuzhiyun  * from dprc_get_obj_count(). dprc_get_obj_count() must
416*4882a593Smuzhiyun  * be called prior to dprc_get_obj().
417*4882a593Smuzhiyun  *
418*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
419*4882a593Smuzhiyun  */
dprc_get_obj(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,int obj_index,struct fsl_mc_obj_desc * obj_desc)420*4882a593Smuzhiyun int dprc_get_obj(struct fsl_mc_io *mc_io,
421*4882a593Smuzhiyun 		 u32 cmd_flags,
422*4882a593Smuzhiyun 		 u16 token,
423*4882a593Smuzhiyun 		 int obj_index,
424*4882a593Smuzhiyun 		 struct fsl_mc_obj_desc *obj_desc)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
427*4882a593Smuzhiyun 	struct dprc_cmd_get_obj *cmd_params;
428*4882a593Smuzhiyun 	struct dprc_rsp_get_obj *rsp_params;
429*4882a593Smuzhiyun 	int err;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	/* prepare command */
432*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
433*4882a593Smuzhiyun 					  cmd_flags,
434*4882a593Smuzhiyun 					  token);
435*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_get_obj *)cmd.params;
436*4882a593Smuzhiyun 	cmd_params->obj_index = cpu_to_le32(obj_index);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	/* send command to mc*/
439*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
440*4882a593Smuzhiyun 	if (err)
441*4882a593Smuzhiyun 		return err;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	/* retrieve response parameters */
444*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_obj *)cmd.params;
445*4882a593Smuzhiyun 	obj_desc->id = le32_to_cpu(rsp_params->id);
446*4882a593Smuzhiyun 	obj_desc->vendor = le16_to_cpu(rsp_params->vendor);
447*4882a593Smuzhiyun 	obj_desc->irq_count = rsp_params->irq_count;
448*4882a593Smuzhiyun 	obj_desc->region_count = rsp_params->region_count;
449*4882a593Smuzhiyun 	obj_desc->state = le32_to_cpu(rsp_params->state);
450*4882a593Smuzhiyun 	obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
451*4882a593Smuzhiyun 	obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
452*4882a593Smuzhiyun 	obj_desc->flags = le16_to_cpu(rsp_params->flags);
453*4882a593Smuzhiyun 	strncpy(obj_desc->type, rsp_params->type, 16);
454*4882a593Smuzhiyun 	obj_desc->type[15] = '\0';
455*4882a593Smuzhiyun 	strncpy(obj_desc->label, rsp_params->label, 16);
456*4882a593Smuzhiyun 	obj_desc->label[15] = '\0';
457*4882a593Smuzhiyun 	return 0;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_get_obj);
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun /**
462*4882a593Smuzhiyun  * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt.
463*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
464*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
465*4882a593Smuzhiyun  * @token:	Token of DPRC object
466*4882a593Smuzhiyun  * @obj_type:	Type of the object to set its IRQ
467*4882a593Smuzhiyun  * @obj_id:	ID of the object to set its IRQ
468*4882a593Smuzhiyun  * @irq_index:	The interrupt index to configure
469*4882a593Smuzhiyun  * @irq_cfg:	IRQ configuration
470*4882a593Smuzhiyun  *
471*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
472*4882a593Smuzhiyun  */
dprc_set_obj_irq(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,char * obj_type,int obj_id,u8 irq_index,struct dprc_irq_cfg * irq_cfg)473*4882a593Smuzhiyun int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
474*4882a593Smuzhiyun 		     u32 cmd_flags,
475*4882a593Smuzhiyun 		     u16 token,
476*4882a593Smuzhiyun 		     char *obj_type,
477*4882a593Smuzhiyun 		     int obj_id,
478*4882a593Smuzhiyun 		     u8 irq_index,
479*4882a593Smuzhiyun 		     struct dprc_irq_cfg *irq_cfg)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
482*4882a593Smuzhiyun 	struct dprc_cmd_set_obj_irq *cmd_params;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	/* prepare command */
485*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ,
486*4882a593Smuzhiyun 					  cmd_flags,
487*4882a593Smuzhiyun 					  token);
488*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_set_obj_irq *)cmd.params;
489*4882a593Smuzhiyun 	cmd_params->irq_val = cpu_to_le32(irq_cfg->val);
490*4882a593Smuzhiyun 	cmd_params->irq_index = irq_index;
491*4882a593Smuzhiyun 	cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
492*4882a593Smuzhiyun 	cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
493*4882a593Smuzhiyun 	cmd_params->obj_id = cpu_to_le32(obj_id);
494*4882a593Smuzhiyun 	strncpy(cmd_params->obj_type, obj_type, 16);
495*4882a593Smuzhiyun 	cmd_params->obj_type[15] = '\0';
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	/* send command to mc*/
498*4882a593Smuzhiyun 	return mc_send_command(mc_io, &cmd);
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_set_obj_irq);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun /**
503*4882a593Smuzhiyun  * dprc_get_obj_region() - Get region information for a specified object.
504*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
505*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
506*4882a593Smuzhiyun  * @token:	Token of DPRC object
507*4882a593Smuzhiyun  * @obj_type;	Object type as returned in dprc_get_obj()
508*4882a593Smuzhiyun  * @obj_id:	Unique object instance as returned in dprc_get_obj()
509*4882a593Smuzhiyun  * @region_index: The specific region to query
510*4882a593Smuzhiyun  * @region_desc:  Returns the requested region descriptor
511*4882a593Smuzhiyun  *
512*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
513*4882a593Smuzhiyun  */
dprc_get_obj_region(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,char * obj_type,int obj_id,u8 region_index,struct dprc_region_desc * region_desc)514*4882a593Smuzhiyun int dprc_get_obj_region(struct fsl_mc_io *mc_io,
515*4882a593Smuzhiyun 			u32 cmd_flags,
516*4882a593Smuzhiyun 			u16 token,
517*4882a593Smuzhiyun 			char *obj_type,
518*4882a593Smuzhiyun 			int obj_id,
519*4882a593Smuzhiyun 			u8 region_index,
520*4882a593Smuzhiyun 			struct dprc_region_desc *region_desc)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
523*4882a593Smuzhiyun 	struct dprc_cmd_get_obj_region *cmd_params;
524*4882a593Smuzhiyun 	struct dprc_rsp_get_obj_region *rsp_params;
525*4882a593Smuzhiyun 	int err;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun     /*
528*4882a593Smuzhiyun      * If the DPRC object version was not yet cached, cache it now.
529*4882a593Smuzhiyun      * Otherwise use the already cached value.
530*4882a593Smuzhiyun      */
531*4882a593Smuzhiyun 	if (!dprc_major_ver && !dprc_minor_ver) {
532*4882a593Smuzhiyun 		err = dprc_get_api_version(mc_io, 0,
533*4882a593Smuzhiyun 				      &dprc_major_ver,
534*4882a593Smuzhiyun 				      &dprc_minor_ver);
535*4882a593Smuzhiyun 		if (err)
536*4882a593Smuzhiyun 			return err;
537*4882a593Smuzhiyun 	}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 6)) {
540*4882a593Smuzhiyun 		/*
541*4882a593Smuzhiyun 		 * MC API version 6.6 changed the size of the MC portals and software
542*4882a593Smuzhiyun 		 * portals to 64K (as implemented by hardware). If older API is in use the
543*4882a593Smuzhiyun 		 * size reported is less (64 bytes for mc portals and 4K for software
544*4882a593Smuzhiyun 		 * portals).
545*4882a593Smuzhiyun 		 */
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 		cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V3,
548*4882a593Smuzhiyun 						  cmd_flags, token);
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	} else if (dprc_major_ver == 6 && dprc_minor_ver >= 3) {
551*4882a593Smuzhiyun 		/*
552*4882a593Smuzhiyun 		 * MC API version 6.3 introduced a new field to the region
553*4882a593Smuzhiyun 		 * descriptor: base_address. If the older API is in use then the base
554*4882a593Smuzhiyun 		 * address is set to zero to indicate it needs to be obtained elsewhere
555*4882a593Smuzhiyun 		 * (typically the device tree).
556*4882a593Smuzhiyun 		 */
557*4882a593Smuzhiyun 		cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG_V2,
558*4882a593Smuzhiyun 						  cmd_flags, token);
559*4882a593Smuzhiyun 	} else {
560*4882a593Smuzhiyun 		cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
561*4882a593Smuzhiyun 						  cmd_flags, token);
562*4882a593Smuzhiyun 	}
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;
565*4882a593Smuzhiyun 	cmd_params->obj_id = cpu_to_le32(obj_id);
566*4882a593Smuzhiyun 	cmd_params->region_index = region_index;
567*4882a593Smuzhiyun 	strncpy(cmd_params->obj_type, obj_type, 16);
568*4882a593Smuzhiyun 	cmd_params->obj_type[15] = '\0';
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	/* send command to mc*/
571*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
572*4882a593Smuzhiyun 	if (err)
573*4882a593Smuzhiyun 		return err;
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	/* retrieve response parameters */
576*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params;
577*4882a593Smuzhiyun 	region_desc->base_offset = le64_to_cpu(rsp_params->base_offset);
578*4882a593Smuzhiyun 	region_desc->size = le32_to_cpu(rsp_params->size);
579*4882a593Smuzhiyun 	if (dprc_major_ver > 6 || (dprc_major_ver == 6 && dprc_minor_ver >= 3))
580*4882a593Smuzhiyun 		region_desc->base_address = le64_to_cpu(rsp_params->base_addr);
581*4882a593Smuzhiyun 	else
582*4882a593Smuzhiyun 		region_desc->base_address = 0;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	return 0;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(dprc_get_obj_region);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun /**
589*4882a593Smuzhiyun  * dprc_get_api_version - Get Data Path Resource Container API version
590*4882a593Smuzhiyun  * @mc_io:	Pointer to Mc portal's I/O object
591*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
592*4882a593Smuzhiyun  * @major_ver:	Major version of Data Path Resource Container API
593*4882a593Smuzhiyun  * @minor_ver:	Minor version of Data Path Resource Container API
594*4882a593Smuzhiyun  *
595*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
596*4882a593Smuzhiyun  */
dprc_get_api_version(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 * major_ver,u16 * minor_ver)597*4882a593Smuzhiyun int dprc_get_api_version(struct fsl_mc_io *mc_io,
598*4882a593Smuzhiyun 			 u32 cmd_flags,
599*4882a593Smuzhiyun 			 u16 *major_ver,
600*4882a593Smuzhiyun 			 u16 *minor_ver)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
603*4882a593Smuzhiyun 	int err;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	/* prepare command */
606*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
607*4882a593Smuzhiyun 					  cmd_flags, 0);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	/* send command to mc */
610*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
611*4882a593Smuzhiyun 	if (err)
612*4882a593Smuzhiyun 		return err;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	/* retrieve response parameters */
615*4882a593Smuzhiyun 	mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	return 0;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun /**
621*4882a593Smuzhiyun  * dprc_get_container_id - Get container ID associated with a given portal.
622*4882a593Smuzhiyun  * @mc_io:		Pointer to Mc portal's I/O object
623*4882a593Smuzhiyun  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
624*4882a593Smuzhiyun  * @container_id:	Requested container id
625*4882a593Smuzhiyun  *
626*4882a593Smuzhiyun  * Return:	'0' on Success; Error code otherwise.
627*4882a593Smuzhiyun  */
dprc_get_container_id(struct fsl_mc_io * mc_io,u32 cmd_flags,int * container_id)628*4882a593Smuzhiyun int dprc_get_container_id(struct fsl_mc_io *mc_io,
629*4882a593Smuzhiyun 			  u32 cmd_flags,
630*4882a593Smuzhiyun 			  int *container_id)
631*4882a593Smuzhiyun {
632*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
633*4882a593Smuzhiyun 	int err;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	/* prepare command */
636*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
637*4882a593Smuzhiyun 					  cmd_flags,
638*4882a593Smuzhiyun 					  0);
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	/* send command to mc*/
641*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
642*4882a593Smuzhiyun 	if (err)
643*4882a593Smuzhiyun 		return err;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	/* retrieve response parameters */
646*4882a593Smuzhiyun 	*container_id = (int)mc_cmd_read_object_id(&cmd);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	return 0;
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun /**
652*4882a593Smuzhiyun  * dprc_get_connection() - Get connected endpoint and link status if connection
653*4882a593Smuzhiyun  *			exists.
654*4882a593Smuzhiyun  * @mc_io:	Pointer to MC portal's I/O object
655*4882a593Smuzhiyun  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
656*4882a593Smuzhiyun  * @token:	Token of DPRC object
657*4882a593Smuzhiyun  * @endpoint1:	Endpoint 1 configuration parameters
658*4882a593Smuzhiyun  * @endpoint2:	Returned endpoint 2 configuration parameters
659*4882a593Smuzhiyun  * @state:	Returned link state:
660*4882a593Smuzhiyun  *		1 - link is up;
661*4882a593Smuzhiyun  *		0 - link is down;
662*4882a593Smuzhiyun  *		-1 - no connection (endpoint2 information is irrelevant)
663*4882a593Smuzhiyun  *
664*4882a593Smuzhiyun  * Return:     '0' on Success; -ENOTCONN if connection does not exist.
665*4882a593Smuzhiyun  */
dprc_get_connection(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,const struct dprc_endpoint * endpoint1,struct dprc_endpoint * endpoint2,int * state)666*4882a593Smuzhiyun int dprc_get_connection(struct fsl_mc_io *mc_io,
667*4882a593Smuzhiyun 			u32 cmd_flags,
668*4882a593Smuzhiyun 			u16 token,
669*4882a593Smuzhiyun 			const struct dprc_endpoint *endpoint1,
670*4882a593Smuzhiyun 			struct dprc_endpoint *endpoint2,
671*4882a593Smuzhiyun 			int *state)
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun 	struct dprc_cmd_get_connection *cmd_params;
674*4882a593Smuzhiyun 	struct dprc_rsp_get_connection *rsp_params;
675*4882a593Smuzhiyun 	struct fsl_mc_command cmd = { 0 };
676*4882a593Smuzhiyun 	int err, i;
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 	/* prepare command */
679*4882a593Smuzhiyun 	cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
680*4882a593Smuzhiyun 					  cmd_flags,
681*4882a593Smuzhiyun 					  token);
682*4882a593Smuzhiyun 	cmd_params = (struct dprc_cmd_get_connection *)cmd.params;
683*4882a593Smuzhiyun 	cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
684*4882a593Smuzhiyun 	cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);
685*4882a593Smuzhiyun 	for (i = 0; i < 16; i++)
686*4882a593Smuzhiyun 		cmd_params->ep1_type[i] = endpoint1->type[i];
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	/* send command to mc */
689*4882a593Smuzhiyun 	err = mc_send_command(mc_io, &cmd);
690*4882a593Smuzhiyun 	if (err)
691*4882a593Smuzhiyun 		return -ENOTCONN;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	/* retrieve response parameters */
694*4882a593Smuzhiyun 	rsp_params = (struct dprc_rsp_get_connection *)cmd.params;
695*4882a593Smuzhiyun 	endpoint2->id = le32_to_cpu(rsp_params->ep2_id);
696*4882a593Smuzhiyun 	endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id);
697*4882a593Smuzhiyun 	*state = le32_to_cpu(rsp_params->state);
698*4882a593Smuzhiyun 	for (i = 0; i < 16; i++)
699*4882a593Smuzhiyun 		endpoint2->type[i] = rsp_params->ep2_type[i];
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	return 0;
702*4882a593Smuzhiyun }
703