1da607e19SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2d67c46b9STakashi Sakamoto /* 3d67c46b9STakashi Sakamoto * Audio and Music Data Transmission Protocol (IEC 61883-6) streams 4d67c46b9STakashi Sakamoto * with Common Isochronous Packet (IEC 61883-1) headers 5d67c46b9STakashi Sakamoto * 6d67c46b9STakashi Sakamoto * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 7d67c46b9STakashi Sakamoto */ 8d67c46b9STakashi Sakamoto 9d67c46b9STakashi Sakamoto #include <linux/device.h> 10d67c46b9STakashi Sakamoto #include <linux/err.h> 11d67c46b9STakashi Sakamoto #include <linux/firewire.h> 12acfedcbeSTakashi Sakamoto #include <linux/firewire-constants.h> 13d67c46b9STakashi Sakamoto #include <linux/module.h> 14d67c46b9STakashi Sakamoto #include <linux/slab.h> 15d67c46b9STakashi Sakamoto #include <sound/pcm.h> 16d67c46b9STakashi Sakamoto #include <sound/pcm_params.h> 17d67c46b9STakashi Sakamoto #include "amdtp-stream.h" 18d67c46b9STakashi Sakamoto 19d67c46b9STakashi Sakamoto #define TICKS_PER_CYCLE 3072 20d67c46b9STakashi Sakamoto #define CYCLES_PER_SECOND 8000 21d67c46b9STakashi Sakamoto #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) 22d67c46b9STakashi Sakamoto 233e106f4fSTakashi Sakamoto #define OHCI_SECOND_MODULUS 8 2410aa8e4aSTakashi Sakamoto 250c95c1d6STakashi Sakamoto /* Always support Linux tracing subsystem. */ 260c95c1d6STakashi Sakamoto #define CREATE_TRACE_POINTS 270c95c1d6STakashi Sakamoto #include "amdtp-stream-trace.h" 280c95c1d6STakashi Sakamoto 29d67c46b9STakashi Sakamoto #define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */ 30d67c46b9STakashi Sakamoto 31d67c46b9STakashi Sakamoto /* isochronous header parameters */ 32d67c46b9STakashi Sakamoto #define ISO_DATA_LENGTH_SHIFT 16 333b196c39STakashi Sakamoto #define TAG_NO_CIP_HEADER 0 34d67c46b9STakashi Sakamoto #define TAG_CIP 1 35d67c46b9STakashi Sakamoto 36*67d92ee7STakashi Sakamoto // Common Isochronous Packet (CIP) header parameters. Use two quadlets CIP header when supported. 37*67d92ee7STakashi Sakamoto #define CIP_HEADER_QUADLETS 2 38d67c46b9STakashi Sakamoto #define CIP_EOH_SHIFT 31 39d67c46b9STakashi Sakamoto #define CIP_EOH (1u << CIP_EOH_SHIFT) 40d67c46b9STakashi Sakamoto #define CIP_EOH_MASK 0x80000000 41d67c46b9STakashi Sakamoto #define CIP_SID_SHIFT 24 42d67c46b9STakashi Sakamoto #define CIP_SID_MASK 0x3f000000 43d67c46b9STakashi Sakamoto #define CIP_DBS_MASK 0x00ff0000 44d67c46b9STakashi Sakamoto #define CIP_DBS_SHIFT 16 459863874fSTakashi Sakamoto #define CIP_SPH_MASK 0x00000400 469863874fSTakashi Sakamoto #define CIP_SPH_SHIFT 10 47d67c46b9STakashi Sakamoto #define CIP_DBC_MASK 0x000000ff 48d67c46b9STakashi Sakamoto #define CIP_FMT_SHIFT 24 49d67c46b9STakashi Sakamoto #define CIP_FMT_MASK 0x3f000000 50d67c46b9STakashi Sakamoto #define CIP_FDF_MASK 0x00ff0000 51d67c46b9STakashi Sakamoto #define CIP_FDF_SHIFT 16 52d67c46b9STakashi Sakamoto #define CIP_SYT_MASK 0x0000ffff 53d67c46b9STakashi Sakamoto #define CIP_SYT_NO_INFO 0xffff 54d67c46b9STakashi Sakamoto 55*67d92ee7STakashi Sakamoto #define CIP_HEADER_SIZE (sizeof(__be32) * CIP_HEADER_QUADLETS) 56*67d92ee7STakashi Sakamoto 5751c29fd2STakashi Sakamoto /* Audio and Music transfer protocol specific parameters */ 58d67c46b9STakashi Sakamoto #define CIP_FMT_AM 0x10 59d67c46b9STakashi Sakamoto #define AMDTP_FDF_NO_DATA 0xff 60d67c46b9STakashi Sakamoto 61f11453c7STakashi Sakamoto // For iso header and tstamp. 62*67d92ee7STakashi Sakamoto #define IR_CTX_HEADER_DEFAULT_QUADLETS 2 63*67d92ee7STakashi Sakamoto // Add nothing. 64*67d92ee7STakashi Sakamoto #define IR_CTX_HEADER_SIZE_NO_CIP (sizeof(__be32) * IR_CTX_HEADER_DEFAULT_QUADLETS) 65*67d92ee7STakashi Sakamoto // Add two quadlets CIP header. 66*67d92ee7STakashi Sakamoto #define IR_CTX_HEADER_SIZE_CIP (IR_CTX_HEADER_SIZE_NO_CIP + CIP_HEADER_SIZE) 67cc4f8e91STakashi Sakamoto #define HEADER_TSTAMP_MASK 0x0000ffff 68d67c46b9STakashi Sakamoto 69*67d92ee7STakashi Sakamoto #define IT_PKT_HEADER_SIZE_CIP CIP_HEADER_SIZE 70b18f0cfaSTakashi Sakamoto #define IT_PKT_HEADER_SIZE_NO_CIP 0 // Nothing. 71b18f0cfaSTakashi Sakamoto 726a3ce97dSTakashi Sakamoto // The initial firmware of OXFW970 can postpone transmission of packet during finishing 736a3ce97dSTakashi Sakamoto // asynchronous transaction. This module accepts 5 cycles to skip as maximum to avoid buffer 746a3ce97dSTakashi Sakamoto // overrun. Actual device can skip more, then this module stops the packet streaming. 756a3ce97dSTakashi Sakamoto #define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5 766a3ce97dSTakashi Sakamoto 772b3d2987STakashi Iwai static void pcm_period_work(struct work_struct *work); 78d67c46b9STakashi Sakamoto 79d67c46b9STakashi Sakamoto /** 80d67c46b9STakashi Sakamoto * amdtp_stream_init - initialize an AMDTP stream structure 81d67c46b9STakashi Sakamoto * @s: the AMDTP stream to initialize 82d67c46b9STakashi Sakamoto * @unit: the target of the stream 83d67c46b9STakashi Sakamoto * @dir: the direction of stream 84ffe66bbeSTakashi Sakamoto * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants. 855955815eSTakashi Sakamoto * @fmt: the value of fmt field in CIP header 869a738ad1STakashi Sakamoto * @process_ctx_payloads: callback handler to process payloads of isoc context 87df075feeSTakashi Sakamoto * @protocol_size: the size to allocate newly for protocol 88d67c46b9STakashi Sakamoto */ 89d67c46b9STakashi Sakamoto int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 90ffe66bbeSTakashi Sakamoto enum amdtp_stream_direction dir, unsigned int flags, 91df075feeSTakashi Sakamoto unsigned int fmt, 929a738ad1STakashi Sakamoto amdtp_stream_process_ctx_payloads_t process_ctx_payloads, 93df075feeSTakashi Sakamoto unsigned int protocol_size) 94d67c46b9STakashi Sakamoto { 959a738ad1STakashi Sakamoto if (process_ctx_payloads == NULL) 96df075feeSTakashi Sakamoto return -EINVAL; 97df075feeSTakashi Sakamoto 98df075feeSTakashi Sakamoto s->protocol = kzalloc(protocol_size, GFP_KERNEL); 99df075feeSTakashi Sakamoto if (!s->protocol) 100df075feeSTakashi Sakamoto return -ENOMEM; 101df075feeSTakashi Sakamoto 102d67c46b9STakashi Sakamoto s->unit = unit; 103d67c46b9STakashi Sakamoto s->direction = dir; 104d67c46b9STakashi Sakamoto s->flags = flags; 105d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 106d67c46b9STakashi Sakamoto mutex_init(&s->mutex); 1072b3d2987STakashi Iwai INIT_WORK(&s->period_work, pcm_period_work); 108d67c46b9STakashi Sakamoto s->packet_index = 0; 109d67c46b9STakashi Sakamoto 110d67c46b9STakashi Sakamoto init_waitqueue_head(&s->callback_wait); 111d67c46b9STakashi Sakamoto s->callbacked = false; 112d67c46b9STakashi Sakamoto 1135955815eSTakashi Sakamoto s->fmt = fmt; 1149a738ad1STakashi Sakamoto s->process_ctx_payloads = process_ctx_payloads; 115d67c46b9STakashi Sakamoto 1163baf3053STakashi Sakamoto if (dir == AMDTP_OUT_STREAM) 1173baf3053STakashi Sakamoto s->ctx_data.rx.syt_override = -1; 1183baf3053STakashi Sakamoto 119d67c46b9STakashi Sakamoto return 0; 120d67c46b9STakashi Sakamoto } 121d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_init); 122d67c46b9STakashi Sakamoto 123d67c46b9STakashi Sakamoto /** 124d67c46b9STakashi Sakamoto * amdtp_stream_destroy - free stream resources 125d67c46b9STakashi Sakamoto * @s: the AMDTP stream to destroy 126d67c46b9STakashi Sakamoto */ 127d67c46b9STakashi Sakamoto void amdtp_stream_destroy(struct amdtp_stream *s) 128d67c46b9STakashi Sakamoto { 12944c376b9STakashi Sakamoto /* Not initialized. */ 13044c376b9STakashi Sakamoto if (s->protocol == NULL) 13144c376b9STakashi Sakamoto return; 13244c376b9STakashi Sakamoto 133d67c46b9STakashi Sakamoto WARN_ON(amdtp_stream_running(s)); 134df075feeSTakashi Sakamoto kfree(s->protocol); 135d67c46b9STakashi Sakamoto mutex_destroy(&s->mutex); 136d67c46b9STakashi Sakamoto } 137d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_destroy); 138d67c46b9STakashi Sakamoto 139d67c46b9STakashi Sakamoto const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT] = { 140d67c46b9STakashi Sakamoto [CIP_SFC_32000] = 8, 141d67c46b9STakashi Sakamoto [CIP_SFC_44100] = 8, 142d67c46b9STakashi Sakamoto [CIP_SFC_48000] = 8, 143d67c46b9STakashi Sakamoto [CIP_SFC_88200] = 16, 144d67c46b9STakashi Sakamoto [CIP_SFC_96000] = 16, 145d67c46b9STakashi Sakamoto [CIP_SFC_176400] = 32, 146d67c46b9STakashi Sakamoto [CIP_SFC_192000] = 32, 147d67c46b9STakashi Sakamoto }; 148d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_syt_intervals); 149d67c46b9STakashi Sakamoto 150d67c46b9STakashi Sakamoto const unsigned int amdtp_rate_table[CIP_SFC_COUNT] = { 151d67c46b9STakashi Sakamoto [CIP_SFC_32000] = 32000, 152d67c46b9STakashi Sakamoto [CIP_SFC_44100] = 44100, 153d67c46b9STakashi Sakamoto [CIP_SFC_48000] = 48000, 154d67c46b9STakashi Sakamoto [CIP_SFC_88200] = 88200, 155d67c46b9STakashi Sakamoto [CIP_SFC_96000] = 96000, 156d67c46b9STakashi Sakamoto [CIP_SFC_176400] = 176400, 157d67c46b9STakashi Sakamoto [CIP_SFC_192000] = 192000, 158d67c46b9STakashi Sakamoto }; 159d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_rate_table); 160d67c46b9STakashi Sakamoto 16159502295STakashi Sakamoto static int apply_constraint_to_size(struct snd_pcm_hw_params *params, 16259502295STakashi Sakamoto struct snd_pcm_hw_rule *rule) 16359502295STakashi Sakamoto { 16459502295STakashi Sakamoto struct snd_interval *s = hw_param_interval(params, rule->var); 16559502295STakashi Sakamoto const struct snd_interval *r = 16659502295STakashi Sakamoto hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 167826b5de9STakashi Sakamoto struct snd_interval t = {0}; 168826b5de9STakashi Sakamoto unsigned int step = 0; 16959502295STakashi Sakamoto int i; 17059502295STakashi Sakamoto 17159502295STakashi Sakamoto for (i = 0; i < CIP_SFC_COUNT; ++i) { 172826b5de9STakashi Sakamoto if (snd_interval_test(r, amdtp_rate_table[i])) 173826b5de9STakashi Sakamoto step = max(step, amdtp_syt_intervals[i]); 17459502295STakashi Sakamoto } 17559502295STakashi Sakamoto 176826b5de9STakashi Sakamoto t.min = roundup(s->min, step); 177826b5de9STakashi Sakamoto t.max = rounddown(s->max, step); 178826b5de9STakashi Sakamoto t.integer = 1; 17959502295STakashi Sakamoto 18059502295STakashi Sakamoto return snd_interval_refine(s, &t); 18159502295STakashi Sakamoto } 18259502295STakashi Sakamoto 183d67c46b9STakashi Sakamoto /** 184d67c46b9STakashi Sakamoto * amdtp_stream_add_pcm_hw_constraints - add hw constraints for PCM substream 185d67c46b9STakashi Sakamoto * @s: the AMDTP stream, which must be initialized. 186d67c46b9STakashi Sakamoto * @runtime: the PCM substream runtime 187d67c46b9STakashi Sakamoto */ 188d67c46b9STakashi Sakamoto int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, 189d67c46b9STakashi Sakamoto struct snd_pcm_runtime *runtime) 190d67c46b9STakashi Sakamoto { 19155799c5aSTakashi Sakamoto struct snd_pcm_hardware *hw = &runtime->hw; 19299921ec6STakashi Sakamoto unsigned int ctx_header_size; 19399921ec6STakashi Sakamoto unsigned int maximum_usec_per_period; 194d67c46b9STakashi Sakamoto int err; 195d67c46b9STakashi Sakamoto 19655799c5aSTakashi Sakamoto hw->info = SNDRV_PCM_INFO_BATCH | 19755799c5aSTakashi Sakamoto SNDRV_PCM_INFO_BLOCK_TRANSFER | 19855799c5aSTakashi Sakamoto SNDRV_PCM_INFO_INTERLEAVED | 19955799c5aSTakashi Sakamoto SNDRV_PCM_INFO_JOINT_DUPLEX | 20055799c5aSTakashi Sakamoto SNDRV_PCM_INFO_MMAP | 20155799c5aSTakashi Sakamoto SNDRV_PCM_INFO_MMAP_VALID; 20255799c5aSTakashi Sakamoto 20355799c5aSTakashi Sakamoto /* SNDRV_PCM_INFO_BATCH */ 20455799c5aSTakashi Sakamoto hw->periods_min = 2; 20555799c5aSTakashi Sakamoto hw->periods_max = UINT_MAX; 20655799c5aSTakashi Sakamoto 20755799c5aSTakashi Sakamoto /* bytes for a frame */ 20855799c5aSTakashi Sakamoto hw->period_bytes_min = 4 * hw->channels_max; 20955799c5aSTakashi Sakamoto 21055799c5aSTakashi Sakamoto /* Just to prevent from allocating much pages. */ 21155799c5aSTakashi Sakamoto hw->period_bytes_max = hw->period_bytes_min * 2048; 21255799c5aSTakashi Sakamoto hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 21355799c5aSTakashi Sakamoto 21499921ec6STakashi Sakamoto // Linux driver for 1394 OHCI controller voluntarily flushes isoc 21599921ec6STakashi Sakamoto // context when total size of accumulated context header reaches 2162b3d2987STakashi Iwai // PAGE_SIZE. This kicks work for the isoc context and brings 21799921ec6STakashi Sakamoto // callback in the middle of scheduled interrupts. 21899921ec6STakashi Sakamoto // Although AMDTP streams in the same domain use the same events per 21999921ec6STakashi Sakamoto // IRQ, use the largest size of context header between IT/IR contexts. 22099921ec6STakashi Sakamoto // Here, use the value of context header in IR context is for both 22199921ec6STakashi Sakamoto // contexts. 22299921ec6STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 22399921ec6STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_CIP; 22499921ec6STakashi Sakamoto else 22599921ec6STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP; 22699921ec6STakashi Sakamoto maximum_usec_per_period = USEC_PER_SEC * PAGE_SIZE / 22799921ec6STakashi Sakamoto CYCLES_PER_SECOND / ctx_header_size; 22899921ec6STakashi Sakamoto 229f706df4fSTakashi Sakamoto // In IEC 61883-6, one isoc packet can transfer events up to the value 230f706df4fSTakashi Sakamoto // of syt interval. This comes from the interval of isoc cycle. As 1394 231f706df4fSTakashi Sakamoto // OHCI controller can generate hardware IRQ per isoc packet, the 232f706df4fSTakashi Sakamoto // interval is 125 usec. 233f706df4fSTakashi Sakamoto // However, there are two ways of transmission in IEC 61883-6; blocking 234f706df4fSTakashi Sakamoto // and non-blocking modes. In blocking mode, the sequence of isoc packet 235f706df4fSTakashi Sakamoto // includes 'empty' or 'NODATA' packets which include no event. In 236f706df4fSTakashi Sakamoto // non-blocking mode, the number of events per packet is variable up to 237f706df4fSTakashi Sakamoto // the syt interval. 238f706df4fSTakashi Sakamoto // Due to the above protocol design, the minimum PCM frames per 239f706df4fSTakashi Sakamoto // interrupt should be double of the value of syt interval, thus it is 240f706df4fSTakashi Sakamoto // 250 usec. 241d67c46b9STakashi Sakamoto err = snd_pcm_hw_constraint_minmax(runtime, 242d67c46b9STakashi Sakamoto SNDRV_PCM_HW_PARAM_PERIOD_TIME, 243f706df4fSTakashi Sakamoto 250, maximum_usec_per_period); 244d67c46b9STakashi Sakamoto if (err < 0) 245d67c46b9STakashi Sakamoto goto end; 246d67c46b9STakashi Sakamoto 247d67c46b9STakashi Sakamoto /* Non-Blocking stream has no more constraints */ 248d67c46b9STakashi Sakamoto if (!(s->flags & CIP_BLOCKING)) 249d67c46b9STakashi Sakamoto goto end; 250d67c46b9STakashi Sakamoto 251d67c46b9STakashi Sakamoto /* 252d67c46b9STakashi Sakamoto * One AMDTP packet can include some frames. In blocking mode, the 253d67c46b9STakashi Sakamoto * number equals to SYT_INTERVAL. So the number is 8, 16 or 32, 254d67c46b9STakashi Sakamoto * depending on its sampling rate. For accurate period interrupt, it's 255d67c46b9STakashi Sakamoto * preferrable to align period/buffer sizes to current SYT_INTERVAL. 256d67c46b9STakashi Sakamoto */ 25759502295STakashi Sakamoto err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 25859502295STakashi Sakamoto apply_constraint_to_size, NULL, 259826b5de9STakashi Sakamoto SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 26059502295STakashi Sakamoto SNDRV_PCM_HW_PARAM_RATE, -1); 261d67c46b9STakashi Sakamoto if (err < 0) 262d67c46b9STakashi Sakamoto goto end; 26359502295STakashi Sakamoto err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 26459502295STakashi Sakamoto apply_constraint_to_size, NULL, 265826b5de9STakashi Sakamoto SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 26659502295STakashi Sakamoto SNDRV_PCM_HW_PARAM_RATE, -1); 26759502295STakashi Sakamoto if (err < 0) 26859502295STakashi Sakamoto goto end; 269d67c46b9STakashi Sakamoto end: 270d67c46b9STakashi Sakamoto return err; 271d67c46b9STakashi Sakamoto } 272d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints); 273d67c46b9STakashi Sakamoto 274d67c46b9STakashi Sakamoto /** 275d67c46b9STakashi Sakamoto * amdtp_stream_set_parameters - set stream parameters 276d67c46b9STakashi Sakamoto * @s: the AMDTP stream to configure 277d67c46b9STakashi Sakamoto * @rate: the sample rate 278df075feeSTakashi Sakamoto * @data_block_quadlets: the size of a data block in quadlet unit 279d67c46b9STakashi Sakamoto * 280d67c46b9STakashi Sakamoto * The parameters must be set before the stream is started, and must not be 281d67c46b9STakashi Sakamoto * changed while the stream is running. 282d67c46b9STakashi Sakamoto */ 283df075feeSTakashi Sakamoto int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate, 284df075feeSTakashi Sakamoto unsigned int data_block_quadlets) 285d67c46b9STakashi Sakamoto { 286df075feeSTakashi Sakamoto unsigned int sfc; 287d67c46b9STakashi Sakamoto 288d67c46b9STakashi Sakamoto for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) { 289d67c46b9STakashi Sakamoto if (amdtp_rate_table[sfc] == rate) 290d67c46b9STakashi Sakamoto break; 291d67c46b9STakashi Sakamoto } 292d67c46b9STakashi Sakamoto if (sfc == ARRAY_SIZE(amdtp_rate_table)) 293d67c46b9STakashi Sakamoto return -EINVAL; 294d67c46b9STakashi Sakamoto 295d67c46b9STakashi Sakamoto s->sfc = sfc; 296df075feeSTakashi Sakamoto s->data_block_quadlets = data_block_quadlets; 297d67c46b9STakashi Sakamoto s->syt_interval = amdtp_syt_intervals[sfc]; 298d67c46b9STakashi Sakamoto 299d3d10a4aSTakashi Sakamoto // default buffering in the device. 300d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_OUT_STREAM) { 301d3d10a4aSTakashi Sakamoto s->ctx_data.rx.transfer_delay = 302d3d10a4aSTakashi Sakamoto TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE; 303d3d10a4aSTakashi Sakamoto 304d3d10a4aSTakashi Sakamoto if (s->flags & CIP_BLOCKING) { 305d3d10a4aSTakashi Sakamoto // additional buffering needed to adjust for no-data 306d3d10a4aSTakashi Sakamoto // packets. 307d3d10a4aSTakashi Sakamoto s->ctx_data.rx.transfer_delay += 308d3d10a4aSTakashi Sakamoto TICKS_PER_SECOND * s->syt_interval / rate; 309d3d10a4aSTakashi Sakamoto } 310d3d10a4aSTakashi Sakamoto } 311d67c46b9STakashi Sakamoto 312d67c46b9STakashi Sakamoto return 0; 313d67c46b9STakashi Sakamoto } 314d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_set_parameters); 315d67c46b9STakashi Sakamoto 316d67c46b9STakashi Sakamoto /** 317d67c46b9STakashi Sakamoto * amdtp_stream_get_max_payload - get the stream's packet size 318d67c46b9STakashi Sakamoto * @s: the AMDTP stream 319d67c46b9STakashi Sakamoto * 320d67c46b9STakashi Sakamoto * This function must not be called before the stream has been configured 321d67c46b9STakashi Sakamoto * with amdtp_stream_set_parameters(). 322d67c46b9STakashi Sakamoto */ 323d67c46b9STakashi Sakamoto unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 324d67c46b9STakashi Sakamoto { 325d67c46b9STakashi Sakamoto unsigned int multiplier = 1; 32607ea238cSTakashi Sakamoto unsigned int cip_header_size = 0; 327d67c46b9STakashi Sakamoto 328d67c46b9STakashi Sakamoto if (s->flags & CIP_JUMBO_PAYLOAD) 3296a3ce97dSTakashi Sakamoto multiplier = IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES; 3303b196c39STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 331*67d92ee7STakashi Sakamoto cip_header_size = CIP_HEADER_SIZE; 332d67c46b9STakashi Sakamoto 33307ea238cSTakashi Sakamoto return cip_header_size + 33407ea238cSTakashi Sakamoto s->syt_interval * s->data_block_quadlets * sizeof(__be32) * multiplier; 335d67c46b9STakashi Sakamoto } 336d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_get_max_payload); 337d67c46b9STakashi Sakamoto 338d67c46b9STakashi Sakamoto /** 339d67c46b9STakashi Sakamoto * amdtp_stream_pcm_prepare - prepare PCM device for running 340d67c46b9STakashi Sakamoto * @s: the AMDTP stream 341d67c46b9STakashi Sakamoto * 342d67c46b9STakashi Sakamoto * This function should be called from the PCM device's .prepare callback. 343d67c46b9STakashi Sakamoto */ 344d67c46b9STakashi Sakamoto void amdtp_stream_pcm_prepare(struct amdtp_stream *s) 345d67c46b9STakashi Sakamoto { 3462b3d2987STakashi Iwai cancel_work_sync(&s->period_work); 347d67c46b9STakashi Sakamoto s->pcm_buffer_pointer = 0; 348d67c46b9STakashi Sakamoto s->pcm_period_pointer = 0; 349d67c46b9STakashi Sakamoto } 350d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_pcm_prepare); 351d67c46b9STakashi Sakamoto 352274fc355STakashi Sakamoto static unsigned int calculate_data_blocks(unsigned int *data_block_state, 353274fc355STakashi Sakamoto bool is_blocking, bool is_no_info, 354274fc355STakashi Sakamoto unsigned int syt_interval, enum cip_sfc sfc) 355d67c46b9STakashi Sakamoto { 356274fc355STakashi Sakamoto unsigned int data_blocks; 357d67c46b9STakashi Sakamoto 358d67c46b9STakashi Sakamoto /* Blocking mode. */ 359274fc355STakashi Sakamoto if (is_blocking) { 360d67c46b9STakashi Sakamoto /* This module generate empty packet for 'no data'. */ 361274fc355STakashi Sakamoto if (is_no_info) 362d67c46b9STakashi Sakamoto data_blocks = 0; 363d67c46b9STakashi Sakamoto else 364274fc355STakashi Sakamoto data_blocks = syt_interval; 365d67c46b9STakashi Sakamoto /* Non-blocking mode. */ 366d67c46b9STakashi Sakamoto } else { 367274fc355STakashi Sakamoto if (!cip_sfc_is_base_44100(sfc)) { 368d3d10a4aSTakashi Sakamoto // Sample_rate / 8000 is an integer, and precomputed. 369274fc355STakashi Sakamoto data_blocks = *data_block_state; 370d67c46b9STakashi Sakamoto } else { 371274fc355STakashi Sakamoto unsigned int phase = *data_block_state; 372d67c46b9STakashi Sakamoto 373d67c46b9STakashi Sakamoto /* 374d67c46b9STakashi Sakamoto * This calculates the number of data blocks per packet so that 375d67c46b9STakashi Sakamoto * 1) the overall rate is correct and exactly synchronized to 376d67c46b9STakashi Sakamoto * the bus clock, and 377d67c46b9STakashi Sakamoto * 2) packets with a rounded-up number of blocks occur as early 378d67c46b9STakashi Sakamoto * as possible in the sequence (to prevent underruns of the 379d67c46b9STakashi Sakamoto * device's buffer). 380d67c46b9STakashi Sakamoto */ 381274fc355STakashi Sakamoto if (sfc == CIP_SFC_44100) 382d67c46b9STakashi Sakamoto /* 6 6 5 6 5 6 5 ... */ 383d67c46b9STakashi Sakamoto data_blocks = 5 + ((phase & 1) ^ 384d67c46b9STakashi Sakamoto (phase == 0 || phase >= 40)); 385d67c46b9STakashi Sakamoto else 386d67c46b9STakashi Sakamoto /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */ 387274fc355STakashi Sakamoto data_blocks = 11 * (sfc >> 1) + (phase == 0); 388274fc355STakashi Sakamoto if (++phase >= (80 >> (sfc >> 1))) 389d67c46b9STakashi Sakamoto phase = 0; 390274fc355STakashi Sakamoto *data_block_state = phase; 391d67c46b9STakashi Sakamoto } 392d67c46b9STakashi Sakamoto } 393d67c46b9STakashi Sakamoto 394d67c46b9STakashi Sakamoto return data_blocks; 395d67c46b9STakashi Sakamoto } 396d67c46b9STakashi Sakamoto 397816d8482STakashi Sakamoto static unsigned int calculate_syt_offset(unsigned int *last_syt_offset, 398816d8482STakashi Sakamoto unsigned int *syt_offset_state, enum cip_sfc sfc) 399d67c46b9STakashi Sakamoto { 400816d8482STakashi Sakamoto unsigned int syt_offset; 401d67c46b9STakashi Sakamoto 402816d8482STakashi Sakamoto if (*last_syt_offset < TICKS_PER_CYCLE) { 403816d8482STakashi Sakamoto if (!cip_sfc_is_base_44100(sfc)) 404816d8482STakashi Sakamoto syt_offset = *last_syt_offset + *syt_offset_state; 405d67c46b9STakashi Sakamoto else { 406d67c46b9STakashi Sakamoto /* 407d67c46b9STakashi Sakamoto * The time, in ticks, of the n'th SYT_INTERVAL sample is: 408d67c46b9STakashi Sakamoto * n * SYT_INTERVAL * 24576000 / sample_rate 409d67c46b9STakashi Sakamoto * Modulo TICKS_PER_CYCLE, the difference between successive 410d67c46b9STakashi Sakamoto * elements is about 1386.23. Rounding the results of this 411d67c46b9STakashi Sakamoto * formula to the SYT precision results in a sequence of 412d67c46b9STakashi Sakamoto * differences that begins with: 413d67c46b9STakashi Sakamoto * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ... 414d67c46b9STakashi Sakamoto * This code generates _exactly_ the same sequence. 415d67c46b9STakashi Sakamoto */ 416816d8482STakashi Sakamoto unsigned int phase = *syt_offset_state; 417816d8482STakashi Sakamoto unsigned int index = phase % 13; 418816d8482STakashi Sakamoto 419816d8482STakashi Sakamoto syt_offset = *last_syt_offset; 420d67c46b9STakashi Sakamoto syt_offset += 1386 + ((index && !(index & 3)) || 421d67c46b9STakashi Sakamoto phase == 146); 422d67c46b9STakashi Sakamoto if (++phase >= 147) 423d67c46b9STakashi Sakamoto phase = 0; 424816d8482STakashi Sakamoto *syt_offset_state = phase; 425d67c46b9STakashi Sakamoto } 426d67c46b9STakashi Sakamoto } else 427816d8482STakashi Sakamoto syt_offset = *last_syt_offset - TICKS_PER_CYCLE; 428816d8482STakashi Sakamoto *last_syt_offset = syt_offset; 429d67c46b9STakashi Sakamoto 43083cfb5c5STakashi Sakamoto if (syt_offset >= TICKS_PER_CYCLE) 43183cfb5c5STakashi Sakamoto syt_offset = CIP_SYT_NO_INFO; 432d67c46b9STakashi Sakamoto 43383cfb5c5STakashi Sakamoto return syt_offset; 434d67c46b9STakashi Sakamoto } 435d67c46b9STakashi Sakamoto 436d67c46b9STakashi Sakamoto static void update_pcm_pointers(struct amdtp_stream *s, 437d67c46b9STakashi Sakamoto struct snd_pcm_substream *pcm, 438d67c46b9STakashi Sakamoto unsigned int frames) 439d67c46b9STakashi Sakamoto { 440d67c46b9STakashi Sakamoto unsigned int ptr; 441d67c46b9STakashi Sakamoto 442d67c46b9STakashi Sakamoto ptr = s->pcm_buffer_pointer + frames; 443d67c46b9STakashi Sakamoto if (ptr >= pcm->runtime->buffer_size) 444d67c46b9STakashi Sakamoto ptr -= pcm->runtime->buffer_size; 4456aa7de05SMark Rutland WRITE_ONCE(s->pcm_buffer_pointer, ptr); 446d67c46b9STakashi Sakamoto 447d67c46b9STakashi Sakamoto s->pcm_period_pointer += frames; 448d67c46b9STakashi Sakamoto if (s->pcm_period_pointer >= pcm->runtime->period_size) { 449d67c46b9STakashi Sakamoto s->pcm_period_pointer -= pcm->runtime->period_size; 4502b3d2987STakashi Iwai queue_work(system_highpri_wq, &s->period_work); 451d67c46b9STakashi Sakamoto } 452d67c46b9STakashi Sakamoto } 453d67c46b9STakashi Sakamoto 4542b3d2987STakashi Iwai static void pcm_period_work(struct work_struct *work) 455d67c46b9STakashi Sakamoto { 4562b3d2987STakashi Iwai struct amdtp_stream *s = container_of(work, struct amdtp_stream, 4572b3d2987STakashi Iwai period_work); 4586aa7de05SMark Rutland struct snd_pcm_substream *pcm = READ_ONCE(s->pcm); 459d67c46b9STakashi Sakamoto 460d67c46b9STakashi Sakamoto if (pcm) 461d67c46b9STakashi Sakamoto snd_pcm_period_elapsed(pcm); 462d67c46b9STakashi Sakamoto } 463d67c46b9STakashi Sakamoto 464e229853dSTakashi Sakamoto static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params, 465e229853dSTakashi Sakamoto bool sched_irq) 466d67c46b9STakashi Sakamoto { 4676007bf54STakashi Sakamoto int err; 468d67c46b9STakashi Sakamoto 469e229853dSTakashi Sakamoto params->interrupt = sched_irq; 4706007bf54STakashi Sakamoto params->tag = s->tag; 4716007bf54STakashi Sakamoto params->sy = 0; 472d67c46b9STakashi Sakamoto 4736007bf54STakashi Sakamoto err = fw_iso_context_queue(s->context, params, &s->buffer.iso_buffer, 474d67c46b9STakashi Sakamoto s->buffer.packets[s->packet_index].offset); 475d67c46b9STakashi Sakamoto if (err < 0) { 476d67c46b9STakashi Sakamoto dev_err(&s->unit->device, "queueing error: %d\n", err); 477d67c46b9STakashi Sakamoto goto end; 478d67c46b9STakashi Sakamoto } 479d67c46b9STakashi Sakamoto 480a0e02331STakashi Sakamoto if (++s->packet_index >= s->queue_size) 481d67c46b9STakashi Sakamoto s->packet_index = 0; 482d67c46b9STakashi Sakamoto end: 483d67c46b9STakashi Sakamoto return err; 484d67c46b9STakashi Sakamoto } 485d67c46b9STakashi Sakamoto 486d67c46b9STakashi Sakamoto static inline int queue_out_packet(struct amdtp_stream *s, 487e229853dSTakashi Sakamoto struct fw_iso_packet *params, bool sched_irq) 488d67c46b9STakashi Sakamoto { 489b18f0cfaSTakashi Sakamoto params->skip = 490b18f0cfaSTakashi Sakamoto !!(params->header_length == 0 && params->payload_length == 0); 491e229853dSTakashi Sakamoto return queue_packet(s, params, sched_irq); 492d67c46b9STakashi Sakamoto } 493d67c46b9STakashi Sakamoto 4946007bf54STakashi Sakamoto static inline int queue_in_packet(struct amdtp_stream *s, 49560dd4929STakashi Sakamoto struct fw_iso_packet *params) 496d67c46b9STakashi Sakamoto { 4976007bf54STakashi Sakamoto // Queue one packet for IR context. 4986007bf54STakashi Sakamoto params->header_length = s->ctx_data.tx.ctx_header_size; 4996007bf54STakashi Sakamoto params->payload_length = s->ctx_data.tx.max_ctx_payload_length; 5006007bf54STakashi Sakamoto params->skip = false; 50160dd4929STakashi Sakamoto return queue_packet(s, params, false); 502d67c46b9STakashi Sakamoto } 503d67c46b9STakashi Sakamoto 504252219c7STakashi Sakamoto static void generate_cip_header(struct amdtp_stream *s, __be32 cip_header[2], 505860d798cSTakashi Sakamoto unsigned int data_block_counter, unsigned int syt) 506252219c7STakashi Sakamoto { 507252219c7STakashi Sakamoto cip_header[0] = cpu_to_be32(READ_ONCE(s->source_node_id_field) | 508252219c7STakashi Sakamoto (s->data_block_quadlets << CIP_DBS_SHIFT) | 509252219c7STakashi Sakamoto ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) | 510860d798cSTakashi Sakamoto data_block_counter); 511252219c7STakashi Sakamoto cip_header[1] = cpu_to_be32(CIP_EOH | 512252219c7STakashi Sakamoto ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | 513252219c7STakashi Sakamoto ((s->ctx_data.rx.fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | 514252219c7STakashi Sakamoto (syt & CIP_SYT_MASK)); 515252219c7STakashi Sakamoto } 516252219c7STakashi Sakamoto 5176bc1a269STakashi Sakamoto static void build_it_pkt_header(struct amdtp_stream *s, unsigned int cycle, 5186bc1a269STakashi Sakamoto struct fw_iso_packet *params, 519860d798cSTakashi Sakamoto unsigned int data_blocks, 520860d798cSTakashi Sakamoto unsigned int data_block_counter, 521860d798cSTakashi Sakamoto unsigned int syt, unsigned int index) 522d67c46b9STakashi Sakamoto { 5230ebf3cebSTakashi Sakamoto unsigned int payload_length; 52416be4589STakashi Sakamoto __be32 *cip_header; 525d67c46b9STakashi Sakamoto 5260ebf3cebSTakashi Sakamoto payload_length = data_blocks * sizeof(__be32) * s->data_block_quadlets; 5270ebf3cebSTakashi Sakamoto params->payload_length = payload_length; 5280ebf3cebSTakashi Sakamoto 529b18f0cfaSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) { 5306bc1a269STakashi Sakamoto cip_header = (__be32 *)params->header; 531860d798cSTakashi Sakamoto generate_cip_header(s, cip_header, data_block_counter, syt); 5326bc1a269STakashi Sakamoto params->header_length = 2 * sizeof(__be32); 5330ebf3cebSTakashi Sakamoto payload_length += params->header_length; 534b18f0cfaSTakashi Sakamoto } else { 535b18f0cfaSTakashi Sakamoto cip_header = NULL; 536b18f0cfaSTakashi Sakamoto } 537d67c46b9STakashi Sakamoto 538213fa989STakashi Sakamoto trace_amdtp_packet(s, cycle, cip_header, payload_length, data_blocks, 539814b4312STakashi Sakamoto data_block_counter, s->packet_index, index); 5403b196c39STakashi Sakamoto } 5413b196c39STakashi Sakamoto 542e335425bSTakashi Sakamoto static int check_cip_header(struct amdtp_stream *s, const __be32 *buf, 543e335425bSTakashi Sakamoto unsigned int payload_length, 544a35463d1STakashi Sakamoto unsigned int *data_blocks, 545a35463d1STakashi Sakamoto unsigned int *data_block_counter, unsigned int *syt) 546d67c46b9STakashi Sakamoto { 547d67c46b9STakashi Sakamoto u32 cip_header[2]; 548e335425bSTakashi Sakamoto unsigned int sph; 549e335425bSTakashi Sakamoto unsigned int fmt; 550e335425bSTakashi Sakamoto unsigned int fdf; 551a35463d1STakashi Sakamoto unsigned int dbc; 552d67c46b9STakashi Sakamoto bool lost; 553d67c46b9STakashi Sakamoto 554e335425bSTakashi Sakamoto cip_header[0] = be32_to_cpu(buf[0]); 555e335425bSTakashi Sakamoto cip_header[1] = be32_to_cpu(buf[1]); 556d67c46b9STakashi Sakamoto 557d67c46b9STakashi Sakamoto /* 558d67c46b9STakashi Sakamoto * This module supports 'Two-quadlet CIP header with SYT field'. 559d67c46b9STakashi Sakamoto * For convenience, also check FMT field is AM824 or not. 560d67c46b9STakashi Sakamoto */ 5612128f78fSTakashi Sakamoto if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 5622128f78fSTakashi Sakamoto ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) && 5632128f78fSTakashi Sakamoto (!(s->flags & CIP_HEADER_WITHOUT_EOH))) { 564d67c46b9STakashi Sakamoto dev_info_ratelimited(&s->unit->device, 565d67c46b9STakashi Sakamoto "Invalid CIP header for AMDTP: %08X:%08X\n", 566d67c46b9STakashi Sakamoto cip_header[0], cip_header[1]); 567e335425bSTakashi Sakamoto return -EAGAIN; 568d67c46b9STakashi Sakamoto } 569d67c46b9STakashi Sakamoto 570d67c46b9STakashi Sakamoto /* Check valid protocol or not. */ 5719863874fSTakashi Sakamoto sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT; 572d67c46b9STakashi Sakamoto fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT; 5739863874fSTakashi Sakamoto if (sph != s->sph || fmt != s->fmt) { 5742a7e1713STakashi Sakamoto dev_info_ratelimited(&s->unit->device, 575d67c46b9STakashi Sakamoto "Detect unexpected protocol: %08x %08x\n", 576d67c46b9STakashi Sakamoto cip_header[0], cip_header[1]); 577e335425bSTakashi Sakamoto return -EAGAIN; 578d67c46b9STakashi Sakamoto } 579d67c46b9STakashi Sakamoto 580d67c46b9STakashi Sakamoto /* Calculate data blocks */ 581d67c46b9STakashi Sakamoto fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT; 5824fd18787STakashi Sakamoto if (payload_length == 0 || (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) { 583e335425bSTakashi Sakamoto *data_blocks = 0; 584d67c46b9STakashi Sakamoto } else { 585e335425bSTakashi Sakamoto unsigned int data_block_quadlets = 586d67c46b9STakashi Sakamoto (cip_header[0] & CIP_DBS_MASK) >> CIP_DBS_SHIFT; 587d67c46b9STakashi Sakamoto /* avoid division by zero */ 588d67c46b9STakashi Sakamoto if (data_block_quadlets == 0) { 589d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 590d67c46b9STakashi Sakamoto "Detect invalid value in dbs field: %08X\n", 591d67c46b9STakashi Sakamoto cip_header[0]); 592d67c46b9STakashi Sakamoto return -EPROTO; 593d67c46b9STakashi Sakamoto } 594d67c46b9STakashi Sakamoto if (s->flags & CIP_WRONG_DBS) 595d67c46b9STakashi Sakamoto data_block_quadlets = s->data_block_quadlets; 596d67c46b9STakashi Sakamoto 5974fd18787STakashi Sakamoto *data_blocks = payload_length / sizeof(__be32) / data_block_quadlets; 598d67c46b9STakashi Sakamoto } 599d67c46b9STakashi Sakamoto 600d67c46b9STakashi Sakamoto /* Check data block counter continuity */ 601a35463d1STakashi Sakamoto dbc = cip_header[0] & CIP_DBC_MASK; 602e335425bSTakashi Sakamoto if (*data_blocks == 0 && (s->flags & CIP_EMPTY_HAS_WRONG_DBC) && 603a35463d1STakashi Sakamoto *data_block_counter != UINT_MAX) 604a35463d1STakashi Sakamoto dbc = *data_block_counter; 605d67c46b9STakashi Sakamoto 606a35463d1STakashi Sakamoto if ((dbc == 0x00 && (s->flags & CIP_SKIP_DBC_ZERO_CHECK)) || 607a35463d1STakashi Sakamoto *data_block_counter == UINT_MAX) { 608d67c46b9STakashi Sakamoto lost = false; 609d67c46b9STakashi Sakamoto } else if (!(s->flags & CIP_DBC_IS_END_EVENT)) { 610a35463d1STakashi Sakamoto lost = dbc != *data_block_counter; 611d67c46b9STakashi Sakamoto } else { 612e335425bSTakashi Sakamoto unsigned int dbc_interval; 613e335425bSTakashi Sakamoto 614e335425bSTakashi Sakamoto if (*data_blocks > 0 && s->ctx_data.tx.dbc_interval > 0) 615d3d10a4aSTakashi Sakamoto dbc_interval = s->ctx_data.tx.dbc_interval; 616d67c46b9STakashi Sakamoto else 617e335425bSTakashi Sakamoto dbc_interval = *data_blocks; 618d67c46b9STakashi Sakamoto 619a35463d1STakashi Sakamoto lost = dbc != ((*data_block_counter + dbc_interval) & 0xff); 620d67c46b9STakashi Sakamoto } 621d67c46b9STakashi Sakamoto 622d67c46b9STakashi Sakamoto if (lost) { 623d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 624d67c46b9STakashi Sakamoto "Detect discontinuity of CIP: %02X %02X\n", 625a35463d1STakashi Sakamoto *data_block_counter, dbc); 626d67c46b9STakashi Sakamoto return -EIO; 627d67c46b9STakashi Sakamoto } 628d67c46b9STakashi Sakamoto 629753e7179STakashi Sakamoto *data_block_counter = dbc; 630753e7179STakashi Sakamoto 631e335425bSTakashi Sakamoto *syt = cip_header[1] & CIP_SYT_MASK; 632e335425bSTakashi Sakamoto 633e335425bSTakashi Sakamoto return 0; 634e335425bSTakashi Sakamoto } 635e335425bSTakashi Sakamoto 63698e3e43bSTakashi Sakamoto static int parse_ir_ctx_header(struct amdtp_stream *s, unsigned int cycle, 63798e3e43bSTakashi Sakamoto const __be32 *ctx_header, 638a35463d1STakashi Sakamoto unsigned int *data_blocks, 639a35463d1STakashi Sakamoto unsigned int *data_block_counter, 640814b4312STakashi Sakamoto unsigned int *syt, unsigned int packet_index, unsigned int index) 641e335425bSTakashi Sakamoto { 642ebd2a647STakashi Sakamoto unsigned int payload_length; 643f11453c7STakashi Sakamoto const __be32 *cip_header; 644395f41e2STakashi Sakamoto unsigned int cip_header_size; 645e335425bSTakashi Sakamoto int err; 646e335425bSTakashi Sakamoto 647ebd2a647STakashi Sakamoto payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT; 648395f41e2STakashi Sakamoto 649395f41e2STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 650*67d92ee7STakashi Sakamoto cip_header_size = CIP_HEADER_SIZE; 651395f41e2STakashi Sakamoto else 652395f41e2STakashi Sakamoto cip_header_size = 0; 653395f41e2STakashi Sakamoto 654ebd2a647STakashi Sakamoto if (payload_length > cip_header_size + s->ctx_data.tx.max_ctx_payload_length) { 655e335425bSTakashi Sakamoto dev_err(&s->unit->device, 656e335425bSTakashi Sakamoto "Detect jumbo payload: %04x %04x\n", 657ebd2a647STakashi Sakamoto payload_length, cip_header_size + s->ctx_data.tx.max_ctx_payload_length); 658e335425bSTakashi Sakamoto return -EIO; 659e335425bSTakashi Sakamoto } 660e335425bSTakashi Sakamoto 661395f41e2STakashi Sakamoto if (cip_header_size > 0) { 662ebd2a647STakashi Sakamoto if (payload_length >= cip_header_size) { 663*67d92ee7STakashi Sakamoto cip_header = ctx_header + IR_CTX_HEADER_DEFAULT_QUADLETS; 6644fd18787STakashi Sakamoto err = check_cip_header(s, cip_header, payload_length - cip_header_size, 6654fd18787STakashi Sakamoto data_blocks, data_block_counter, syt); 666b8b0e24cSTakashi Sakamoto if (err < 0) 667e335425bSTakashi Sakamoto return err; 668947b437eSTakashi Sakamoto } else { 669c09010eeSTakashi Sakamoto // Handle the cycle so that empty packet arrives. 670c09010eeSTakashi Sakamoto cip_header = NULL; 671c09010eeSTakashi Sakamoto *data_blocks = 0; 672c09010eeSTakashi Sakamoto *syt = 0; 673c09010eeSTakashi Sakamoto } 674c09010eeSTakashi Sakamoto } else { 675947b437eSTakashi Sakamoto cip_header = NULL; 67676864868STakashi Sakamoto err = 0; 677ebd2a647STakashi Sakamoto *data_blocks = payload_length / sizeof(__be32) / s->data_block_quadlets; 67898e3e43bSTakashi Sakamoto *syt = 0; 6797fbf9096STakashi Sakamoto 680a35463d1STakashi Sakamoto if (*data_block_counter == UINT_MAX) 681a35463d1STakashi Sakamoto *data_block_counter = 0; 682947b437eSTakashi Sakamoto } 683e335425bSTakashi Sakamoto 684ebd2a647STakashi Sakamoto trace_amdtp_packet(s, cycle, cip_header, payload_length, *data_blocks, 685814b4312STakashi Sakamoto *data_block_counter, packet_index, index); 68664d0bf4dSTakashi Sakamoto 68776864868STakashi Sakamoto return err; 688d67c46b9STakashi Sakamoto } 689d67c46b9STakashi Sakamoto 69026cd1e58STakashi Sakamoto // In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On 69126cd1e58STakashi Sakamoto // the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent 69226cd1e58STakashi Sakamoto // it. Thus, via Linux firewire subsystem, we can get the 3 bits for second. 6933e106f4fSTakashi Sakamoto static inline u32 compute_ohci_cycle_count(__be32 ctx_header_tstamp) 69473fc7f08STakashi Sakamoto { 69526cd1e58STakashi Sakamoto u32 tstamp = be32_to_cpu(ctx_header_tstamp) & HEADER_TSTAMP_MASK; 69673fc7f08STakashi Sakamoto return (((tstamp >> 13) & 0x07) * 8000) + (tstamp & 0x1fff); 69773fc7f08STakashi Sakamoto } 69873fc7f08STakashi Sakamoto 6993e106f4fSTakashi Sakamoto static inline u32 increment_ohci_cycle_count(u32 cycle, unsigned int addend) 70073fc7f08STakashi Sakamoto { 70173fc7f08STakashi Sakamoto cycle += addend; 7023e106f4fSTakashi Sakamoto if (cycle >= OHCI_SECOND_MODULUS * CYCLES_PER_SECOND) 7033e106f4fSTakashi Sakamoto cycle -= OHCI_SECOND_MODULUS * CYCLES_PER_SECOND; 70473fc7f08STakashi Sakamoto return cycle; 70573fc7f08STakashi Sakamoto } 70673fc7f08STakashi Sakamoto 707705794c5STakashi Sakamoto static int compare_ohci_cycle_count(u32 lval, u32 rval) 708705794c5STakashi Sakamoto { 709705794c5STakashi Sakamoto if (lval == rval) 710705794c5STakashi Sakamoto return 0; 711705794c5STakashi Sakamoto else if (lval < rval && rval - lval < OHCI_SECOND_MODULUS * CYCLES_PER_SECOND / 2) 712705794c5STakashi Sakamoto return -1; 713705794c5STakashi Sakamoto else 714705794c5STakashi Sakamoto return 1; 715705794c5STakashi Sakamoto } 716705794c5STakashi Sakamoto 71726cd1e58STakashi Sakamoto // Align to actual cycle count for the packet which is going to be scheduled. 718a0e02331STakashi Sakamoto // This module queued the same number of isochronous cycle as the size of queue 719a0e02331STakashi Sakamoto // to kip isochronous cycle, therefore it's OK to just increment the cycle by 720a0e02331STakashi Sakamoto // the size of queue for scheduled cycle. 7213e106f4fSTakashi Sakamoto static inline u32 compute_ohci_it_cycle(const __be32 ctx_header_tstamp, 722a0e02331STakashi Sakamoto unsigned int queue_size) 72326cd1e58STakashi Sakamoto { 7243e106f4fSTakashi Sakamoto u32 cycle = compute_ohci_cycle_count(ctx_header_tstamp); 7253e106f4fSTakashi Sakamoto return increment_ohci_cycle_count(cycle, queue_size); 72626cd1e58STakashi Sakamoto } 72726cd1e58STakashi Sakamoto 728753e7179STakashi Sakamoto static int generate_device_pkt_descs(struct amdtp_stream *s, 729753e7179STakashi Sakamoto struct pkt_desc *descs, 730753e7179STakashi Sakamoto const __be32 *ctx_header, 73173246fc4STakashi Sakamoto unsigned int packets, 73273246fc4STakashi Sakamoto unsigned int *desc_count) 733753e7179STakashi Sakamoto { 734705794c5STakashi Sakamoto unsigned int next_cycle = s->next_cycle; 735753e7179STakashi Sakamoto unsigned int dbc = s->data_block_counter; 736814b4312STakashi Sakamoto unsigned int packet_index = s->packet_index; 737814b4312STakashi Sakamoto unsigned int queue_size = s->queue_size; 738753e7179STakashi Sakamoto int i; 739753e7179STakashi Sakamoto int err; 740753e7179STakashi Sakamoto 74173246fc4STakashi Sakamoto *desc_count = 0; 742753e7179STakashi Sakamoto for (i = 0; i < packets; ++i) { 74373246fc4STakashi Sakamoto struct pkt_desc *desc = descs + *desc_count; 744753e7179STakashi Sakamoto unsigned int cycle; 745705794c5STakashi Sakamoto bool lost; 746753e7179STakashi Sakamoto unsigned int data_blocks; 747753e7179STakashi Sakamoto unsigned int syt; 748753e7179STakashi Sakamoto 7493e106f4fSTakashi Sakamoto cycle = compute_ohci_cycle_count(ctx_header[1]); 750705794c5STakashi Sakamoto lost = (next_cycle != cycle); 751705794c5STakashi Sakamoto if (lost) { 752705794c5STakashi Sakamoto if (s->flags & CIP_NO_HEADER) { 753705794c5STakashi Sakamoto // Fireface skips transmission just for an isoc cycle corresponding 754705794c5STakashi Sakamoto // to empty packet. 75573246fc4STakashi Sakamoto unsigned int prev_cycle = next_cycle; 75673246fc4STakashi Sakamoto 757705794c5STakashi Sakamoto next_cycle = increment_ohci_cycle_count(next_cycle, 1); 758705794c5STakashi Sakamoto lost = (next_cycle != cycle); 75973246fc4STakashi Sakamoto if (!lost) { 76073246fc4STakashi Sakamoto // Prepare a description for the skipped cycle for 76173246fc4STakashi Sakamoto // sequence replay. 76273246fc4STakashi Sakamoto desc->cycle = prev_cycle; 76373246fc4STakashi Sakamoto desc->syt = 0; 76473246fc4STakashi Sakamoto desc->data_blocks = 0; 76573246fc4STakashi Sakamoto desc->data_block_counter = dbc; 76673246fc4STakashi Sakamoto desc->ctx_payload = NULL; 76773246fc4STakashi Sakamoto ++desc; 76873246fc4STakashi Sakamoto ++(*desc_count); 76973246fc4STakashi Sakamoto } 770705794c5STakashi Sakamoto } else if (s->flags & CIP_JUMBO_PAYLOAD) { 771705794c5STakashi Sakamoto // OXFW970 skips transmission for several isoc cycles during 77273246fc4STakashi Sakamoto // asynchronous transaction. The sequence replay is impossible due 77373246fc4STakashi Sakamoto // to the reason. 774705794c5STakashi Sakamoto unsigned int safe_cycle = increment_ohci_cycle_count(next_cycle, 775705794c5STakashi Sakamoto IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES); 776705794c5STakashi Sakamoto lost = (compare_ohci_cycle_count(safe_cycle, cycle) > 0); 777705794c5STakashi Sakamoto } 778705794c5STakashi Sakamoto if (lost) { 779705794c5STakashi Sakamoto dev_err(&s->unit->device, "Detect discontinuity of cycle: %d %d\n", 780705794c5STakashi Sakamoto next_cycle, cycle); 781705794c5STakashi Sakamoto return -EIO; 782705794c5STakashi Sakamoto } 783705794c5STakashi Sakamoto } 784753e7179STakashi Sakamoto 785ebd2a647STakashi Sakamoto err = parse_ir_ctx_header(s, cycle, ctx_header, &data_blocks, &dbc, &syt, 786ebd2a647STakashi Sakamoto packet_index, i); 787753e7179STakashi Sakamoto if (err < 0) 788753e7179STakashi Sakamoto return err; 789753e7179STakashi Sakamoto 790753e7179STakashi Sakamoto desc->cycle = cycle; 791753e7179STakashi Sakamoto desc->syt = syt; 792753e7179STakashi Sakamoto desc->data_blocks = data_blocks; 793753e7179STakashi Sakamoto desc->data_block_counter = dbc; 794814b4312STakashi Sakamoto desc->ctx_payload = s->buffer.packets[packet_index].buffer; 795753e7179STakashi Sakamoto 796753e7179STakashi Sakamoto if (!(s->flags & CIP_DBC_IS_END_EVENT)) 797753e7179STakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 798753e7179STakashi Sakamoto 799705794c5STakashi Sakamoto next_cycle = increment_ohci_cycle_count(next_cycle, 1); 80073246fc4STakashi Sakamoto ++(*desc_count); 801705794c5STakashi Sakamoto ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header); 802814b4312STakashi Sakamoto packet_index = (packet_index + 1) % queue_size; 803753e7179STakashi Sakamoto } 804753e7179STakashi Sakamoto 805705794c5STakashi Sakamoto s->next_cycle = next_cycle; 806753e7179STakashi Sakamoto s->data_block_counter = dbc; 807753e7179STakashi Sakamoto 808753e7179STakashi Sakamoto return 0; 809753e7179STakashi Sakamoto } 810753e7179STakashi Sakamoto 81183cfb5c5STakashi Sakamoto static unsigned int compute_syt(unsigned int syt_offset, unsigned int cycle, 81283cfb5c5STakashi Sakamoto unsigned int transfer_delay) 81383cfb5c5STakashi Sakamoto { 81483cfb5c5STakashi Sakamoto unsigned int syt; 81583cfb5c5STakashi Sakamoto 81683cfb5c5STakashi Sakamoto syt_offset += transfer_delay; 81783cfb5c5STakashi Sakamoto syt = ((cycle + syt_offset / TICKS_PER_CYCLE) << 12) | 81883cfb5c5STakashi Sakamoto (syt_offset % TICKS_PER_CYCLE); 81983cfb5c5STakashi Sakamoto return syt & CIP_SYT_MASK; 82083cfb5c5STakashi Sakamoto } 82183cfb5c5STakashi Sakamoto 82269efd5c4STakashi Sakamoto static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs, 82369efd5c4STakashi Sakamoto const __be32 *ctx_header, unsigned int packets, 82469efd5c4STakashi Sakamoto const struct seq_desc *seq_descs, 82569efd5c4STakashi Sakamoto unsigned int seq_size) 826f4f6ae7bSTakashi Sakamoto { 827f4f6ae7bSTakashi Sakamoto unsigned int dbc = s->data_block_counter; 82869efd5c4STakashi Sakamoto unsigned int seq_index = s->ctx_data.rx.seq_index; 829f4f6ae7bSTakashi Sakamoto int i; 830f4f6ae7bSTakashi Sakamoto 831f4f6ae7bSTakashi Sakamoto for (i = 0; i < packets; ++i) { 832f4f6ae7bSTakashi Sakamoto struct pkt_desc *desc = descs + i; 833a0e02331STakashi Sakamoto unsigned int index = (s->packet_index + i) % s->queue_size; 83469efd5c4STakashi Sakamoto const struct seq_desc *seq = seq_descs + seq_index; 83569efd5c4STakashi Sakamoto unsigned int syt; 836f4f6ae7bSTakashi Sakamoto 8373e106f4fSTakashi Sakamoto desc->cycle = compute_ohci_it_cycle(*ctx_header, s->queue_size); 83869efd5c4STakashi Sakamoto 83969efd5c4STakashi Sakamoto syt = seq->syt_offset; 84069efd5c4STakashi Sakamoto if (syt != CIP_SYT_NO_INFO) { 84169efd5c4STakashi Sakamoto syt = compute_syt(syt, desc->cycle, 84283cfb5c5STakashi Sakamoto s->ctx_data.rx.transfer_delay); 84383cfb5c5STakashi Sakamoto } 84469efd5c4STakashi Sakamoto desc->syt = syt; 84569efd5c4STakashi Sakamoto desc->data_blocks = seq->data_blocks; 846f4f6ae7bSTakashi Sakamoto 847f4f6ae7bSTakashi Sakamoto if (s->flags & CIP_DBC_IS_END_EVENT) 848f4f6ae7bSTakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 849f4f6ae7bSTakashi Sakamoto 850f4f6ae7bSTakashi Sakamoto desc->data_block_counter = dbc; 851f4f6ae7bSTakashi Sakamoto 852f4f6ae7bSTakashi Sakamoto if (!(s->flags & CIP_DBC_IS_END_EVENT)) 853f4f6ae7bSTakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 854f4f6ae7bSTakashi Sakamoto 855f4f6ae7bSTakashi Sakamoto desc->ctx_payload = s->buffer.packets[index].buffer; 856f4f6ae7bSTakashi Sakamoto 85769efd5c4STakashi Sakamoto seq_index = (seq_index + 1) % seq_size; 85869efd5c4STakashi Sakamoto 859f4f6ae7bSTakashi Sakamoto ++ctx_header; 860f4f6ae7bSTakashi Sakamoto } 861f4f6ae7bSTakashi Sakamoto 862f4f6ae7bSTakashi Sakamoto s->data_block_counter = dbc; 86369efd5c4STakashi Sakamoto s->ctx_data.rx.seq_index = seq_index; 864f4f6ae7bSTakashi Sakamoto } 865f4f6ae7bSTakashi Sakamoto 866fce9b013STakashi Sakamoto static inline void cancel_stream(struct amdtp_stream *s) 867fce9b013STakashi Sakamoto { 868fce9b013STakashi Sakamoto s->packet_index = -1; 8692b3d2987STakashi Iwai if (current_work() == &s->period_work) 870fce9b013STakashi Sakamoto amdtp_stream_pcm_abort(s); 871fce9b013STakashi Sakamoto WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); 872fce9b013STakashi Sakamoto } 873fce9b013STakashi Sakamoto 8740f5cfcb2STakashi Sakamoto static void process_ctx_payloads(struct amdtp_stream *s, 8750f5cfcb2STakashi Sakamoto const struct pkt_desc *descs, 8760f5cfcb2STakashi Sakamoto unsigned int packets) 8770f5cfcb2STakashi Sakamoto { 8789a738ad1STakashi Sakamoto struct snd_pcm_substream *pcm; 8790f5cfcb2STakashi Sakamoto unsigned int pcm_frames; 8800f5cfcb2STakashi Sakamoto 8819a738ad1STakashi Sakamoto pcm = READ_ONCE(s->pcm); 8829a738ad1STakashi Sakamoto pcm_frames = s->process_ctx_payloads(s, descs, packets, pcm); 8839a738ad1STakashi Sakamoto if (pcm) 8840f5cfcb2STakashi Sakamoto update_pcm_pointers(s, pcm, pcm_frames); 8850f5cfcb2STakashi Sakamoto } 8860f5cfcb2STakashi Sakamoto 88773fc7f08STakashi Sakamoto static void out_stream_callback(struct fw_iso_context *context, u32 tstamp, 888d67c46b9STakashi Sakamoto size_t header_length, void *header, 889d67c46b9STakashi Sakamoto void *private_data) 890d67c46b9STakashi Sakamoto { 891d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 89269efd5c4STakashi Sakamoto const struct amdtp_domain *d = s->domain; 89326cd1e58STakashi Sakamoto const __be32 *ctx_header = header; 8946d60b7a3STakashi Sakamoto unsigned int events_per_period = d->events_per_period; 89560dd4929STakashi Sakamoto unsigned int event_count = s->ctx_data.rx.event_count; 896a0e02331STakashi Sakamoto unsigned int packets; 8970dcb4efbSTakashi Sakamoto int i; 898d67c46b9STakashi Sakamoto 899d67c46b9STakashi Sakamoto if (s->packet_index < 0) 900d67c46b9STakashi Sakamoto return; 901d67c46b9STakashi Sakamoto 902a0e02331STakashi Sakamoto // Calculate the number of packets in buffer and check XRUN. 903a0e02331STakashi Sakamoto packets = header_length / sizeof(*ctx_header); 904a0e02331STakashi Sakamoto 905d32872f3STakashi Sakamoto generate_pkt_descs(s, s->pkt_descs, ctx_header, packets, d->seq.descs, 906d32872f3STakashi Sakamoto d->seq.size); 907f4f6ae7bSTakashi Sakamoto 9080f5cfcb2STakashi Sakamoto process_ctx_payloads(s, s->pkt_descs, packets); 9095e2ece0fSTakashi Sakamoto 9105e2ece0fSTakashi Sakamoto for (i = 0; i < packets; ++i) { 9115e2ece0fSTakashi Sakamoto const struct pkt_desc *desc = s->pkt_descs + i; 912f4f6ae7bSTakashi Sakamoto unsigned int syt; 9136bc1a269STakashi Sakamoto struct { 9146bc1a269STakashi Sakamoto struct fw_iso_packet params; 915*67d92ee7STakashi Sakamoto __be32 header[CIP_HEADER_QUADLETS]; 9166bc1a269STakashi Sakamoto } template = { {0}, {0} }; 917e229853dSTakashi Sakamoto bool sched_irq = false; 918860d798cSTakashi Sakamoto 919f4f6ae7bSTakashi Sakamoto if (s->ctx_data.rx.syt_override < 0) 920f4f6ae7bSTakashi Sakamoto syt = desc->syt; 921f4f6ae7bSTakashi Sakamoto else 9223baf3053STakashi Sakamoto syt = s->ctx_data.rx.syt_override; 9233baf3053STakashi Sakamoto 924f4f6ae7bSTakashi Sakamoto build_it_pkt_header(s, desc->cycle, &template.params, 925f4f6ae7bSTakashi Sakamoto desc->data_blocks, desc->data_block_counter, 926f4f6ae7bSTakashi Sakamoto syt, i); 9276bc1a269STakashi Sakamoto 9282472cfb3STakashi Sakamoto if (s == s->domain->irq_target) { 929e229853dSTakashi Sakamoto event_count += desc->data_blocks; 930e229853dSTakashi Sakamoto if (event_count >= events_per_period) { 931e229853dSTakashi Sakamoto event_count -= events_per_period; 932e229853dSTakashi Sakamoto sched_irq = true; 933e229853dSTakashi Sakamoto } 93460dd4929STakashi Sakamoto } 935e229853dSTakashi Sakamoto 936e229853dSTakashi Sakamoto if (queue_out_packet(s, &template.params, sched_irq) < 0) { 937fce9b013STakashi Sakamoto cancel_stream(s); 938d67c46b9STakashi Sakamoto return; 939d67c46b9STakashi Sakamoto } 940d67c46b9STakashi Sakamoto } 941d67c46b9STakashi Sakamoto 94260dd4929STakashi Sakamoto s->ctx_data.rx.event_count = event_count; 943d67c46b9STakashi Sakamoto } 944d67c46b9STakashi Sakamoto 94573fc7f08STakashi Sakamoto static void in_stream_callback(struct fw_iso_context *context, u32 tstamp, 946d67c46b9STakashi Sakamoto size_t header_length, void *header, 947d67c46b9STakashi Sakamoto void *private_data) 948d67c46b9STakashi Sakamoto { 949d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 950cc4f8e91STakashi Sakamoto __be32 *ctx_header = header; 951e229853dSTakashi Sakamoto unsigned int packets; 95273246fc4STakashi Sakamoto unsigned int desc_count; 953753e7179STakashi Sakamoto int i; 954753e7179STakashi Sakamoto int err; 955d67c46b9STakashi Sakamoto 956d67c46b9STakashi Sakamoto if (s->packet_index < 0) 957d67c46b9STakashi Sakamoto return; 958d67c46b9STakashi Sakamoto 959a0e02331STakashi Sakamoto // Calculate the number of packets in buffer and check XRUN. 960d3d10a4aSTakashi Sakamoto packets = header_length / s->ctx_data.tx.ctx_header_size; 961f90e2dedSTakashi Sakamoto 96273246fc4STakashi Sakamoto desc_count = 0; 96373246fc4STakashi Sakamoto err = generate_device_pkt_descs(s, s->pkt_descs, ctx_header, packets, &desc_count); 964753e7179STakashi Sakamoto if (err < 0) { 965753e7179STakashi Sakamoto if (err != -EAGAIN) { 966753e7179STakashi Sakamoto cancel_stream(s); 967753e7179STakashi Sakamoto return; 968753e7179STakashi Sakamoto } 9695e2ece0fSTakashi Sakamoto } else { 97073246fc4STakashi Sakamoto process_ctx_payloads(s, s->pkt_descs, desc_count); 9715e2ece0fSTakashi Sakamoto } 9725e2ece0fSTakashi Sakamoto 9735e2ece0fSTakashi Sakamoto for (i = 0; i < packets; ++i) { 9745e2ece0fSTakashi Sakamoto struct fw_iso_packet params = {0}; 975a35463d1STakashi Sakamoto 97660dd4929STakashi Sakamoto if (queue_in_packet(s, ¶ms) < 0) { 977753e7179STakashi Sakamoto cancel_stream(s); 978753e7179STakashi Sakamoto return; 979753e7179STakashi Sakamoto } 980d67c46b9STakashi Sakamoto } 981d67c46b9STakashi Sakamoto } 982d67c46b9STakashi Sakamoto 9831a4be183STakashi Sakamoto static void pool_ideal_seq_descs(struct amdtp_domain *d, unsigned int packets) 9841a4be183STakashi Sakamoto { 9851a4be183STakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 986d32872f3STakashi Sakamoto unsigned int seq_tail = d->seq.tail; 987d32872f3STakashi Sakamoto unsigned int seq_size = d->seq.size; 9881a4be183STakashi Sakamoto unsigned int min_avail; 9891a4be183STakashi Sakamoto struct amdtp_stream *s; 9901a4be183STakashi Sakamoto 991d32872f3STakashi Sakamoto min_avail = d->seq.size; 9921a4be183STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 9931a4be183STakashi Sakamoto unsigned int seq_index; 9941a4be183STakashi Sakamoto unsigned int avail; 9951a4be183STakashi Sakamoto 9961a4be183STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) 9971a4be183STakashi Sakamoto continue; 9981a4be183STakashi Sakamoto 9991a4be183STakashi Sakamoto seq_index = s->ctx_data.rx.seq_index; 1000d32872f3STakashi Sakamoto avail = d->seq.tail; 10011a4be183STakashi Sakamoto if (seq_index > avail) 1002d32872f3STakashi Sakamoto avail += d->seq.size; 10031a4be183STakashi Sakamoto avail -= seq_index; 10041a4be183STakashi Sakamoto 10051a4be183STakashi Sakamoto if (avail < min_avail) 10061a4be183STakashi Sakamoto min_avail = avail; 10071a4be183STakashi Sakamoto } 10081a4be183STakashi Sakamoto 10091a4be183STakashi Sakamoto while (min_avail < packets) { 1010d32872f3STakashi Sakamoto struct seq_desc *desc = d->seq.descs + seq_tail; 10111a4be183STakashi Sakamoto 10121a4be183STakashi Sakamoto desc->syt_offset = calculate_syt_offset(&d->last_syt_offset, 10131a4be183STakashi Sakamoto &d->syt_offset_state, irq_target->sfc); 10141a4be183STakashi Sakamoto desc->data_blocks = calculate_data_blocks(&d->data_block_state, 10151a4be183STakashi Sakamoto !!(irq_target->flags & CIP_BLOCKING), 10161a4be183STakashi Sakamoto desc->syt_offset == CIP_SYT_NO_INFO, 10171a4be183STakashi Sakamoto irq_target->syt_interval, irq_target->sfc); 10181a4be183STakashi Sakamoto 10191a4be183STakashi Sakamoto ++seq_tail; 10201a4be183STakashi Sakamoto seq_tail %= seq_size; 10211a4be183STakashi Sakamoto 10221a4be183STakashi Sakamoto ++min_avail; 10231a4be183STakashi Sakamoto } 10241a4be183STakashi Sakamoto 1025d32872f3STakashi Sakamoto d->seq.tail = seq_tail; 10261a4be183STakashi Sakamoto } 10271a4be183STakashi Sakamoto 10282472cfb3STakashi Sakamoto static void irq_target_callback(struct fw_iso_context *context, u32 tstamp, 10292472cfb3STakashi Sakamoto size_t header_length, void *header, 10302472cfb3STakashi Sakamoto void *private_data) 103160dd4929STakashi Sakamoto { 10322472cfb3STakashi Sakamoto struct amdtp_stream *irq_target = private_data; 10332472cfb3STakashi Sakamoto struct amdtp_domain *d = irq_target->domain; 10341a4be183STakashi Sakamoto unsigned int packets = header_length / sizeof(__be32); 103560dd4929STakashi Sakamoto struct amdtp_stream *s; 103660dd4929STakashi Sakamoto 10371a4be183STakashi Sakamoto // Record enough entries with extra 3 cycles at least. 10381a4be183STakashi Sakamoto pool_ideal_seq_descs(d, packets + 3); 10391a4be183STakashi Sakamoto 104060dd4929STakashi Sakamoto out_stream_callback(context, tstamp, header_length, header, irq_target); 104160dd4929STakashi Sakamoto if (amdtp_streaming_error(irq_target)) 104260dd4929STakashi Sakamoto goto error; 104360dd4929STakashi Sakamoto 104460dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 104560dd4929STakashi Sakamoto if (s != irq_target && amdtp_stream_running(s)) { 104660dd4929STakashi Sakamoto fw_iso_context_flush_completions(s->context); 104760dd4929STakashi Sakamoto if (amdtp_streaming_error(s)) 104860dd4929STakashi Sakamoto goto error; 104960dd4929STakashi Sakamoto } 105060dd4929STakashi Sakamoto } 105160dd4929STakashi Sakamoto 105260dd4929STakashi Sakamoto return; 105360dd4929STakashi Sakamoto error: 105460dd4929STakashi Sakamoto if (amdtp_stream_running(irq_target)) 105560dd4929STakashi Sakamoto cancel_stream(irq_target); 105660dd4929STakashi Sakamoto 105760dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 105860dd4929STakashi Sakamoto if (amdtp_stream_running(s)) 105960dd4929STakashi Sakamoto cancel_stream(s); 106060dd4929STakashi Sakamoto } 106160dd4929STakashi Sakamoto } 106260dd4929STakashi Sakamoto 106360dd4929STakashi Sakamoto // this is executed one time. 1064d67c46b9STakashi Sakamoto static void amdtp_stream_first_callback(struct fw_iso_context *context, 106573fc7f08STakashi Sakamoto u32 tstamp, size_t header_length, 1066d67c46b9STakashi Sakamoto void *header, void *private_data) 1067d67c46b9STakashi Sakamoto { 1068d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 106926cd1e58STakashi Sakamoto const __be32 *ctx_header = header; 1070a04513f8STakashi Sakamoto u32 cycle; 1071d67c46b9STakashi Sakamoto 1072d67c46b9STakashi Sakamoto /* 1073d67c46b9STakashi Sakamoto * For in-stream, first packet has come. 1074d67c46b9STakashi Sakamoto * For out-stream, prepared to transmit first packet 1075d67c46b9STakashi Sakamoto */ 1076d67c46b9STakashi Sakamoto s->callbacked = true; 1077d67c46b9STakashi Sakamoto wake_up(&s->callback_wait); 1078d67c46b9STakashi Sakamoto 1079cc4f8e91STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 10803e106f4fSTakashi Sakamoto cycle = compute_ohci_cycle_count(ctx_header[1]); 1081705794c5STakashi Sakamoto s->next_cycle = cycle; 1082a04513f8STakashi Sakamoto 1083d67c46b9STakashi Sakamoto context->callback.sc = in_stream_callback; 1084a04513f8STakashi Sakamoto } else { 10853e106f4fSTakashi Sakamoto cycle = compute_ohci_it_cycle(*ctx_header, s->queue_size); 108626cd1e58STakashi Sakamoto 10872472cfb3STakashi Sakamoto if (s == s->domain->irq_target) 10882472cfb3STakashi Sakamoto context->callback.sc = irq_target_callback; 10892472cfb3STakashi Sakamoto else 1090d67c46b9STakashi Sakamoto context->callback.sc = out_stream_callback; 1091a04513f8STakashi Sakamoto } 1092a04513f8STakashi Sakamoto 1093a04513f8STakashi Sakamoto s->start_cycle = cycle; 1094d67c46b9STakashi Sakamoto 109573fc7f08STakashi Sakamoto context->callback.sc(context, tstamp, header_length, header, s); 1096d67c46b9STakashi Sakamoto } 1097d67c46b9STakashi Sakamoto 1098d67c46b9STakashi Sakamoto /** 1099d67c46b9STakashi Sakamoto * amdtp_stream_start - start transferring packets 1100d67c46b9STakashi Sakamoto * @s: the AMDTP stream to start 1101d67c46b9STakashi Sakamoto * @channel: the isochronous channel on the bus 1102d67c46b9STakashi Sakamoto * @speed: firewire speed code 1103acfedcbeSTakashi Sakamoto * @start_cycle: the isochronous cycle to start the context. Start immediately 1104acfedcbeSTakashi Sakamoto * if negative value is given. 1105af86b0b1STakashi Sakamoto * @queue_size: The number of packets in the queue. 1106af86b0b1STakashi Sakamoto * @idle_irq_interval: the interval to queue packet during initial state. 1107d67c46b9STakashi Sakamoto * 1108d67c46b9STakashi Sakamoto * The stream cannot be started until it has been configured with 1109d67c46b9STakashi Sakamoto * amdtp_stream_set_parameters() and it must be started before any PCM or MIDI 1110d67c46b9STakashi Sakamoto * device can be started. 1111d67c46b9STakashi Sakamoto */ 1112a0e02331STakashi Sakamoto static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed, 1113af86b0b1STakashi Sakamoto int start_cycle, unsigned int queue_size, 1114af86b0b1STakashi Sakamoto unsigned int idle_irq_interval) 1115d67c46b9STakashi Sakamoto { 11162472cfb3STakashi Sakamoto bool is_irq_target = (s == s->domain->irq_target); 1117d3d10a4aSTakashi Sakamoto unsigned int ctx_header_size; 1118f11453c7STakashi Sakamoto unsigned int max_ctx_payload_size; 1119d67c46b9STakashi Sakamoto enum dma_data_direction dir; 1120d67c46b9STakashi Sakamoto int type, tag, err; 1121d67c46b9STakashi Sakamoto 1122d67c46b9STakashi Sakamoto mutex_lock(&s->mutex); 1123d67c46b9STakashi Sakamoto 1124d67c46b9STakashi Sakamoto if (WARN_ON(amdtp_stream_running(s) || 1125d67c46b9STakashi Sakamoto (s->data_block_quadlets < 1))) { 1126d67c46b9STakashi Sakamoto err = -EBADFD; 1127d67c46b9STakashi Sakamoto goto err_unlock; 1128d67c46b9STakashi Sakamoto } 1129d67c46b9STakashi Sakamoto 1130d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 113160dd4929STakashi Sakamoto // NOTE: IT context should be used for constant IRQ. 113260dd4929STakashi Sakamoto if (is_irq_target) { 113360dd4929STakashi Sakamoto err = -EINVAL; 113460dd4929STakashi Sakamoto goto err_unlock; 113560dd4929STakashi Sakamoto } 113660dd4929STakashi Sakamoto 1137d67c46b9STakashi Sakamoto s->data_block_counter = UINT_MAX; 1138d3d10a4aSTakashi Sakamoto } else { 1139d67c46b9STakashi Sakamoto s->data_block_counter = 0; 1140d3d10a4aSTakashi Sakamoto } 1141d67c46b9STakashi Sakamoto 11421be4f21dSTakashi Sakamoto // initialize packet buffer. 11431be4f21dSTakashi Sakamoto max_ctx_payload_size = amdtp_stream_get_max_payload(s); 1144d67c46b9STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1145d67c46b9STakashi Sakamoto dir = DMA_FROM_DEVICE; 1146d67c46b9STakashi Sakamoto type = FW_ISO_CONTEXT_RECEIVE; 11471be4f21dSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) { 1148*67d92ee7STakashi Sakamoto max_ctx_payload_size -= CIP_HEADER_SIZE; 1149f11453c7STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_CIP; 11501be4f21dSTakashi Sakamoto } else { 1151f11453c7STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP; 11521be4f21dSTakashi Sakamoto } 1153d67c46b9STakashi Sakamoto } else { 1154d67c46b9STakashi Sakamoto dir = DMA_TO_DEVICE; 1155d67c46b9STakashi Sakamoto type = FW_ISO_CONTEXT_TRANSMIT; 1156df9160b9STakashi Sakamoto ctx_header_size = 0; // No effect for IT context. 1157f11453c7STakashi Sakamoto 1158b18f0cfaSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 1159b18f0cfaSTakashi Sakamoto max_ctx_payload_size -= IT_PKT_HEADER_SIZE_CIP; 1160b18f0cfaSTakashi Sakamoto } 1161f11453c7STakashi Sakamoto 1162af86b0b1STakashi Sakamoto err = iso_packets_buffer_init(&s->buffer, s->unit, queue_size, 1163f11453c7STakashi Sakamoto max_ctx_payload_size, dir); 1164d67c46b9STakashi Sakamoto if (err < 0) 1165d67c46b9STakashi Sakamoto goto err_unlock; 1166af86b0b1STakashi Sakamoto s->queue_size = queue_size; 116760dd4929STakashi Sakamoto 1168d67c46b9STakashi Sakamoto s->context = fw_iso_context_create(fw_parent_device(s->unit)->card, 1169d3d10a4aSTakashi Sakamoto type, channel, speed, ctx_header_size, 11702472cfb3STakashi Sakamoto amdtp_stream_first_callback, s); 1171d67c46b9STakashi Sakamoto if (IS_ERR(s->context)) { 1172d67c46b9STakashi Sakamoto err = PTR_ERR(s->context); 1173d67c46b9STakashi Sakamoto if (err == -EBUSY) 1174d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 1175d67c46b9STakashi Sakamoto "no free stream on this controller\n"); 1176d67c46b9STakashi Sakamoto goto err_buffer; 1177d67c46b9STakashi Sakamoto } 1178d67c46b9STakashi Sakamoto 1179d67c46b9STakashi Sakamoto amdtp_stream_update(s); 1180d67c46b9STakashi Sakamoto 1181d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1182f11453c7STakashi Sakamoto s->ctx_data.tx.max_ctx_payload_length = max_ctx_payload_size; 1183d3d10a4aSTakashi Sakamoto s->ctx_data.tx.ctx_header_size = ctx_header_size; 1184d3d10a4aSTakashi Sakamoto } 118552759c09STakashi Sakamoto 11863b196c39STakashi Sakamoto if (s->flags & CIP_NO_HEADER) 11873b196c39STakashi Sakamoto s->tag = TAG_NO_CIP_HEADER; 11883b196c39STakashi Sakamoto else 11893b196c39STakashi Sakamoto s->tag = TAG_CIP; 11903b196c39STakashi Sakamoto 1191a0e02331STakashi Sakamoto s->pkt_descs = kcalloc(s->queue_size, sizeof(*s->pkt_descs), 119204130cf8STakashi Sakamoto GFP_KERNEL); 119304130cf8STakashi Sakamoto if (!s->pkt_descs) { 119404130cf8STakashi Sakamoto err = -ENOMEM; 119504130cf8STakashi Sakamoto goto err_context; 119604130cf8STakashi Sakamoto } 119704130cf8STakashi Sakamoto 1198d67c46b9STakashi Sakamoto s->packet_index = 0; 1199d67c46b9STakashi Sakamoto do { 12006007bf54STakashi Sakamoto struct fw_iso_packet params; 1201e229853dSTakashi Sakamoto 1202b18f0cfaSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 120360dd4929STakashi Sakamoto err = queue_in_packet(s, ¶ms); 1204b18f0cfaSTakashi Sakamoto } else { 120560dd4929STakashi Sakamoto bool sched_irq = false; 120660dd4929STakashi Sakamoto 1207b18f0cfaSTakashi Sakamoto params.header_length = 0; 1208b18f0cfaSTakashi Sakamoto params.payload_length = 0; 120960dd4929STakashi Sakamoto 121060dd4929STakashi Sakamoto if (is_irq_target) { 121160dd4929STakashi Sakamoto sched_irq = !((s->packet_index + 1) % 121260dd4929STakashi Sakamoto idle_irq_interval); 121360dd4929STakashi Sakamoto } 121460dd4929STakashi Sakamoto 1215e229853dSTakashi Sakamoto err = queue_out_packet(s, ¶ms, sched_irq); 1216b18f0cfaSTakashi Sakamoto } 1217d67c46b9STakashi Sakamoto if (err < 0) 121804130cf8STakashi Sakamoto goto err_pkt_descs; 1219d67c46b9STakashi Sakamoto } while (s->packet_index > 0); 1220d67c46b9STakashi Sakamoto 1221d67c46b9STakashi Sakamoto /* NOTE: TAG1 matches CIP. This just affects in stream. */ 1222d67c46b9STakashi Sakamoto tag = FW_ISO_CONTEXT_MATCH_TAG1; 12233b196c39STakashi Sakamoto if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER)) 1224d67c46b9STakashi Sakamoto tag |= FW_ISO_CONTEXT_MATCH_TAG0; 1225d67c46b9STakashi Sakamoto 1226d67c46b9STakashi Sakamoto s->callbacked = false; 1227acfedcbeSTakashi Sakamoto err = fw_iso_context_start(s->context, start_cycle, 0, tag); 1228d67c46b9STakashi Sakamoto if (err < 0) 122904130cf8STakashi Sakamoto goto err_pkt_descs; 1230d67c46b9STakashi Sakamoto 1231d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1232d67c46b9STakashi Sakamoto 1233d67c46b9STakashi Sakamoto return 0; 123404130cf8STakashi Sakamoto err_pkt_descs: 123504130cf8STakashi Sakamoto kfree(s->pkt_descs); 1236d67c46b9STakashi Sakamoto err_context: 1237d67c46b9STakashi Sakamoto fw_iso_context_destroy(s->context); 1238d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 1239d67c46b9STakashi Sakamoto err_buffer: 1240d67c46b9STakashi Sakamoto iso_packets_buffer_destroy(&s->buffer, s->unit); 1241d67c46b9STakashi Sakamoto err_unlock: 1242d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1243d67c46b9STakashi Sakamoto 1244d67c46b9STakashi Sakamoto return err; 1245d67c46b9STakashi Sakamoto } 1246d67c46b9STakashi Sakamoto 1247d67c46b9STakashi Sakamoto /** 1248f890f9a0STakashi Sakamoto * amdtp_domain_stream_pcm_pointer - get the PCM buffer position 1249f890f9a0STakashi Sakamoto * @d: the AMDTP domain. 1250d67c46b9STakashi Sakamoto * @s: the AMDTP stream that transports the PCM data 1251d67c46b9STakashi Sakamoto * 1252d67c46b9STakashi Sakamoto * Returns the current buffer position, in frames. 1253d67c46b9STakashi Sakamoto */ 1254f890f9a0STakashi Sakamoto unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, 1255f890f9a0STakashi Sakamoto struct amdtp_stream *s) 1256d67c46b9STakashi Sakamoto { 1257f890f9a0STakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 1258f890f9a0STakashi Sakamoto 1259f890f9a0STakashi Sakamoto if (irq_target && amdtp_stream_running(irq_target)) { 1260f890f9a0STakashi Sakamoto // This function is called in software IRQ context of 12612b3d2987STakashi Iwai // period_work or process context. 1262f890f9a0STakashi Sakamoto // 1263f890f9a0STakashi Sakamoto // When the software IRQ context was scheduled by software IRQ 1264f890f9a0STakashi Sakamoto // context of IT contexts, queued packets were already handled. 1265f890f9a0STakashi Sakamoto // Therefore, no need to flush the queue in buffer furthermore. 1266f890f9a0STakashi Sakamoto // 1267f890f9a0STakashi Sakamoto // When the process context reach here, some packets will be 1268f890f9a0STakashi Sakamoto // already queued in the buffer. These packets should be handled 1269f890f9a0STakashi Sakamoto // immediately to keep better granularity of PCM pointer. 1270f890f9a0STakashi Sakamoto // 1271f890f9a0STakashi Sakamoto // Later, the process context will sometimes schedules software 12722b3d2987STakashi Iwai // IRQ context of the period_work. Then, no need to flush the 1273f890f9a0STakashi Sakamoto // queue by the same reason as described in the above 12742b3d2987STakashi Iwai if (current_work() != &s->period_work) { 1275f890f9a0STakashi Sakamoto // Queued packet should be processed without any kernel 1276f890f9a0STakashi Sakamoto // preemption to keep latency against bus cycle. 1277f890f9a0STakashi Sakamoto preempt_disable(); 1278f890f9a0STakashi Sakamoto fw_iso_context_flush_completions(irq_target->context); 1279f890f9a0STakashi Sakamoto preempt_enable(); 1280f890f9a0STakashi Sakamoto } 1281f890f9a0STakashi Sakamoto } 1282d67c46b9STakashi Sakamoto 12836aa7de05SMark Rutland return READ_ONCE(s->pcm_buffer_pointer); 1284d67c46b9STakashi Sakamoto } 1285f890f9a0STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stream_pcm_pointer); 1286d67c46b9STakashi Sakamoto 1287d67c46b9STakashi Sakamoto /** 1288e6dcc92fSTakashi Sakamoto * amdtp_domain_stream_pcm_ack - acknowledge queued PCM frames 1289e6dcc92fSTakashi Sakamoto * @d: the AMDTP domain. 1290875becf8STakashi Sakamoto * @s: the AMDTP stream that transfers the PCM frames 1291875becf8STakashi Sakamoto * 1292875becf8STakashi Sakamoto * Returns zero always. 1293875becf8STakashi Sakamoto */ 1294e6dcc92fSTakashi Sakamoto int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s) 1295875becf8STakashi Sakamoto { 1296e6dcc92fSTakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 1297e6dcc92fSTakashi Sakamoto 1298e6dcc92fSTakashi Sakamoto // Process isochronous packets for recent isochronous cycle to handle 1299e6dcc92fSTakashi Sakamoto // queued PCM frames. 1300e6dcc92fSTakashi Sakamoto if (irq_target && amdtp_stream_running(irq_target)) { 1301e6dcc92fSTakashi Sakamoto // Queued packet should be processed without any kernel 1302e6dcc92fSTakashi Sakamoto // preemption to keep latency against bus cycle. 1303e6dcc92fSTakashi Sakamoto preempt_disable(); 1304e6dcc92fSTakashi Sakamoto fw_iso_context_flush_completions(irq_target->context); 1305e6dcc92fSTakashi Sakamoto preempt_enable(); 1306e6dcc92fSTakashi Sakamoto } 1307875becf8STakashi Sakamoto 1308875becf8STakashi Sakamoto return 0; 1309875becf8STakashi Sakamoto } 1310e6dcc92fSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stream_pcm_ack); 1311875becf8STakashi Sakamoto 1312875becf8STakashi Sakamoto /** 1313d67c46b9STakashi Sakamoto * amdtp_stream_update - update the stream after a bus reset 1314d67c46b9STakashi Sakamoto * @s: the AMDTP stream 1315d67c46b9STakashi Sakamoto */ 1316d67c46b9STakashi Sakamoto void amdtp_stream_update(struct amdtp_stream *s) 1317d67c46b9STakashi Sakamoto { 1318d67c46b9STakashi Sakamoto /* Precomputing. */ 13196aa7de05SMark Rutland WRITE_ONCE(s->source_node_id_field, 13206aa7de05SMark Rutland (fw_parent_device(s->unit)->card->node_id << CIP_SID_SHIFT) & CIP_SID_MASK); 1321d67c46b9STakashi Sakamoto } 1322d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_update); 1323d67c46b9STakashi Sakamoto 1324d67c46b9STakashi Sakamoto /** 1325d67c46b9STakashi Sakamoto * amdtp_stream_stop - stop sending packets 1326d67c46b9STakashi Sakamoto * @s: the AMDTP stream to stop 1327d67c46b9STakashi Sakamoto * 1328d67c46b9STakashi Sakamoto * All PCM and MIDI devices of the stream must be stopped before the stream 1329d67c46b9STakashi Sakamoto * itself can be stopped. 1330d67c46b9STakashi Sakamoto */ 133174f94e41STakashi Sakamoto static void amdtp_stream_stop(struct amdtp_stream *s) 1332d67c46b9STakashi Sakamoto { 1333d67c46b9STakashi Sakamoto mutex_lock(&s->mutex); 1334d67c46b9STakashi Sakamoto 1335d67c46b9STakashi Sakamoto if (!amdtp_stream_running(s)) { 1336d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1337d67c46b9STakashi Sakamoto return; 1338d67c46b9STakashi Sakamoto } 1339d67c46b9STakashi Sakamoto 13402b3d2987STakashi Iwai cancel_work_sync(&s->period_work); 1341d67c46b9STakashi Sakamoto fw_iso_context_stop(s->context); 1342d67c46b9STakashi Sakamoto fw_iso_context_destroy(s->context); 1343d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 1344d67c46b9STakashi Sakamoto iso_packets_buffer_destroy(&s->buffer, s->unit); 134504130cf8STakashi Sakamoto kfree(s->pkt_descs); 1346d67c46b9STakashi Sakamoto 1347d67c46b9STakashi Sakamoto s->callbacked = false; 1348d67c46b9STakashi Sakamoto 1349d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1350d67c46b9STakashi Sakamoto } 1351d67c46b9STakashi Sakamoto 1352d67c46b9STakashi Sakamoto /** 1353d67c46b9STakashi Sakamoto * amdtp_stream_pcm_abort - abort the running PCM device 1354d67c46b9STakashi Sakamoto * @s: the AMDTP stream about to be stopped 1355d67c46b9STakashi Sakamoto * 1356d67c46b9STakashi Sakamoto * If the isochronous stream needs to be stopped asynchronously, call this 1357d67c46b9STakashi Sakamoto * function first to stop the PCM device. 1358d67c46b9STakashi Sakamoto */ 1359d67c46b9STakashi Sakamoto void amdtp_stream_pcm_abort(struct amdtp_stream *s) 1360d67c46b9STakashi Sakamoto { 1361d67c46b9STakashi Sakamoto struct snd_pcm_substream *pcm; 1362d67c46b9STakashi Sakamoto 13636aa7de05SMark Rutland pcm = READ_ONCE(s->pcm); 1364d67c46b9STakashi Sakamoto if (pcm) 1365d67c46b9STakashi Sakamoto snd_pcm_stop_xrun(pcm); 1366d67c46b9STakashi Sakamoto } 1367d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_pcm_abort); 13683ec3d7a3STakashi Sakamoto 13693ec3d7a3STakashi Sakamoto /** 13703ec3d7a3STakashi Sakamoto * amdtp_domain_init - initialize an AMDTP domain structure 13713ec3d7a3STakashi Sakamoto * @d: the AMDTP domain to initialize. 13723ec3d7a3STakashi Sakamoto */ 13733ec3d7a3STakashi Sakamoto int amdtp_domain_init(struct amdtp_domain *d) 13743ec3d7a3STakashi Sakamoto { 13753ec3d7a3STakashi Sakamoto INIT_LIST_HEAD(&d->streams); 13763ec3d7a3STakashi Sakamoto 1377d68c3123STakashi Sakamoto d->events_per_period = 0; 1378d68c3123STakashi Sakamoto 1379d32872f3STakashi Sakamoto d->seq.descs = NULL; 138025babf29STakashi Sakamoto 13813ec3d7a3STakashi Sakamoto return 0; 13823ec3d7a3STakashi Sakamoto } 13833ec3d7a3STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_init); 13843ec3d7a3STakashi Sakamoto 13853ec3d7a3STakashi Sakamoto /** 13863ec3d7a3STakashi Sakamoto * amdtp_domain_destroy - destroy an AMDTP domain structure 13873ec3d7a3STakashi Sakamoto * @d: the AMDTP domain to destroy. 13883ec3d7a3STakashi Sakamoto */ 13893ec3d7a3STakashi Sakamoto void amdtp_domain_destroy(struct amdtp_domain *d) 13903ec3d7a3STakashi Sakamoto { 13918d0d5c3fSTakashi Sakamoto // At present nothing to do. 13928d0d5c3fSTakashi Sakamoto return; 13933ec3d7a3STakashi Sakamoto } 13943ec3d7a3STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_destroy); 13956261f90bSTakashi Sakamoto 13966261f90bSTakashi Sakamoto /** 1397157a53eeSTakashi Sakamoto * amdtp_domain_add_stream - register isoc context into the domain. 1398157a53eeSTakashi Sakamoto * @d: the AMDTP domain. 1399157a53eeSTakashi Sakamoto * @s: the AMDTP stream. 1400157a53eeSTakashi Sakamoto * @channel: the isochronous channel on the bus. 1401157a53eeSTakashi Sakamoto * @speed: firewire speed code. 1402157a53eeSTakashi Sakamoto */ 1403157a53eeSTakashi Sakamoto int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, 1404157a53eeSTakashi Sakamoto int channel, int speed) 1405157a53eeSTakashi Sakamoto { 1406157a53eeSTakashi Sakamoto struct amdtp_stream *tmp; 1407157a53eeSTakashi Sakamoto 1408157a53eeSTakashi Sakamoto list_for_each_entry(tmp, &d->streams, list) { 1409157a53eeSTakashi Sakamoto if (s == tmp) 1410157a53eeSTakashi Sakamoto return -EBUSY; 1411157a53eeSTakashi Sakamoto } 1412157a53eeSTakashi Sakamoto 1413157a53eeSTakashi Sakamoto list_add(&s->list, &d->streams); 1414157a53eeSTakashi Sakamoto 1415157a53eeSTakashi Sakamoto s->channel = channel; 1416157a53eeSTakashi Sakamoto s->speed = speed; 14172472cfb3STakashi Sakamoto s->domain = d; 1418157a53eeSTakashi Sakamoto 1419157a53eeSTakashi Sakamoto return 0; 1420157a53eeSTakashi Sakamoto } 1421157a53eeSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_add_stream); 1422157a53eeSTakashi Sakamoto 1423acfedcbeSTakashi Sakamoto static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle) 1424acfedcbeSTakashi Sakamoto { 1425acfedcbeSTakashi Sakamoto int generation; 1426acfedcbeSTakashi Sakamoto int rcode; 1427acfedcbeSTakashi Sakamoto __be32 reg; 1428acfedcbeSTakashi Sakamoto u32 data; 1429acfedcbeSTakashi Sakamoto 1430acfedcbeSTakashi Sakamoto // This is a request to local 1394 OHCI controller and expected to 1431acfedcbeSTakashi Sakamoto // complete without any event waiting. 1432acfedcbeSTakashi Sakamoto generation = fw_card->generation; 1433acfedcbeSTakashi Sakamoto smp_rmb(); // node_id vs. generation. 1434acfedcbeSTakashi Sakamoto rcode = fw_run_transaction(fw_card, TCODE_READ_QUADLET_REQUEST, 1435acfedcbeSTakashi Sakamoto fw_card->node_id, generation, SCODE_100, 1436acfedcbeSTakashi Sakamoto CSR_REGISTER_BASE + CSR_CYCLE_TIME, 1437acfedcbeSTakashi Sakamoto ®, sizeof(reg)); 1438acfedcbeSTakashi Sakamoto if (rcode != RCODE_COMPLETE) 1439acfedcbeSTakashi Sakamoto return -EIO; 1440acfedcbeSTakashi Sakamoto 1441acfedcbeSTakashi Sakamoto data = be32_to_cpu(reg); 1442acfedcbeSTakashi Sakamoto *cur_cycle = data >> 12; 1443acfedcbeSTakashi Sakamoto 1444acfedcbeSTakashi Sakamoto return 0; 1445acfedcbeSTakashi Sakamoto } 1446acfedcbeSTakashi Sakamoto 1447157a53eeSTakashi Sakamoto /** 14489b4702b0STakashi Sakamoto * amdtp_domain_start - start sending packets for isoc context in the domain. 14499b4702b0STakashi Sakamoto * @d: the AMDTP domain. 1450acfedcbeSTakashi Sakamoto * @ir_delay_cycle: the cycle delay to start all IR contexts. 14519b4702b0STakashi Sakamoto */ 1452acfedcbeSTakashi Sakamoto int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) 14539b4702b0STakashi Sakamoto { 14541a4be183STakashi Sakamoto static const struct { 14551a4be183STakashi Sakamoto unsigned int data_block; 14561a4be183STakashi Sakamoto unsigned int syt_offset; 14571a4be183STakashi Sakamoto } *entry, initial_state[] = { 14581a4be183STakashi Sakamoto [CIP_SFC_32000] = { 4, 3072 }, 14591a4be183STakashi Sakamoto [CIP_SFC_48000] = { 6, 1024 }, 14601a4be183STakashi Sakamoto [CIP_SFC_96000] = { 12, 1024 }, 14611a4be183STakashi Sakamoto [CIP_SFC_192000] = { 24, 1024 }, 14621a4be183STakashi Sakamoto [CIP_SFC_44100] = { 0, 67 }, 14631a4be183STakashi Sakamoto [CIP_SFC_88200] = { 0, 67 }, 14641a4be183STakashi Sakamoto [CIP_SFC_176400] = { 0, 67 }, 14651a4be183STakashi Sakamoto }; 1466af86b0b1STakashi Sakamoto unsigned int events_per_buffer = d->events_per_buffer; 1467af86b0b1STakashi Sakamoto unsigned int events_per_period = d->events_per_period; 1468af86b0b1STakashi Sakamoto unsigned int idle_irq_interval; 1469af86b0b1STakashi Sakamoto unsigned int queue_size; 14709b4702b0STakashi Sakamoto struct amdtp_stream *s; 1471acfedcbeSTakashi Sakamoto int cycle; 1472acfedcbeSTakashi Sakamoto int err; 14739b4702b0STakashi Sakamoto 147460dd4929STakashi Sakamoto // Select an IT context as IRQ target. 14759b4702b0STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 147660dd4929STakashi Sakamoto if (s->direction == AMDTP_OUT_STREAM) 14779b4702b0STakashi Sakamoto break; 14789b4702b0STakashi Sakamoto } 147960dd4929STakashi Sakamoto if (!s) 148060dd4929STakashi Sakamoto return -ENXIO; 148160dd4929STakashi Sakamoto d->irq_target = s; 14829b4702b0STakashi Sakamoto 1483af86b0b1STakashi Sakamoto // This is a case that AMDTP streams in domain run just for MIDI 1484af86b0b1STakashi Sakamoto // substream. Use the number of events equivalent to 10 msec as 1485af86b0b1STakashi Sakamoto // interval of hardware IRQ. 1486af86b0b1STakashi Sakamoto if (events_per_period == 0) 1487af86b0b1STakashi Sakamoto events_per_period = amdtp_rate_table[d->irq_target->sfc] / 100; 1488af86b0b1STakashi Sakamoto if (events_per_buffer == 0) 1489af86b0b1STakashi Sakamoto events_per_buffer = events_per_period * 3; 1490af86b0b1STakashi Sakamoto 1491af86b0b1STakashi Sakamoto queue_size = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_buffer, 1492af86b0b1STakashi Sakamoto amdtp_rate_table[d->irq_target->sfc]); 1493af86b0b1STakashi Sakamoto 1494d32872f3STakashi Sakamoto d->seq.descs = kcalloc(queue_size, sizeof(*d->seq.descs), GFP_KERNEL); 1495d32872f3STakashi Sakamoto if (!d->seq.descs) 149625babf29STakashi Sakamoto return -ENOMEM; 1497d32872f3STakashi Sakamoto d->seq.size = queue_size; 1498d32872f3STakashi Sakamoto d->seq.tail = 0; 149925babf29STakashi Sakamoto 15001a4be183STakashi Sakamoto entry = &initial_state[s->sfc]; 15011a4be183STakashi Sakamoto d->data_block_state = entry->data_block; 15021a4be183STakashi Sakamoto d->syt_offset_state = entry->syt_offset; 15031a4be183STakashi Sakamoto d->last_syt_offset = TICKS_PER_CYCLE; 15041a4be183STakashi Sakamoto 1505acfedcbeSTakashi Sakamoto if (ir_delay_cycle > 0) { 1506acfedcbeSTakashi Sakamoto struct fw_card *fw_card = fw_parent_device(s->unit)->card; 1507acfedcbeSTakashi Sakamoto 1508acfedcbeSTakashi Sakamoto err = get_current_cycle_time(fw_card, &cycle); 1509acfedcbeSTakashi Sakamoto if (err < 0) 151025babf29STakashi Sakamoto goto error; 1511acfedcbeSTakashi Sakamoto 1512acfedcbeSTakashi Sakamoto // No need to care overflow in cycle field because of enough 1513acfedcbeSTakashi Sakamoto // width. 1514acfedcbeSTakashi Sakamoto cycle += ir_delay_cycle; 1515acfedcbeSTakashi Sakamoto 1516acfedcbeSTakashi Sakamoto // Round up to sec field. 1517acfedcbeSTakashi Sakamoto if ((cycle & 0x00001fff) >= CYCLES_PER_SECOND) { 1518acfedcbeSTakashi Sakamoto unsigned int sec; 1519acfedcbeSTakashi Sakamoto 1520acfedcbeSTakashi Sakamoto // The sec field can overflow. 1521acfedcbeSTakashi Sakamoto sec = (cycle & 0xffffe000) >> 13; 1522acfedcbeSTakashi Sakamoto cycle = (++sec << 13) | 1523acfedcbeSTakashi Sakamoto ((cycle & 0x00001fff) / CYCLES_PER_SECOND); 1524acfedcbeSTakashi Sakamoto } 1525acfedcbeSTakashi Sakamoto 1526acfedcbeSTakashi Sakamoto // In OHCI 1394 specification, lower 2 bits are available for 1527acfedcbeSTakashi Sakamoto // sec field. 1528acfedcbeSTakashi Sakamoto cycle &= 0x00007fff; 1529acfedcbeSTakashi Sakamoto } else { 1530acfedcbeSTakashi Sakamoto cycle = -1; 1531acfedcbeSTakashi Sakamoto } 1532acfedcbeSTakashi Sakamoto 153360dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 1534acfedcbeSTakashi Sakamoto int cycle_match; 1535acfedcbeSTakashi Sakamoto 1536acfedcbeSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1537acfedcbeSTakashi Sakamoto cycle_match = cycle; 1538acfedcbeSTakashi Sakamoto } else { 1539acfedcbeSTakashi Sakamoto // IT context starts immediately. 1540acfedcbeSTakashi Sakamoto cycle_match = -1; 15411a4be183STakashi Sakamoto s->ctx_data.rx.seq_index = 0; 1542acfedcbeSTakashi Sakamoto } 1543acfedcbeSTakashi Sakamoto 154460dd4929STakashi Sakamoto if (s != d->irq_target) { 15452472cfb3STakashi Sakamoto err = amdtp_stream_start(s, s->channel, s->speed, 1546af86b0b1STakashi Sakamoto cycle_match, queue_size, 0); 154760dd4929STakashi Sakamoto if (err < 0) 154860dd4929STakashi Sakamoto goto error; 154960dd4929STakashi Sakamoto } 15509b4702b0STakashi Sakamoto } 15519b4702b0STakashi Sakamoto 155260dd4929STakashi Sakamoto s = d->irq_target; 1553af86b0b1STakashi Sakamoto s->ctx_data.rx.event_count = 0; 15541a4be183STakashi Sakamoto s->ctx_data.rx.seq_index = 0; 1555af86b0b1STakashi Sakamoto 1556af86b0b1STakashi Sakamoto idle_irq_interval = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_period, 1557af86b0b1STakashi Sakamoto amdtp_rate_table[d->irq_target->sfc]); 1558af86b0b1STakashi Sakamoto err = amdtp_stream_start(s, s->channel, s->speed, -1, queue_size, 1559af86b0b1STakashi Sakamoto idle_irq_interval); 156060dd4929STakashi Sakamoto if (err < 0) 156160dd4929STakashi Sakamoto goto error; 156260dd4929STakashi Sakamoto 156360dd4929STakashi Sakamoto return 0; 156460dd4929STakashi Sakamoto error: 156560dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) 156660dd4929STakashi Sakamoto amdtp_stream_stop(s); 1567d32872f3STakashi Sakamoto kfree(d->seq.descs); 1568d32872f3STakashi Sakamoto d->seq.descs = NULL; 15699b4702b0STakashi Sakamoto return err; 15709b4702b0STakashi Sakamoto } 15719b4702b0STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_start); 15729b4702b0STakashi Sakamoto 15739b4702b0STakashi Sakamoto /** 15746261f90bSTakashi Sakamoto * amdtp_domain_stop - stop sending packets for isoc context in the same domain. 15756261f90bSTakashi Sakamoto * @d: the AMDTP domain to which the isoc contexts belong. 15766261f90bSTakashi Sakamoto */ 15776261f90bSTakashi Sakamoto void amdtp_domain_stop(struct amdtp_domain *d) 15786261f90bSTakashi Sakamoto { 15796261f90bSTakashi Sakamoto struct amdtp_stream *s, *next; 15806261f90bSTakashi Sakamoto 158160dd4929STakashi Sakamoto if (d->irq_target) 158260dd4929STakashi Sakamoto amdtp_stream_stop(d->irq_target); 158360dd4929STakashi Sakamoto 15846261f90bSTakashi Sakamoto list_for_each_entry_safe(s, next, &d->streams, list) { 15856261f90bSTakashi Sakamoto list_del(&s->list); 15866261f90bSTakashi Sakamoto 158760dd4929STakashi Sakamoto if (s != d->irq_target) 15886261f90bSTakashi Sakamoto amdtp_stream_stop(s); 15896261f90bSTakashi Sakamoto } 1590d68c3123STakashi Sakamoto 1591d68c3123STakashi Sakamoto d->events_per_period = 0; 159260dd4929STakashi Sakamoto d->irq_target = NULL; 159325babf29STakashi Sakamoto 1594d32872f3STakashi Sakamoto kfree(d->seq.descs); 1595d32872f3STakashi Sakamoto d->seq.descs = NULL; 15966261f90bSTakashi Sakamoto } 15976261f90bSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stop); 1598