Lines Matching refs:ivc
8 #include <asm/arch-tegra/ivc.h>
13 * IVC channel reset protocol.
71 static inline void tegra_ivc_invalidate_counter(struct tegra_ivc *ivc,
79 static inline void tegra_ivc_flush_counter(struct tegra_ivc *ivc,
87 static inline ulong tegra_ivc_frame_addr(struct tegra_ivc *ivc,
91 BUG_ON(frame >= ivc->nframes);
94 (ivc->frame_size * frame);
97 static inline void *tegra_ivc_frame_pointer(struct tegra_ivc *ivc,
101 return (void *)tegra_ivc_frame_addr(ivc, ch, frame);
104 static inline void tegra_ivc_invalidate_frame(struct tegra_ivc *ivc,
108 ulong base = tegra_ivc_frame_addr(ivc, h, frame);
109 invalidate_dcache_range(base, base + ivc->frame_size);
112 static inline void tegra_ivc_flush_frame(struct tegra_ivc *ivc,
116 ulong base = tegra_ivc_frame_addr(ivc, h, frame);
117 flush_dcache_range(base, base + ivc->frame_size);
120 static inline int tegra_ivc_channel_empty(struct tegra_ivc *ivc,
141 if (w_count - r_count > ivc->nframes)
147 static inline int tegra_ivc_channel_full(struct tegra_ivc *ivc,
155 ivc->nframes;
158 static inline void tegra_ivc_advance_rx(struct tegra_ivc *ivc)
160 ACCESS_ONCE(ivc->rx_channel->r_count) =
161 ACCESS_ONCE(ivc->rx_channel->r_count) + 1;
163 if (ivc->r_pos == ivc->nframes - 1)
164 ivc->r_pos = 0;
166 ivc->r_pos++;
169 static inline void tegra_ivc_advance_tx(struct tegra_ivc *ivc)
171 ACCESS_ONCE(ivc->tx_channel->w_count) =
172 ACCESS_ONCE(ivc->tx_channel->w_count) + 1;
174 if (ivc->w_pos == ivc->nframes - 1)
175 ivc->w_pos = 0;
177 ivc->w_pos++;
180 static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
192 if (ivc->tx_channel->state != ivc_state_established)
197 * an IVC channel by checking the old queue pointers first.
201 if (!tegra_ivc_channel_empty(ivc, ivc->rx_channel))
205 tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
206 return tegra_ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
209 static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
213 if (ivc->tx_channel->state != ivc_state_established)
216 if (!tegra_ivc_channel_full(ivc, ivc->tx_channel))
220 tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
221 return tegra_ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
224 static inline uint32_t tegra_ivc_channel_avail_count(struct tegra_ivc *ivc,
236 int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame)
238 int result = tegra_ivc_check_read(ivc);
248 tegra_ivc_invalidate_frame(ivc, ivc->rx_channel, ivc->r_pos);
249 *frame = tegra_ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
254 int tegra_ivc_read_advance(struct tegra_ivc *ivc)
264 result = tegra_ivc_check_read(ivc);
268 tegra_ivc_advance_rx(ivc);
270 tegra_ivc_flush_counter(ivc, ivc->rx_channel, offset);
278 tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
280 if (tegra_ivc_channel_avail_count(ivc, ivc->rx_channel) ==
281 ivc->nframes - 1)
282 ivc->notify(ivc);
287 int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame)
289 int result = tegra_ivc_check_write(ivc);
293 *frame = tegra_ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
298 int tegra_ivc_write_advance(struct tegra_ivc *ivc)
303 result = tegra_ivc_check_write(ivc);
307 tegra_ivc_flush_frame(ivc, ivc->tx_channel, ivc->w_pos);
314 tegra_ivc_advance_tx(ivc);
316 tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
324 tegra_ivc_invalidate_counter(ivc, ivc->tx_channel, offset);
326 if (tegra_ivc_channel_avail_count(ivc, ivc->tx_channel) == 1)
327 ivc->notify(ivc);
334 * IVC State Transition Table - see tegra_ivc_channel_notified()
351 int tegra_ivc_channel_notified(struct tegra_ivc *ivc)
358 tegra_ivc_invalidate_counter(ivc, ivc->rx_channel, offset);
359 peer_state = ACCESS_ONCE(ivc->rx_channel->state);
373 ivc->tx_channel->w_count = 0;
374 ivc->rx_channel->r_count = 0;
376 ivc->w_pos = 0;
377 ivc->r_pos = 0;
389 ivc->tx_channel->state = ivc_state_ack;
391 tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
396 ivc->notify(ivc);
397 } else if (ivc->tx_channel->state == ivc_state_sync &&
410 ivc->tx_channel->w_count = 0;
411 ivc->rx_channel->r_count = 0;
413 ivc->w_pos = 0;
414 ivc->r_pos = 0;
427 ivc->tx_channel->state = ivc_state_established;
429 tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
434 ivc->notify(ivc);
435 } else if (ivc->tx_channel->state == ivc_state_ack) {
449 ivc->tx_channel->state = ivc_state_established;
451 tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
456 ivc->notify(ivc);
462 * to the diagram in "IVC State Transition Table" above.
466 if (ivc->tx_channel->state != ivc_state_established)
472 void tegra_ivc_channel_reset(struct tegra_ivc *ivc)
476 ivc->tx_channel->state = ivc_state_sync;
478 tegra_ivc_flush_counter(ivc, ivc->tx_channel, offset);
479 ivc->notify(ivc);
530 int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base,
536 if (!ivc)
543 ivc->rx_channel = (struct tegra_ivc_channel_header *)rx_base;
544 ivc->tx_channel = (struct tegra_ivc_channel_header *)tx_base;
545 ivc->w_pos = 0;
546 ivc->r_pos = 0;
547 ivc->nframes = nframes;
548 ivc->frame_size = frame_size;
549 ivc->notify = notify;