1/* Copyright 2013-2015 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
37int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token)
38{
39	struct mc_command cmd = { 0 };
40	int err;
41
42	/* prepare command */
43	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN,
44					  MC_CMD_PRI_LOW, 0);
45	cmd.params[0] |= mc_enc(0, 32, dpmcp_id);
46
47	/* send command to mc*/
48	err = mc_send_command(mc_io, &cmd);
49	if (err)
50		return err;
51
52	/* retrieve response parameters */
53	*token = MC_CMD_HDR_READ_TOKEN(cmd.header);
54
55	return err;
56}
57
58int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token)
59{
60	struct mc_command cmd = { 0 };
61
62	/* prepare command */
63	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, MC_CMD_PRI_HIGH,
64					  token);
65
66	/* send command to mc*/
67	return mc_send_command(mc_io, &cmd);
68}
69
70int dpmcp_create(struct fsl_mc_io *mc_io,
71		 const struct dpmcp_cfg *cfg,
72		uint16_t *token)
73{
74	struct mc_command cmd = { 0 };
75	int err;
76
77	/* prepare command */
78	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE,
79					  MC_CMD_PRI_LOW, 0);
80	cmd.params[0] |= mc_enc(0, 32, cfg->portal_id);
81
82	/* send command to mc*/
83	err = mc_send_command(mc_io, &cmd);
84	if (err)
85		return err;
86
87	/* retrieve response parameters */
88	*token = MC_CMD_HDR_READ_TOKEN(cmd.header);
89
90	return 0;
91}
92
93int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token)
94{
95	struct mc_command cmd = { 0 };
96
97	/* prepare command */
98	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY,
99					  MC_CMD_PRI_LOW, token);
100
101	/* send command to mc*/
102	return mc_send_command(mc_io, &cmd);
103}
104
105int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token)
106{
107	struct mc_command cmd = { 0 };
108
109	/* prepare command */
110	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET,
111					  MC_CMD_PRI_LOW, token);
112
113	/* send command to mc*/
114	return mc_send_command(mc_io, &cmd);
115}
116
117int dpmcp_set_irq(struct fsl_mc_io *mc_io,
118		  uint16_t token,
119		 uint8_t irq_index,
120		 uint64_t irq_addr,
121		 uint32_t irq_val,
122		 int user_irq_id)
123{
124	struct mc_command cmd = { 0 };
125
126	/* prepare command */
127	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ,
128					  MC_CMD_PRI_LOW, token);
129	cmd.params[0] |= mc_enc(0, 8, irq_index);
130	cmd.params[0] |= mc_enc(32, 32, irq_val);
131	cmd.params[1] |= mc_enc(0, 64, irq_addr);
132	cmd.params[2] |= mc_enc(0, 32, user_irq_id);
133
134	/* send command to mc*/
135	return mc_send_command(mc_io, &cmd);
136}
137
138int dpmcp_get_irq(struct fsl_mc_io *mc_io,
139		  uint16_t token,
140		 uint8_t irq_index,
141		 int *type,
142		 uint64_t *irq_addr,
143		 uint32_t *irq_val,
144		 int *user_irq_id)
145{
146	struct mc_command cmd = { 0 };
147	int err;
148
149	/* prepare command */
150	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ,
151					  MC_CMD_PRI_LOW, token);
152	cmd.params[0] |= mc_enc(32, 8, irq_index);
153
154	/* send command to mc*/
155	err = mc_send_command(mc_io, &cmd);
156	if (err)
157		return err;
158
159	/* retrieve response parameters */
160	*irq_val = (uint32_t)mc_dec(cmd.params[0], 0, 32);
161	*irq_addr = (uint64_t)mc_dec(cmd.params[1], 0, 64);
162	*user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
163	*type = (int)mc_dec(cmd.params[2], 32, 32);
164	return 0;
165}
166
167int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io,
168			 uint16_t token,
169			uint8_t irq_index,
170			uint8_t en)
171{
172	struct mc_command cmd = { 0 };
173
174	/* prepare command */
175	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE,
176					  MC_CMD_PRI_LOW, token);
177	cmd.params[0] |= mc_enc(0, 8, en);
178	cmd.params[0] |= mc_enc(32, 8, irq_index);
179
180	/* send command to mc*/
181	return mc_send_command(mc_io, &cmd);
182}
183
184int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io,
185			 uint16_t token,
186			uint8_t irq_index,
187			uint8_t *en)
188{
189	struct mc_command cmd = { 0 };
190	int err;
191
192	/* prepare command */
193	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE,
194					  MC_CMD_PRI_LOW, token);
195	cmd.params[0] |= mc_enc(32, 8, irq_index);
196
197	/* send command to mc*/
198	err = mc_send_command(mc_io, &cmd);
199	if (err)
200		return err;
201
202	/* retrieve response parameters */
203	*en = (uint8_t)mc_dec(cmd.params[0], 0, 8);
204	return 0;
205}
206
207int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
208		       uint16_t token,
209		      uint8_t irq_index,
210		      uint32_t mask)
211{
212	struct mc_command cmd = { 0 };
213
214	/* prepare command */
215	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK,
216					  MC_CMD_PRI_LOW, token);
217	cmd.params[0] |= mc_enc(0, 32, mask);
218	cmd.params[0] |= mc_enc(32, 8, irq_index);
219
220	/* send command to mc*/
221	return mc_send_command(mc_io, &cmd);
222}
223
224int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io,
225		       uint16_t token,
226		      uint8_t irq_index,
227		      uint32_t *mask)
228{
229	struct mc_command cmd = { 0 };
230	int err;
231
232	/* prepare command */
233	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK,
234					  MC_CMD_PRI_LOW, token);
235	cmd.params[0] |= mc_enc(32, 8, irq_index);
236
237	/* send command to mc*/
238	err = mc_send_command(mc_io, &cmd);
239	if (err)
240		return err;
241
242	/* retrieve response parameters */
243	*mask = (uint32_t)mc_dec(cmd.params[0], 0, 32);
244	return 0;
245}
246
247int dpmcp_get_irq_status(struct fsl_mc_io *mc_io,
248			 uint16_t token,
249			uint8_t irq_index,
250			uint32_t *status)
251{
252	struct mc_command cmd = { 0 };
253	int err;
254
255	/* prepare command */
256	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS,
257					  MC_CMD_PRI_LOW, token);
258	cmd.params[0] |= mc_enc(32, 8, 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	*status = (uint32_t)mc_dec(cmd.params[0], 0, 32);
267	return 0;
268}
269
270int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io,
271			   uint16_t token,
272			  uint8_t irq_index,
273			  uint32_t status)
274{
275	struct mc_command cmd = { 0 };
276
277	/* prepare command */
278	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLEAR_IRQ_STATUS,
279					  MC_CMD_PRI_LOW, token);
280	cmd.params[0] |= mc_enc(0, 32, status);
281	cmd.params[0] |= mc_enc(32, 8, irq_index);
282
283	/* send command to mc*/
284	return mc_send_command(mc_io, &cmd);
285}
286
287int dpmcp_get_attributes(struct fsl_mc_io *mc_io,
288			 uint16_t token,
289			struct dpmcp_attr *attr)
290{
291	struct mc_command cmd = { 0 };
292	int err;
293
294	/* prepare command */
295	cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR,
296					  MC_CMD_PRI_LOW, token);
297
298	/* send command to mc*/
299	err = mc_send_command(mc_io, &cmd);
300	if (err)
301		return err;
302
303	/* retrieve response parameters */
304	attr->id = (int)mc_dec(cmd.params[0], 32, 32);
305	attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16);
306	attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16);
307	return 0;
308}
309