alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: clemens@ladisch.de, tiwai@suse.de
Cc: alsa-devel@alsa-project.org
Subject: [PATCH 09/10] ALSA: firewire-lib: pool ideal sequence of syt offset and data block
Date: Fri,  8 May 2020 13:36:34 +0900	[thread overview]
Message-ID: <20200508043635.349339-10-o-takashi@sakamocchi.jp> (raw)
In-Reply-To: <20200508043635.349339-1-o-takashi@sakamocchi.jp>

In current implementation, sequence of syt offset and the number of data
blocks is generated when packets for outgoing stream are going to be
queued.

This commit generates and pools the sequence independently of the
processing of outgoing packets for future extension.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/amdtp-stream.c | 68 +++++++++++++++++++++++++++++++++++
 sound/firewire/amdtp-stream.h |  6 ++++
 2 files changed, 74 insertions(+)

diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index f1c8611cfc70..a2af598e9b9a 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -905,14 +905,63 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
 	}
 }
 
+static void pool_ideal_seq_descs(struct amdtp_domain *d, unsigned int packets)
+{
+	struct amdtp_stream *irq_target = d->irq_target;
+	unsigned int seq_tail = d->seq_tail;
+	unsigned int seq_size = d->seq_size;
+	unsigned int min_avail;
+	struct amdtp_stream *s;
+
+	min_avail = d->seq_size;
+	list_for_each_entry(s, &d->streams, list) {
+		unsigned int seq_index;
+		unsigned int avail;
+
+		if (s->direction == AMDTP_IN_STREAM)
+			continue;
+
+		seq_index = s->ctx_data.rx.seq_index;
+		avail = d->seq_tail;
+		if (seq_index > avail)
+			avail += d->seq_size;
+		avail -= seq_index;
+
+		if (avail < min_avail)
+			min_avail = avail;
+	}
+
+	while (min_avail < packets) {
+		struct seq_desc *desc = d->seq_descs + seq_tail;
+
+		desc->syt_offset = calculate_syt_offset(&d->last_syt_offset,
+					&d->syt_offset_state, irq_target->sfc);
+		desc->data_blocks = calculate_data_blocks(&d->data_block_state,
+				!!(irq_target->flags & CIP_BLOCKING),
+				desc->syt_offset == CIP_SYT_NO_INFO,
+				irq_target->syt_interval, irq_target->sfc);
+
+		++seq_tail;
+		seq_tail %= seq_size;
+
+		++min_avail;
+	}
+
+	d->seq_tail = seq_tail;
+}
+
 static void irq_target_callback(struct fw_iso_context *context, u32 tstamp,
 				size_t header_length, void *header,
 				void *private_data)
 {
 	struct amdtp_stream *irq_target = private_data;
 	struct amdtp_domain *d = irq_target->domain;
+	unsigned int packets = header_length / sizeof(__be32);
 	struct amdtp_stream *s;
 
+	// Record enough entries with extra 3 cycles at least.
+	pool_ideal_seq_descs(d, packets + 3);
+
 	out_stream_callback(context, tstamp, header_length, header, irq_target);
 	if (amdtp_streaming_error(irq_target))
 		goto error;
@@ -1344,6 +1393,18 @@ static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle)
  */
 int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
 {
+	static const struct {
+		unsigned int data_block;
+		unsigned int syt_offset;
+	} *entry, initial_state[] = {
+		[CIP_SFC_32000]  = {  4, 3072 },
+		[CIP_SFC_48000]  = {  6, 1024 },
+		[CIP_SFC_96000]  = { 12, 1024 },
+		[CIP_SFC_192000] = { 24, 1024 },
+		[CIP_SFC_44100]  = {  0,   67 },
+		[CIP_SFC_88200]  = {  0,   67 },
+		[CIP_SFC_176400] = {  0,   67 },
+	};
 	unsigned int events_per_buffer = d->events_per_buffer;
 	unsigned int events_per_period = d->events_per_period;
 	unsigned int idle_irq_interval;
@@ -1378,6 +1439,11 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
 	d->seq_size = queue_size;
 	d->seq_tail = 0;
 
+	entry = &initial_state[s->sfc];
+	d->data_block_state = entry->data_block;
+	d->syt_offset_state = entry->syt_offset;
+	d->last_syt_offset = TICKS_PER_CYCLE;
+
 	if (ir_delay_cycle > 0) {
 		struct fw_card *fw_card = fw_parent_device(s->unit)->card;
 
@@ -1414,6 +1480,7 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
 		} else {
 			// IT context starts immediately.
 			cycle_match = -1;
+			s->ctx_data.rx.seq_index = 0;
 		}
 
 		if (s != d->irq_target) {
@@ -1427,6 +1494,7 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle)
 	s = d->irq_target;
 	s->ctx_data.rx.events_per_period = events_per_period;
 	s->ctx_data.rx.event_count = 0;
+	s->ctx_data.rx.seq_index = 0;
 
 	idle_irq_interval = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_period,
 					 amdtp_rate_table[d->irq_target->sfc]);
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 84a01efa5a85..11cff4cafd90 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -138,6 +138,8 @@ struct amdtp_stream {
 		struct {
 			// To calculate CIP data blocks and tstamp.
 			unsigned int transfer_delay;
+			unsigned int seq_index;
+
 			unsigned int data_block_state;
 			unsigned int last_syt_offset;
 			unsigned int syt_offset_state;
@@ -292,6 +294,10 @@ struct amdtp_domain {
 	struct seq_desc *seq_descs;
 	unsigned int seq_size;
 	unsigned int seq_tail;
+
+	unsigned int data_block_state;
+	unsigned int syt_offset_state;
+	unsigned int last_syt_offset;
 };
 
 int amdtp_domain_init(struct amdtp_domain *d);
-- 
2.25.1


  parent reply	other threads:[~2020-05-08  4:43 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-08  4:36 [PATCH 00/10] ALSA: firewire-lib: pool sequence of syt offset and data blocks in AMDTP domain structure Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 01/10] ALSA: firewire-lib: fix invalid assignment to union data for directional parameter Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 02/10] ALSA: firewire-lib: use macro for maximum value of second in 1394 OHCI isoc descriptor Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 03/10] ALSA: firewire-lib: add reference to domain structure from stream structure Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 04/10] ALSA: firewire-lib: code refactoring for parameters of packet queue and IRQ timing Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 05/10] ALSA: firewire-lib: code refactoring for syt computation Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 06/10] ALSA: firewire-lib: code refactoring for syt offset calculation Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 07/10] ALSA: firewire-lib: code refactoring for data block calculation Takashi Sakamoto
2020-05-08  4:36 ` [PATCH 08/10] ALSA: firewire-lib: add cache for packet sequence to AMDTP domain structure Takashi Sakamoto
2020-05-08  4:36 ` Takashi Sakamoto [this message]
2020-05-08  4:36 ` [PATCH 10/10] ALSA: firewire-lib: use sequence of syt offset and data block on pool in AMDTP domain Takashi Sakamoto
2020-05-08  7:48 ` [PATCH 00/10] ALSA: firewire-lib: pool sequence of syt offset and data blocks in AMDTP domain structure Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200508043635.349339-10-o-takashi@sakamocchi.jp \
    --to=o-takashi@sakamocchi.jp \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).