xref: /openbmc/linux/drivers/net/ethernet/freescale/dpaa2/dprtc.c (revision 0898782247ae533d1f4e47a06bc5d4870931b284)
10a006a2fSYangbo Lu // SPDX-License-Identifier: GPL-2.0
20a006a2fSYangbo Lu /*
30a006a2fSYangbo Lu  * Copyright 2013-2016 Freescale Semiconductor Inc.
40a006a2fSYangbo Lu  * Copyright 2016-2018 NXP
50a006a2fSYangbo Lu  */
60a006a2fSYangbo Lu 
70a006a2fSYangbo Lu #include <linux/fsl/mc.h>
80a006a2fSYangbo Lu 
90a006a2fSYangbo Lu #include "dprtc.h"
100a006a2fSYangbo Lu #include "dprtc-cmd.h"
110a006a2fSYangbo Lu 
120a006a2fSYangbo Lu /**
130a006a2fSYangbo Lu  * dprtc_open() - Open a control session for the specified object.
140a006a2fSYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
150a006a2fSYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
160a006a2fSYangbo Lu  * @dprtc_id:	DPRTC unique ID
170a006a2fSYangbo Lu  * @token:	Returned token; use in subsequent API calls
180a006a2fSYangbo Lu  *
190a006a2fSYangbo Lu  * This function can be used to open a control session for an
200a006a2fSYangbo Lu  * already created object; an object may have been declared in
210a006a2fSYangbo Lu  * the DPL or by calling the dprtc_create function.
220a006a2fSYangbo Lu  * This function returns a unique authentication token,
230a006a2fSYangbo Lu  * associated with the specific object ID and the specific MC
240a006a2fSYangbo Lu  * portal; this token must be used in all subsequent commands for
250a006a2fSYangbo Lu  * this specific object
260a006a2fSYangbo Lu  *
270a006a2fSYangbo Lu  * Return:	'0' on Success; Error code otherwise.
280a006a2fSYangbo Lu  */
dprtc_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int dprtc_id,u16 * token)290a006a2fSYangbo Lu int dprtc_open(struct fsl_mc_io *mc_io,
300a006a2fSYangbo Lu 	       u32 cmd_flags,
310a006a2fSYangbo Lu 	       int dprtc_id,
320a006a2fSYangbo Lu 	       u16 *token)
330a006a2fSYangbo Lu {
340a006a2fSYangbo Lu 	struct dprtc_cmd_open *cmd_params;
350a006a2fSYangbo Lu 	struct fsl_mc_command cmd = { 0 };
360a006a2fSYangbo Lu 	int err;
370a006a2fSYangbo Lu 
380a006a2fSYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_OPEN,
390a006a2fSYangbo Lu 					  cmd_flags,
400a006a2fSYangbo Lu 					  0);
410a006a2fSYangbo Lu 	cmd_params = (struct dprtc_cmd_open *)cmd.params;
420a006a2fSYangbo Lu 	cmd_params->dprtc_id = cpu_to_le32(dprtc_id);
430a006a2fSYangbo Lu 
440a006a2fSYangbo Lu 	err = mc_send_command(mc_io, &cmd);
450a006a2fSYangbo Lu 	if (err)
460a006a2fSYangbo Lu 		return err;
470a006a2fSYangbo Lu 
480a006a2fSYangbo Lu 	*token = mc_cmd_hdr_read_token(&cmd);
490a006a2fSYangbo Lu 
500a006a2fSYangbo Lu 	return 0;
510a006a2fSYangbo Lu }
520a006a2fSYangbo Lu 
530a006a2fSYangbo Lu /**
540a006a2fSYangbo Lu  * dprtc_close() - Close the control session of the object
550a006a2fSYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
560a006a2fSYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
570a006a2fSYangbo Lu  * @token:	Token of DPRTC object
580a006a2fSYangbo Lu  *
590a006a2fSYangbo Lu  * After this function is called, no further operations are
600a006a2fSYangbo Lu  * allowed on the object without opening a new control session.
610a006a2fSYangbo Lu  *
620a006a2fSYangbo Lu  * Return:	'0' on Success; Error code otherwise.
630a006a2fSYangbo Lu  */
dprtc_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)640a006a2fSYangbo Lu int dprtc_close(struct fsl_mc_io *mc_io,
650a006a2fSYangbo Lu 		u32 cmd_flags,
660a006a2fSYangbo Lu 		u16 token)
670a006a2fSYangbo Lu {
680a006a2fSYangbo Lu 	struct fsl_mc_command cmd = { 0 };
690a006a2fSYangbo Lu 
700a006a2fSYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CLOSE, cmd_flags,
710a006a2fSYangbo Lu 					  token);
720a006a2fSYangbo Lu 
730a006a2fSYangbo Lu 	return mc_send_command(mc_io, &cmd);
740a006a2fSYangbo Lu }
75*8893a843SYangbo Lu 
76*8893a843SYangbo Lu /**
77*8893a843SYangbo Lu  * dprtc_set_irq_enable() - Set overall interrupt state.
78*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
79*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
80*8893a843SYangbo Lu  * @token:	Token of DPRTC object
81*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
82*8893a843SYangbo Lu  * @en:		Interrupt state - enable = 1, disable = 0
83*8893a843SYangbo Lu  *
84*8893a843SYangbo Lu  * Allows GPP software to control when interrupts are generated.
85*8893a843SYangbo Lu  * Each interrupt can have up to 32 causes.  The enable/disable control's the
86*8893a843SYangbo Lu  * overall interrupt state. if the interrupt is disabled no causes will cause
87*8893a843SYangbo Lu  * an interrupt.
88*8893a843SYangbo Lu  *
89*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
90*8893a843SYangbo Lu  */
dprtc_set_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 en)91*8893a843SYangbo Lu int dprtc_set_irq_enable(struct fsl_mc_io *mc_io,
92*8893a843SYangbo Lu 			 u32 cmd_flags,
93*8893a843SYangbo Lu 			 u16 token,
94*8893a843SYangbo Lu 			 u8 irq_index,
95*8893a843SYangbo Lu 			 u8 en)
96*8893a843SYangbo Lu {
97*8893a843SYangbo Lu 	struct dprtc_cmd_set_irq_enable *cmd_params;
98*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
99*8893a843SYangbo Lu 
100*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_IRQ_ENABLE,
101*8893a843SYangbo Lu 					  cmd_flags,
102*8893a843SYangbo Lu 					  token);
103*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_set_irq_enable *)cmd.params;
104*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
105*8893a843SYangbo Lu 	cmd_params->en = en;
106*8893a843SYangbo Lu 
107*8893a843SYangbo Lu 	return mc_send_command(mc_io, &cmd);
108*8893a843SYangbo Lu }
109*8893a843SYangbo Lu 
110*8893a843SYangbo Lu /**
111*8893a843SYangbo Lu  * dprtc_get_irq_enable() - Get overall interrupt state
112*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
113*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
114*8893a843SYangbo Lu  * @token:	Token of DPRTC object
115*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
116*8893a843SYangbo Lu  * @en:		Returned interrupt state - enable = 1, disable = 0
117*8893a843SYangbo Lu  *
118*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
119*8893a843SYangbo Lu  */
dprtc_get_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 * en)120*8893a843SYangbo Lu int dprtc_get_irq_enable(struct fsl_mc_io *mc_io,
121*8893a843SYangbo Lu 			 u32 cmd_flags,
122*8893a843SYangbo Lu 			 u16 token,
123*8893a843SYangbo Lu 			 u8 irq_index,
124*8893a843SYangbo Lu 			 u8 *en)
125*8893a843SYangbo Lu {
126*8893a843SYangbo Lu 	struct dprtc_rsp_get_irq_enable *rsp_params;
127*8893a843SYangbo Lu 	struct dprtc_cmd_get_irq *cmd_params;
128*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
129*8893a843SYangbo Lu 	int err;
130*8893a843SYangbo Lu 
131*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_ENABLE,
132*8893a843SYangbo Lu 					  cmd_flags,
133*8893a843SYangbo Lu 					  token);
134*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_get_irq *)cmd.params;
135*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
136*8893a843SYangbo Lu 
137*8893a843SYangbo Lu 	err = mc_send_command(mc_io, &cmd);
138*8893a843SYangbo Lu 	if (err)
139*8893a843SYangbo Lu 		return err;
140*8893a843SYangbo Lu 
141*8893a843SYangbo Lu 	rsp_params = (struct dprtc_rsp_get_irq_enable *)cmd.params;
142*8893a843SYangbo Lu 	*en = rsp_params->en;
143*8893a843SYangbo Lu 
144*8893a843SYangbo Lu 	return 0;
145*8893a843SYangbo Lu }
146*8893a843SYangbo Lu 
147*8893a843SYangbo Lu /**
148*8893a843SYangbo Lu  * dprtc_set_irq_mask() - Set interrupt mask.
149*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
150*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
151*8893a843SYangbo Lu  * @token:	Token of DPRTC object
152*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
153*8893a843SYangbo Lu  * @mask:	Event mask to trigger interrupt;
154*8893a843SYangbo Lu  *		each bit:
155*8893a843SYangbo Lu  *			0 = ignore event
156*8893a843SYangbo Lu  *			1 = consider event for asserting IRQ
157*8893a843SYangbo Lu  *
158*8893a843SYangbo Lu  * Every interrupt can have up to 32 causes and the interrupt model supports
159*8893a843SYangbo Lu  * masking/unmasking each cause independently
160*8893a843SYangbo Lu  *
161*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
162*8893a843SYangbo Lu  */
dprtc_set_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 mask)163*8893a843SYangbo Lu int dprtc_set_irq_mask(struct fsl_mc_io *mc_io,
164*8893a843SYangbo Lu 		       u32 cmd_flags,
165*8893a843SYangbo Lu 		       u16 token,
166*8893a843SYangbo Lu 		       u8 irq_index,
167*8893a843SYangbo Lu 		       u32 mask)
168*8893a843SYangbo Lu {
169*8893a843SYangbo Lu 	struct dprtc_cmd_set_irq_mask *cmd_params;
170*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
171*8893a843SYangbo Lu 
172*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_IRQ_MASK,
173*8893a843SYangbo Lu 					  cmd_flags,
174*8893a843SYangbo Lu 					  token);
175*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_set_irq_mask *)cmd.params;
176*8893a843SYangbo Lu 	cmd_params->mask = cpu_to_le32(mask);
177*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
178*8893a843SYangbo Lu 
179*8893a843SYangbo Lu 	return mc_send_command(mc_io, &cmd);
180*8893a843SYangbo Lu }
181*8893a843SYangbo Lu 
182*8893a843SYangbo Lu /**
183*8893a843SYangbo Lu  * dprtc_get_irq_mask() - Get interrupt mask.
184*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
185*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
186*8893a843SYangbo Lu  * @token:	Token of DPRTC object
187*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
188*8893a843SYangbo Lu  * @mask:	Returned event mask to trigger interrupt
189*8893a843SYangbo Lu  *
190*8893a843SYangbo Lu  * Every interrupt can have up to 32 causes and the interrupt model supports
191*8893a843SYangbo Lu  * masking/unmasking each cause independently
192*8893a843SYangbo Lu  *
193*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
194*8893a843SYangbo Lu  */
dprtc_get_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * mask)195*8893a843SYangbo Lu int dprtc_get_irq_mask(struct fsl_mc_io *mc_io,
196*8893a843SYangbo Lu 		       u32 cmd_flags,
197*8893a843SYangbo Lu 		       u16 token,
198*8893a843SYangbo Lu 		       u8 irq_index,
199*8893a843SYangbo Lu 		       u32 *mask)
200*8893a843SYangbo Lu {
201*8893a843SYangbo Lu 	struct dprtc_rsp_get_irq_mask *rsp_params;
202*8893a843SYangbo Lu 	struct dprtc_cmd_get_irq *cmd_params;
203*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
204*8893a843SYangbo Lu 	int err;
205*8893a843SYangbo Lu 
206*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_MASK,
207*8893a843SYangbo Lu 					  cmd_flags,
208*8893a843SYangbo Lu 					  token);
209*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_get_irq *)cmd.params;
210*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
211*8893a843SYangbo Lu 
212*8893a843SYangbo Lu 	err = mc_send_command(mc_io, &cmd);
213*8893a843SYangbo Lu 	if (err)
214*8893a843SYangbo Lu 		return err;
215*8893a843SYangbo Lu 
216*8893a843SYangbo Lu 	rsp_params = (struct dprtc_rsp_get_irq_mask *)cmd.params;
217*8893a843SYangbo Lu 	*mask = le32_to_cpu(rsp_params->mask);
218*8893a843SYangbo Lu 
219*8893a843SYangbo Lu 	return 0;
220*8893a843SYangbo Lu }
221*8893a843SYangbo Lu 
222*8893a843SYangbo Lu /**
223*8893a843SYangbo Lu  * dprtc_get_irq_status() - Get the current status of any pending interrupts.
224*8893a843SYangbo Lu  *
225*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
226*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
227*8893a843SYangbo Lu  * @token:	Token of DPRTC object
228*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
229*8893a843SYangbo Lu  * @status:	Returned interrupts status - one bit per cause:
230*8893a843SYangbo Lu  *			0 = no interrupt pending
231*8893a843SYangbo Lu  *			1 = interrupt pending
232*8893a843SYangbo Lu  *
233*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
234*8893a843SYangbo Lu  */
dprtc_get_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * status)235*8893a843SYangbo Lu int dprtc_get_irq_status(struct fsl_mc_io *mc_io,
236*8893a843SYangbo Lu 			 u32 cmd_flags,
237*8893a843SYangbo Lu 			 u16 token,
238*8893a843SYangbo Lu 			 u8 irq_index,
239*8893a843SYangbo Lu 			 u32 *status)
240*8893a843SYangbo Lu {
241*8893a843SYangbo Lu 	struct dprtc_cmd_get_irq_status *cmd_params;
242*8893a843SYangbo Lu 	struct dprtc_rsp_get_irq_status *rsp_params;
243*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
244*8893a843SYangbo Lu 	int err;
245*8893a843SYangbo Lu 
246*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_IRQ_STATUS,
247*8893a843SYangbo Lu 					  cmd_flags,
248*8893a843SYangbo Lu 					  token);
249*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_get_irq_status *)cmd.params;
250*8893a843SYangbo Lu 	cmd_params->status = cpu_to_le32(*status);
251*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
252*8893a843SYangbo Lu 
253*8893a843SYangbo Lu 	err = mc_send_command(mc_io, &cmd);
254*8893a843SYangbo Lu 	if (err)
255*8893a843SYangbo Lu 		return err;
256*8893a843SYangbo Lu 
257*8893a843SYangbo Lu 	rsp_params = (struct dprtc_rsp_get_irq_status *)cmd.params;
258*8893a843SYangbo Lu 	*status = le32_to_cpu(rsp_params->status);
259*8893a843SYangbo Lu 
260*8893a843SYangbo Lu 	return 0;
261*8893a843SYangbo Lu }
262*8893a843SYangbo Lu 
263*8893a843SYangbo Lu /**
264*8893a843SYangbo Lu  * dprtc_clear_irq_status() - Clear a pending interrupt's status
265*8893a843SYangbo Lu  *
266*8893a843SYangbo Lu  * @mc_io:	Pointer to MC portal's I/O object
267*8893a843SYangbo Lu  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
268*8893a843SYangbo Lu  * @token:	Token of DPRTC object
269*8893a843SYangbo Lu  * @irq_index:	The interrupt index to configure
270*8893a843SYangbo Lu  * @status:	Bits to clear (W1C) - one bit per cause:
271*8893a843SYangbo Lu  *			0 = don't change
272*8893a843SYangbo Lu  *			1 = clear status bit
273*8893a843SYangbo Lu  *
274*8893a843SYangbo Lu  * Return:	'0' on Success; Error code otherwise.
275*8893a843SYangbo Lu  */
dprtc_clear_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 status)276*8893a843SYangbo Lu int dprtc_clear_irq_status(struct fsl_mc_io *mc_io,
277*8893a843SYangbo Lu 			   u32 cmd_flags,
278*8893a843SYangbo Lu 			   u16 token,
279*8893a843SYangbo Lu 			   u8 irq_index,
280*8893a843SYangbo Lu 			   u32 status)
281*8893a843SYangbo Lu {
282*8893a843SYangbo Lu 	struct dprtc_cmd_clear_irq_status *cmd_params;
283*8893a843SYangbo Lu 	struct fsl_mc_command cmd = { 0 };
284*8893a843SYangbo Lu 
285*8893a843SYangbo Lu 	cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CLEAR_IRQ_STATUS,
286*8893a843SYangbo Lu 					  cmd_flags,
287*8893a843SYangbo Lu 					  token);
288*8893a843SYangbo Lu 	cmd_params = (struct dprtc_cmd_clear_irq_status *)cmd.params;
289*8893a843SYangbo Lu 	cmd_params->irq_index = irq_index;
290*8893a843SYangbo Lu 	cmd_params->status = cpu_to_le32(status);
291*8893a843SYangbo Lu 
292*8893a843SYangbo Lu 	return mc_send_command(mc_io, &cmd);
293*8893a843SYangbo Lu }
294