1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28// MPHI videocore message driver
29
30#ifndef _VCHI_MESSAGE_H_
31#define _VCHI_MESSAGE_H_
32
33#include "interface/vchi/vchi_cfg_internal.h"
34#include "interface/vcos/vcos.h"
35#include "interface/vchi/vchi_common.h"
36
37
38typedef enum message_event_type {
39 MESSAGE_EVENT_NONE,
40 MESSAGE_EVENT_NOP,
41 MESSAGE_EVENT_MESSAGE,
42 MESSAGE_EVENT_SLOT_COMPLETE,
43 MESSAGE_EVENT_RX_BULK_PAUSED,
44 MESSAGE_EVENT_RX_BULK_COMPLETE,
45 MESSAGE_EVENT_TX_COMPLETE,
46 MESSAGE_EVENT_MSG_DISCARDED
47} MESSAGE_EVENT_TYPE_T;
48
49typedef enum vchi_msg_flags
50{
51 VCHI_MSG_FLAGS_NONE = 0x0,
52 VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1
53} VCHI_MSG_FLAGS_T;
54
55typedef enum message_tx_channel
56{
57 MESSAGE_TX_CHANNEL_MESSAGE = 0,
58 MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
59} MESSAGE_TX_CHANNEL_T;
60
61// Macros used for cycling through bulk channels
62#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
63#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
64
65typedef enum message_rx_channel
66{
67 MESSAGE_RX_CHANNEL_MESSAGE = 0,
68 MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
69} MESSAGE_RX_CHANNEL_T;
70
71// Message receive slot information
72typedef struct rx_msg_slot_info {
73
74 struct rx_msg_slot_info *next;
75 //struct slot_info *prev;
76#if !defined VCHI_COARSE_LOCKING
77 VCOS_SEMAPHORE_T sem;
78#endif
79
80 uint8_t *addr; // base address of slot
81 uint32_t len; // length of slot in bytes
82
83 uint32_t write_ptr; // hardware causes this to advance
84 uint32_t read_ptr; // this module does the reading
85 int active; // is this slot in the hardware dma fifo?
86 uint32_t msgs_parsed; // count how many messages are in this slot
87 uint32_t msgs_released; // how many messages have been released
88 void *state; // connection state information
89 uint8_t ref_count[VCHI_MAX_SERVICES_PER_CONNECTION]; // reference count for slots held by services
90} RX_MSG_SLOTINFO_T;
91
92// The message driver no longer needs to know about the fields of RX_BULK_SLOTINFO_T - sort this out.
93// In particular, it mustn't use addr and len - they're the client buffer, but the message
94// driver will be tasked with sending the aligned core section.
95typedef struct rx_bulk_slotinfo_t {
96 struct rx_bulk_slotinfo_t *next;
97
98 VCOS_SEMAPHORE_T *blocking;
99
100 // needed by DMA
101 void *addr;
102 uint32_t len;
103
104 // needed for the callback
105 void *service;
106 void *handle;
107 VCHI_FLAGS_T flags;
108} RX_BULK_SLOTINFO_T;
109
110
111/* ----------------------------------------------------------------------
112 * each connection driver will have a pool of the following struct.
113 *
114 * the pool will be managed by vchi_qman_*
115 * this means there will be multiple queues (single linked lists)
116 * a given struct message_info will be on exactly one of these queues
117 * at any one time
118 * -------------------------------------------------------------------- */
119typedef struct rx_message_info {
120
121 struct message_info *next;
122 //struct message_info *prev;
123
124 uint8_t *addr;
125 uint32_t len;
126 RX_MSG_SLOTINFO_T *slot; // points to whichever slot contains this message
127 uint32_t tx_timestamp;
128 uint32_t rx_timestamp;
129
130} RX_MESSAGE_INFO_T;
131
132typedef struct {
133 MESSAGE_EVENT_TYPE_T type;
134
135 struct {
136 // for messages
137 void *addr; // address of message
138 uint16_t slot_delta; // whether this message indicated slot delta
139 uint32_t len; // length of message
140 RX_MSG_SLOTINFO_T *slot; // slot this message is in
141 vcos_fourcc_t service; // service id this message is destined for
142 uint32_t tx_timestamp; // timestamp from the header
143 uint32_t rx_timestamp; // timestamp when we parsed it
144 } message;
145
146 // FIXME: cleanup slot reporting...
147 RX_MSG_SLOTINFO_T *rx_msg;
148 RX_BULK_SLOTINFO_T *rx_bulk;
149 void *tx_handle;
150 MESSAGE_TX_CHANNEL_T tx_channel;
151
152} MESSAGE_EVENT_T;
153
154
155// callbacks
156typedef void VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T( void *state );
157
158typedef struct {
159 VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T *event_callback;
160} VCHI_MESSAGE_DRIVER_OPEN_T;
161
162
163// handle to this instance of message driver (as returned by ->open)
164typedef struct opaque_mhandle_t *VCHI_MDRIVER_HANDLE_T;
165
166struct opaque_vchi_message_driver_t {
167 VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state );
168 int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle );
169 int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle );
170 int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, vcos_bool_t enable );
171 int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot ); // rx message
172 int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot ); // rx data (bulk)
173 int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle ); // tx (message & bulk)
174 void (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event ); // get the next event from message_driver
175 int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle );
176 int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, vcos_fourcc_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void
177 *address, uint32_t length_avail, uint32_t max_total_length, vcos_bool_t pad_to_fill, vcos_bool_t allow_partial );
178
179 int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count );
180 int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length );
181 void * (*allocate_buffer)( VCHI_MDRIVER_HANDLE_T *handle, uint32_t *length );
182 void (*free_buffer)( VCHI_MDRIVER_HANDLE_T *handle, void *address );
183 int (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
184 int (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
185
186 vcos_bool_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
187 uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
188 int (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
189 int (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel );
190 void (*form_bulk_aux)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, uint32_t chunk_size, const void **aux_data, int32_t *aux_len );
191 void (*debug)( VCHI_MDRIVER_HANDLE_T *handle );
192};
193
194
195#endif // _VCHI_MESSAGE_H_
196
197/****************************** End of file ***********************************/
198