summaryrefslogtreecommitdiffstats
path: root/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h
blob: 5c7972f91ef648ab58c99e168309dce73abbe9f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/* Cypress West Bridge API header file (cyaslowlevel.h)
## ===========================
## Copyright (C) 2010  Cypress Semiconductor
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 2
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street
## Fifth Floor, Boston, MA  02110-1301, USA.
## ===========================
*/

#ifndef _INCLUDED_CYASLOWLEVEL_H_
#define _INCLUDED_CYASLOWLEVEL_H_

/*@@Low Level Communications

	Summary
	The low level communications module is responsible for
	communications between the West Bridge device and the P
	port processor.  Communications is organized as a series
	of requests and subsequent responses. For each request
	there is a one and only one response. Requests may go
	from the West Bridge device to the P port processor, or
	from the P Port processor to the West Bridge device.

	Description
	Requests are issued across what is called a context. A
	context is a single channel of communications from one
	processor to another processor. There can be only a single
	request outstanding on a context at a given time. Contexts
	are used to identify subsystems that can only process a
	single request at a time, but are independent of other
	contexts in the system. For instance, there is a context
	for communicating storage commands from the P port processor
	to the West Bridge device.  There is also a context for
	communicating USB commands from the P port processor to the
	West Bridge device.

	Requests and responses are identical with the exception of
	the type bit in the request/response header.  If the type
	bit is one, the packet is a request. If this bit is zero,
	the packet is a response. Also encoded within the header of
	the request/response is the code. The code is a command
	code for a request, or a response code for a response.  For
	a request, the code is a function of the context.  The code
	0 has one meaning for the storage context and a different
	meaning for the USB context.  The code is treated differently
	in the response. If the code in the response is less than 16,
	then the meaning of the response is global across all
	contexts. If the response is greater than or equal to 16,
	then the response is specific to the associated context.

	Requests and responses are transferred between processors
	through the mailbox registers.  It may take one or more cycles
	to transmit a complete request or response.  The context is
	encoded into each cycle of the transfer to insure the
	receiving processor can route the data to the appropriate
	context for processing. In this way, the traffic from multiple
	contexts can be multiplexed into a single data stream through
	the mailbox registers by the sending processor, and
	demultiplexed from the mailbox registers by the receiving
	processor.

	* Firmware Assumptions *
	The firmware assumes that mailbox contents will be consumed
	immediately. Therefore for multi-cycle packets, the data is
	sent in a tight polling loop from the firmware. This implies
	that the data must be read from the mailbox register on the P
	port side and processed immediately or performance of the
	firmware will suffer. In order to insure this is the case,
	the data from the mailboxes is read and stored immediately
	in a per context buffer. This occurs until the entire packet
	is received at which time the request packet is processed.
	Since the protocol is designed to allow for only one
	outstanding packet at a time, the firmware can never be in a
	position of waiting on the mailbox registers while the P port
	is processing a request.  Only after the response to the
	previous request is sent will another request be sent.
*/

#include "cyashal.h"
#include "cyasdevice.h"

#include "cyas_cplus_start.h"

/*
 * Constants
 */
#define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff)
#define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK	(0x0F00)
#define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8)
#define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000)
#define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000)
#define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000)

/*
 * These macros extract the data from a 16 bit value
 */
#define cy_as_mbox_get_code(c) \
	((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK))
#define cy_as_mbox_get_context(c) \
	((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \
		>> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))
#define cy_as_mbox_is_last(c) \
	((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK)
#define cy_as_mbox_is_request(c) \
	(((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0)
#define cy_as_mbox_is_response(c) \
	(((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0)

/*
 * These macros (not yet written) pack data into or extract data
 * from the m_box0 field of the request or response
 */
#define cy_as_ll_request_response__set_code(req, code) \
		((req)->box0 = \
		((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \
			(code & CY_AS_REQUEST_RESPONSE_CODE_MASK))

#define cy_as_ll_request_response__get_code(req) \
	cy_as_mbox_get_code((req)->box0)

#define cy_as_ll_request_response__set_context(req, context) \
		((req)->box0 |= ((context) << \
			CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT))

#define cy_as_ll_request_response__set_clear_storage_flag(req) \
		((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG)

#define cy_as_ll_request_response__get_context(req) \
	cy_as_mbox_get_context((req)->box0)

#define cy_as_ll_request_response__is_last(req) \
	cy_as_mbox_is_last((req)->box0)

#define CY_an_ll_request_response___set_last(req) \
		((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK)

#define cy_as_ll_request_response__is_request(req) \
	cy_as_mbox_is_request((req)->box0)

#define cy_as_ll_request_response__set_request(req) \
		((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK)

#define cy_as_ll_request_response__set_response(req) \
		((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK)

#define cy_as_ll_request_response__is_response(req) \
	cy_as_mbox_is_response((req)->box0)

#define cy_as_ll_request_response__get_word(req, offset) \
	((req)->data[(offset)])

#define cy_as_ll_request_response__set_word(req, offset, \
	value) ((req)->data[(offset)] = value)

typedef enum cy_as_remove_request_result_t {
	cy_as_remove_request_sucessful,
	cy_as_remove_request_in_transit,
	cy_as_remove_request_not_found
} cy_as_remove_request_result_t;

/* Summary
   Start the low level communications module

   Description
*/
cy_as_return_status_t
cy_as_ll_start(
		cy_as_device *dev_p
		);

cy_as_return_status_t
cy_as_ll_stop(
   cy_as_device *dev_p
   );


cy_as_ll_request_response *
cy_as_ll_create_request(
		cy_as_device *dev_p,
		uint16_t code,
		uint8_t context,
		/* Length of the request in 16 bit words */
		uint16_t length
		);

void
cy_as_ll_init_request(
	cy_as_ll_request_response *req_p,
	uint16_t code,
	uint16_t context,
	uint16_t length);

void
cy_as_ll_init_response(
	cy_as_ll_request_response *req_p,
	uint16_t length);

void
cy_as_ll_destroy_request(
		cy_as_device *dev_p,
		cy_as_ll_request_response *);

cy_as_ll_request_response *
cy_as_ll_create_response(
		cy_as_device *dev_p,
		/* Length of the request in 16 bit words */
		uint16_t length
		);

cy_as_remove_request_result_t
cy_as_ll_remove_request(
		cy_as_device *dev_p,
		cy_as_context *ctxt_p,
		cy_as_ll_request_response *req_p,
		cy_bool force
		);
void
cy_as_ll_remove_all_requests(cy_as_device *dev_p,
	cy_as_context *ctxt_p);

void
cy_as_ll_destroy_response(
	cy_as_device *dev_p,
	cy_as_ll_request_response *);

cy_as_return_status_t
cy_as_ll_send_request(
	/* The West Bridge device */
	cy_as_device *dev_p,
	/* The request to send */
	cy_as_ll_request_response *req,
	/* Storage for a reply, must be sure it is of sufficient size */
	cy_as_ll_request_response *resp,
	/* If true, this is a sync request */
	cy_bool	sync,
	/* Callback to call when reply is received */
	cy_as_response_callback cb
);

cy_as_return_status_t
cy_as_ll_send_request_wait_reply(
	/* The West Bridge device */
	cy_as_device *dev_p,
	/* The request to send */
	cy_as_ll_request_response *req,
	/* Storage for a reply, must be sure it is of sufficient size */
	cy_as_ll_request_response *resp
);

/* Summary
   This function registers a callback function to be called when a
   request arrives on a given context.

   Description

   Returns
   * CY_AS_ERROR_SUCCESS
*/
extern cy_as_return_status_t
cy_as_ll_register_request_callback(
		cy_as_device *dev_p,
		uint8_t context,
		cy_as_response_callback cb
		);

/* Summary
   This function packs a set of bytes given by the data_p pointer
   into a request, reply structure.
*/
extern void
cy_as_ll_request_response__pack(
	/* The destintation request or response */
	cy_as_ll_request_response *req,
	/* The offset of where to pack the data */
	uint32_t offset,
	/* The length of the data to pack in bytes */
	uint32_t length,
	/* The data to pack */
	void *data_p
	);

/* Summary
   This function unpacks a set of bytes from a request/reply
   structure into a segment of memory given by the data_p pointer.
*/
extern void
cy_as_ll_request_response__unpack(
	/* The source of the data to unpack */
	cy_as_ll_request_response *req,
	/* The offset of the data to unpack */
	uint32_t offset,
	/* The length of the data to unpack in bytes */
	uint32_t length,
	/* The destination of the unpack operation */
	void *data_p
	);

/* Summary
   This function sends a status response back to the West Bridge
   device in response to a previously send request
*/
extern cy_as_return_status_t
cy_as_ll_send_status_response(
	 /* The West Bridge device */
	cy_as_device *dev_p,
	/* The context to send the response on */
	uint8_t context,
	/* The success/failure code to send */
	uint16_t code,
	/* Flag to clear wait on storage context */
	uint8_t clear_storage);

/* Summary
   This function sends a response back to the West Bridge device.

   Description
   This function sends a response back to the West Bridge device.
   The response is sent on the context given by the 'context'
   variable.  The code for the response is given by the 'code'
   argument.  The data for the response is given by the data and
   length arguments.
*/
extern cy_as_return_status_t
cy_as_ll_send_data_response(
	/* The West Bridge device */
	cy_as_device *dev_p,
	/* The context to send the response on */
	uint8_t context,
	/* The response code to use */
	uint16_t code,
	/* The length of the data for the response */
	uint16_t length,
	/* The data for the response */
	void *data
);

/* Summary
   This function removes any requests of the given type
   from the given context.

   Description
   This function removes requests of a given type from the
   context given via the context number.
*/
extern cy_as_return_status_t
cy_as_ll_remove_ep_data_requests(
	/* The West Bridge device */
	cy_as_device *dev_p,
	cy_as_end_point_number_t ep
	);

#include "cyas_cplus_end.h"

#endif				  /* _INCLUDED_CYASLOWLEVEL_H_ */
OpenPOWER on IntegriCloud