{
struct amdtp_domain *d = s->domain;
- if (!d->replay.enable || !s->ctx_data.rx.replay_target)
+ if (!d->replay.enable || !s->ctx_data.rx.replay_target) {
pool_ideal_seq_descs(s, count);
- else
- pool_replayed_seq(s, count);
+ } else {
+ if (!d->replay.on_the_fly) {
+ pool_replayed_seq(s, count);
+ } else {
+ struct amdtp_stream *tx = s->ctx_data.rx.replay_target;
+ const unsigned int cache_size = tx->ctx_data.tx.cache.size;
+ const unsigned int cache_head = s->ctx_data.rx.cache_head;
+ unsigned int cached_cycles = calculate_cached_cycle_count(tx, cache_head);
+
+ if (cached_cycles > count && cached_cycles > cache_size / 2)
+ pool_replayed_seq(s, count);
+ else
+ pool_ideal_seq_descs(s, count);
+ }
+ }
}
static void update_pcm_pointers(struct amdtp_stream *s,
skip_rx_packets(context, tstamp, header_length, header, private_data);
process_ctxs_in_domain(d);
- if (d->replay.enable) {
+ if (d->replay.enable && !d->replay.on_the_fly) {
unsigned int rx_count = 0;
unsigned int rx_ready_count = 0;
struct amdtp_stream *rx;
* contexts.
* @replay_seq: whether to replay the sequence of packet in IR context for the sequence of packet in
* IT context.
+ * @replay_on_the_fly: transfer rx packets according to nominal frequency, then begin to replay
+ * according to arrival of events in tx packets.
*/
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq)
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+ bool replay_on_the_fly)
{
unsigned int events_per_buffer = d->events_per_buffer;
unsigned int events_per_period = d->events_per_period;
return err;
}
d->replay.enable = replay_seq;
+ d->replay.on_the_fly = replay_on_the_fly;
// Select an IT context as IRQ target.
list_for_each_entry(s, &d->streams, list) {
} processing_cycle;
struct {
- bool enable;
+ bool enable:1;
+ bool on_the_fly:1;
} replay;
};
int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
int channel, int speed);
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq);
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+ bool replay_on_the_fly);
void amdtp_domain_stop(struct amdtp_domain *d);
static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d,