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 2310aa8e4aSTakashi Sakamoto #define OHCI_MAX_SECOND 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 36d67c46b9STakashi Sakamoto /* common isochronous packet header parameters */ 37d67c46b9STakashi Sakamoto #define CIP_EOH_SHIFT 31 38d67c46b9STakashi Sakamoto #define CIP_EOH (1u << CIP_EOH_SHIFT) 39d67c46b9STakashi Sakamoto #define CIP_EOH_MASK 0x80000000 40d67c46b9STakashi Sakamoto #define CIP_SID_SHIFT 24 41d67c46b9STakashi Sakamoto #define CIP_SID_MASK 0x3f000000 42d67c46b9STakashi Sakamoto #define CIP_DBS_MASK 0x00ff0000 43d67c46b9STakashi Sakamoto #define CIP_DBS_SHIFT 16 449863874fSTakashi Sakamoto #define CIP_SPH_MASK 0x00000400 459863874fSTakashi Sakamoto #define CIP_SPH_SHIFT 10 46d67c46b9STakashi Sakamoto #define CIP_DBC_MASK 0x000000ff 47d67c46b9STakashi Sakamoto #define CIP_FMT_SHIFT 24 48d67c46b9STakashi Sakamoto #define CIP_FMT_MASK 0x3f000000 49d67c46b9STakashi Sakamoto #define CIP_FDF_MASK 0x00ff0000 50d67c46b9STakashi Sakamoto #define CIP_FDF_SHIFT 16 51d67c46b9STakashi Sakamoto #define CIP_SYT_MASK 0x0000ffff 52d67c46b9STakashi Sakamoto #define CIP_SYT_NO_INFO 0xffff 53d67c46b9STakashi Sakamoto 5451c29fd2STakashi Sakamoto /* Audio and Music transfer protocol specific parameters */ 55d67c46b9STakashi Sakamoto #define CIP_FMT_AM 0x10 56d67c46b9STakashi Sakamoto #define AMDTP_FDF_NO_DATA 0xff 57d67c46b9STakashi Sakamoto 58f11453c7STakashi Sakamoto // For iso header, tstamp and 2 CIP header. 59f11453c7STakashi Sakamoto #define IR_CTX_HEADER_SIZE_CIP 16 60f11453c7STakashi Sakamoto // For iso header and tstamp. 61f11453c7STakashi Sakamoto #define IR_CTX_HEADER_SIZE_NO_CIP 8 62cc4f8e91STakashi Sakamoto #define HEADER_TSTAMP_MASK 0x0000ffff 63d67c46b9STakashi Sakamoto 64b18f0cfaSTakashi Sakamoto #define IT_PKT_HEADER_SIZE_CIP 8 // For 2 CIP header. 65b18f0cfaSTakashi Sakamoto #define IT_PKT_HEADER_SIZE_NO_CIP 0 // Nothing. 66b18f0cfaSTakashi Sakamoto 676a3ce97dSTakashi Sakamoto // The initial firmware of OXFW970 can postpone transmission of packet during finishing 686a3ce97dSTakashi Sakamoto // asynchronous transaction. This module accepts 5 cycles to skip as maximum to avoid buffer 696a3ce97dSTakashi Sakamoto // overrun. Actual device can skip more, then this module stops the packet streaming. 706a3ce97dSTakashi Sakamoto #define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5 716a3ce97dSTakashi Sakamoto 722b3d2987STakashi Iwai static void pcm_period_work(struct work_struct *work); 73d67c46b9STakashi Sakamoto 74d67c46b9STakashi Sakamoto /** 75d67c46b9STakashi Sakamoto * amdtp_stream_init - initialize an AMDTP stream structure 76d67c46b9STakashi Sakamoto * @s: the AMDTP stream to initialize 77d67c46b9STakashi Sakamoto * @unit: the target of the stream 78d67c46b9STakashi Sakamoto * @dir: the direction of stream 79ffe66bbeSTakashi Sakamoto * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants. 805955815eSTakashi Sakamoto * @fmt: the value of fmt field in CIP header 819a738ad1STakashi Sakamoto * @process_ctx_payloads: callback handler to process payloads of isoc context 82df075feeSTakashi Sakamoto * @protocol_size: the size to allocate newly for protocol 83d67c46b9STakashi Sakamoto */ 84d67c46b9STakashi Sakamoto int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 85ffe66bbeSTakashi Sakamoto enum amdtp_stream_direction dir, unsigned int flags, 86df075feeSTakashi Sakamoto unsigned int fmt, 879a738ad1STakashi Sakamoto amdtp_stream_process_ctx_payloads_t process_ctx_payloads, 88df075feeSTakashi Sakamoto unsigned int protocol_size) 89d67c46b9STakashi Sakamoto { 909a738ad1STakashi Sakamoto if (process_ctx_payloads == NULL) 91df075feeSTakashi Sakamoto return -EINVAL; 92df075feeSTakashi Sakamoto 93df075feeSTakashi Sakamoto s->protocol = kzalloc(protocol_size, GFP_KERNEL); 94df075feeSTakashi Sakamoto if (!s->protocol) 95df075feeSTakashi Sakamoto return -ENOMEM; 96df075feeSTakashi Sakamoto 97d67c46b9STakashi Sakamoto s->unit = unit; 98d67c46b9STakashi Sakamoto s->direction = dir; 99d67c46b9STakashi Sakamoto s->flags = flags; 100d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 101d67c46b9STakashi Sakamoto mutex_init(&s->mutex); 1022b3d2987STakashi Iwai INIT_WORK(&s->period_work, pcm_period_work); 103d67c46b9STakashi Sakamoto s->packet_index = 0; 104d67c46b9STakashi Sakamoto 105d67c46b9STakashi Sakamoto init_waitqueue_head(&s->callback_wait); 106d67c46b9STakashi Sakamoto s->callbacked = false; 107d67c46b9STakashi Sakamoto 1085955815eSTakashi Sakamoto s->fmt = fmt; 1099a738ad1STakashi Sakamoto s->process_ctx_payloads = process_ctx_payloads; 110d67c46b9STakashi Sakamoto 1113baf3053STakashi Sakamoto if (dir == AMDTP_OUT_STREAM) 1123baf3053STakashi Sakamoto s->ctx_data.rx.syt_override = -1; 1133baf3053STakashi Sakamoto 114d67c46b9STakashi Sakamoto return 0; 115d67c46b9STakashi Sakamoto } 116d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_init); 117d67c46b9STakashi Sakamoto 118d67c46b9STakashi Sakamoto /** 119d67c46b9STakashi Sakamoto * amdtp_stream_destroy - free stream resources 120d67c46b9STakashi Sakamoto * @s: the AMDTP stream to destroy 121d67c46b9STakashi Sakamoto */ 122d67c46b9STakashi Sakamoto void amdtp_stream_destroy(struct amdtp_stream *s) 123d67c46b9STakashi Sakamoto { 12444c376b9STakashi Sakamoto /* Not initialized. */ 12544c376b9STakashi Sakamoto if (s->protocol == NULL) 12644c376b9STakashi Sakamoto return; 12744c376b9STakashi Sakamoto 128d67c46b9STakashi Sakamoto WARN_ON(amdtp_stream_running(s)); 129df075feeSTakashi Sakamoto kfree(s->protocol); 130d67c46b9STakashi Sakamoto mutex_destroy(&s->mutex); 131d67c46b9STakashi Sakamoto } 132d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_destroy); 133d67c46b9STakashi Sakamoto 134d67c46b9STakashi Sakamoto const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT] = { 135d67c46b9STakashi Sakamoto [CIP_SFC_32000] = 8, 136d67c46b9STakashi Sakamoto [CIP_SFC_44100] = 8, 137d67c46b9STakashi Sakamoto [CIP_SFC_48000] = 8, 138d67c46b9STakashi Sakamoto [CIP_SFC_88200] = 16, 139d67c46b9STakashi Sakamoto [CIP_SFC_96000] = 16, 140d67c46b9STakashi Sakamoto [CIP_SFC_176400] = 32, 141d67c46b9STakashi Sakamoto [CIP_SFC_192000] = 32, 142d67c46b9STakashi Sakamoto }; 143d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_syt_intervals); 144d67c46b9STakashi Sakamoto 145d67c46b9STakashi Sakamoto const unsigned int amdtp_rate_table[CIP_SFC_COUNT] = { 146d67c46b9STakashi Sakamoto [CIP_SFC_32000] = 32000, 147d67c46b9STakashi Sakamoto [CIP_SFC_44100] = 44100, 148d67c46b9STakashi Sakamoto [CIP_SFC_48000] = 48000, 149d67c46b9STakashi Sakamoto [CIP_SFC_88200] = 88200, 150d67c46b9STakashi Sakamoto [CIP_SFC_96000] = 96000, 151d67c46b9STakashi Sakamoto [CIP_SFC_176400] = 176400, 152d67c46b9STakashi Sakamoto [CIP_SFC_192000] = 192000, 153d67c46b9STakashi Sakamoto }; 154d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_rate_table); 155d67c46b9STakashi Sakamoto 15659502295STakashi Sakamoto static int apply_constraint_to_size(struct snd_pcm_hw_params *params, 15759502295STakashi Sakamoto struct snd_pcm_hw_rule *rule) 15859502295STakashi Sakamoto { 15959502295STakashi Sakamoto struct snd_interval *s = hw_param_interval(params, rule->var); 16059502295STakashi Sakamoto const struct snd_interval *r = 16159502295STakashi Sakamoto hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 162826b5de9STakashi Sakamoto struct snd_interval t = {0}; 163826b5de9STakashi Sakamoto unsigned int step = 0; 16459502295STakashi Sakamoto int i; 16559502295STakashi Sakamoto 16659502295STakashi Sakamoto for (i = 0; i < CIP_SFC_COUNT; ++i) { 167826b5de9STakashi Sakamoto if (snd_interval_test(r, amdtp_rate_table[i])) 168826b5de9STakashi Sakamoto step = max(step, amdtp_syt_intervals[i]); 16959502295STakashi Sakamoto } 17059502295STakashi Sakamoto 171826b5de9STakashi Sakamoto t.min = roundup(s->min, step); 172826b5de9STakashi Sakamoto t.max = rounddown(s->max, step); 173826b5de9STakashi Sakamoto t.integer = 1; 17459502295STakashi Sakamoto 17559502295STakashi Sakamoto return snd_interval_refine(s, &t); 17659502295STakashi Sakamoto } 17759502295STakashi Sakamoto 178d67c46b9STakashi Sakamoto /** 179d67c46b9STakashi Sakamoto * amdtp_stream_add_pcm_hw_constraints - add hw constraints for PCM substream 180d67c46b9STakashi Sakamoto * @s: the AMDTP stream, which must be initialized. 181d67c46b9STakashi Sakamoto * @runtime: the PCM substream runtime 182d67c46b9STakashi Sakamoto */ 183d67c46b9STakashi Sakamoto int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, 184d67c46b9STakashi Sakamoto struct snd_pcm_runtime *runtime) 185d67c46b9STakashi Sakamoto { 18655799c5aSTakashi Sakamoto struct snd_pcm_hardware *hw = &runtime->hw; 18799921ec6STakashi Sakamoto unsigned int ctx_header_size; 18899921ec6STakashi Sakamoto unsigned int maximum_usec_per_period; 189d67c46b9STakashi Sakamoto int err; 190d67c46b9STakashi Sakamoto 19155799c5aSTakashi Sakamoto hw->info = SNDRV_PCM_INFO_BATCH | 19255799c5aSTakashi Sakamoto SNDRV_PCM_INFO_BLOCK_TRANSFER | 19355799c5aSTakashi Sakamoto SNDRV_PCM_INFO_INTERLEAVED | 19455799c5aSTakashi Sakamoto SNDRV_PCM_INFO_JOINT_DUPLEX | 19555799c5aSTakashi Sakamoto SNDRV_PCM_INFO_MMAP | 19655799c5aSTakashi Sakamoto SNDRV_PCM_INFO_MMAP_VALID; 19755799c5aSTakashi Sakamoto 19855799c5aSTakashi Sakamoto /* SNDRV_PCM_INFO_BATCH */ 19955799c5aSTakashi Sakamoto hw->periods_min = 2; 20055799c5aSTakashi Sakamoto hw->periods_max = UINT_MAX; 20155799c5aSTakashi Sakamoto 20255799c5aSTakashi Sakamoto /* bytes for a frame */ 20355799c5aSTakashi Sakamoto hw->period_bytes_min = 4 * hw->channels_max; 20455799c5aSTakashi Sakamoto 20555799c5aSTakashi Sakamoto /* Just to prevent from allocating much pages. */ 20655799c5aSTakashi Sakamoto hw->period_bytes_max = hw->period_bytes_min * 2048; 20755799c5aSTakashi Sakamoto hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 20855799c5aSTakashi Sakamoto 20999921ec6STakashi Sakamoto // Linux driver for 1394 OHCI controller voluntarily flushes isoc 21099921ec6STakashi Sakamoto // context when total size of accumulated context header reaches 2112b3d2987STakashi Iwai // PAGE_SIZE. This kicks work for the isoc context and brings 21299921ec6STakashi Sakamoto // callback in the middle of scheduled interrupts. 21399921ec6STakashi Sakamoto // Although AMDTP streams in the same domain use the same events per 21499921ec6STakashi Sakamoto // IRQ, use the largest size of context header between IT/IR contexts. 21599921ec6STakashi Sakamoto // Here, use the value of context header in IR context is for both 21699921ec6STakashi Sakamoto // contexts. 21799921ec6STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 21899921ec6STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_CIP; 21999921ec6STakashi Sakamoto else 22099921ec6STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP; 22199921ec6STakashi Sakamoto maximum_usec_per_period = USEC_PER_SEC * PAGE_SIZE / 22299921ec6STakashi Sakamoto CYCLES_PER_SECOND / ctx_header_size; 22399921ec6STakashi Sakamoto 224f706df4fSTakashi Sakamoto // In IEC 61883-6, one isoc packet can transfer events up to the value 225f706df4fSTakashi Sakamoto // of syt interval. This comes from the interval of isoc cycle. As 1394 226f706df4fSTakashi Sakamoto // OHCI controller can generate hardware IRQ per isoc packet, the 227f706df4fSTakashi Sakamoto // interval is 125 usec. 228f706df4fSTakashi Sakamoto // However, there are two ways of transmission in IEC 61883-6; blocking 229f706df4fSTakashi Sakamoto // and non-blocking modes. In blocking mode, the sequence of isoc packet 230f706df4fSTakashi Sakamoto // includes 'empty' or 'NODATA' packets which include no event. In 231f706df4fSTakashi Sakamoto // non-blocking mode, the number of events per packet is variable up to 232f706df4fSTakashi Sakamoto // the syt interval. 233f706df4fSTakashi Sakamoto // Due to the above protocol design, the minimum PCM frames per 234f706df4fSTakashi Sakamoto // interrupt should be double of the value of syt interval, thus it is 235f706df4fSTakashi Sakamoto // 250 usec. 236d67c46b9STakashi Sakamoto err = snd_pcm_hw_constraint_minmax(runtime, 237d67c46b9STakashi Sakamoto SNDRV_PCM_HW_PARAM_PERIOD_TIME, 238f706df4fSTakashi Sakamoto 250, maximum_usec_per_period); 239d67c46b9STakashi Sakamoto if (err < 0) 240d67c46b9STakashi Sakamoto goto end; 241d67c46b9STakashi Sakamoto 242d67c46b9STakashi Sakamoto /* Non-Blocking stream has no more constraints */ 243d67c46b9STakashi Sakamoto if (!(s->flags & CIP_BLOCKING)) 244d67c46b9STakashi Sakamoto goto end; 245d67c46b9STakashi Sakamoto 246d67c46b9STakashi Sakamoto /* 247d67c46b9STakashi Sakamoto * One AMDTP packet can include some frames. In blocking mode, the 248d67c46b9STakashi Sakamoto * number equals to SYT_INTERVAL. So the number is 8, 16 or 32, 249d67c46b9STakashi Sakamoto * depending on its sampling rate. For accurate period interrupt, it's 250d67c46b9STakashi Sakamoto * preferrable to align period/buffer sizes to current SYT_INTERVAL. 251d67c46b9STakashi Sakamoto */ 25259502295STakashi Sakamoto err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 25359502295STakashi Sakamoto apply_constraint_to_size, NULL, 254826b5de9STakashi Sakamoto SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 25559502295STakashi Sakamoto SNDRV_PCM_HW_PARAM_RATE, -1); 256d67c46b9STakashi Sakamoto if (err < 0) 257d67c46b9STakashi Sakamoto goto end; 25859502295STakashi Sakamoto err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 25959502295STakashi Sakamoto apply_constraint_to_size, NULL, 260826b5de9STakashi Sakamoto SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 26159502295STakashi Sakamoto SNDRV_PCM_HW_PARAM_RATE, -1); 26259502295STakashi Sakamoto if (err < 0) 26359502295STakashi Sakamoto goto end; 264d67c46b9STakashi Sakamoto end: 265d67c46b9STakashi Sakamoto return err; 266d67c46b9STakashi Sakamoto } 267d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints); 268d67c46b9STakashi Sakamoto 269d67c46b9STakashi Sakamoto /** 270d67c46b9STakashi Sakamoto * amdtp_stream_set_parameters - set stream parameters 271d67c46b9STakashi Sakamoto * @s: the AMDTP stream to configure 272d67c46b9STakashi Sakamoto * @rate: the sample rate 273df075feeSTakashi Sakamoto * @data_block_quadlets: the size of a data block in quadlet unit 274d67c46b9STakashi Sakamoto * 275d67c46b9STakashi Sakamoto * The parameters must be set before the stream is started, and must not be 276d67c46b9STakashi Sakamoto * changed while the stream is running. 277d67c46b9STakashi Sakamoto */ 278df075feeSTakashi Sakamoto int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate, 279df075feeSTakashi Sakamoto unsigned int data_block_quadlets) 280d67c46b9STakashi Sakamoto { 281df075feeSTakashi Sakamoto unsigned int sfc; 282d67c46b9STakashi Sakamoto 283d67c46b9STakashi Sakamoto for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) { 284d67c46b9STakashi Sakamoto if (amdtp_rate_table[sfc] == rate) 285d67c46b9STakashi Sakamoto break; 286d67c46b9STakashi Sakamoto } 287d67c46b9STakashi Sakamoto if (sfc == ARRAY_SIZE(amdtp_rate_table)) 288d67c46b9STakashi Sakamoto return -EINVAL; 289d67c46b9STakashi Sakamoto 290d67c46b9STakashi Sakamoto s->sfc = sfc; 291df075feeSTakashi Sakamoto s->data_block_quadlets = data_block_quadlets; 292d67c46b9STakashi Sakamoto s->syt_interval = amdtp_syt_intervals[sfc]; 293d67c46b9STakashi Sakamoto 294d3d10a4aSTakashi Sakamoto // default buffering in the device. 295d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_OUT_STREAM) { 296d3d10a4aSTakashi Sakamoto s->ctx_data.rx.transfer_delay = 297d3d10a4aSTakashi Sakamoto TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE; 298d3d10a4aSTakashi Sakamoto 299d3d10a4aSTakashi Sakamoto if (s->flags & CIP_BLOCKING) { 300d3d10a4aSTakashi Sakamoto // additional buffering needed to adjust for no-data 301d3d10a4aSTakashi Sakamoto // packets. 302d3d10a4aSTakashi Sakamoto s->ctx_data.rx.transfer_delay += 303d3d10a4aSTakashi Sakamoto TICKS_PER_SECOND * s->syt_interval / rate; 304d3d10a4aSTakashi Sakamoto } 305d3d10a4aSTakashi Sakamoto } 306d67c46b9STakashi Sakamoto 307d67c46b9STakashi Sakamoto return 0; 308d67c46b9STakashi Sakamoto } 309d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_set_parameters); 310d67c46b9STakashi Sakamoto 311d67c46b9STakashi Sakamoto /** 312d67c46b9STakashi Sakamoto * amdtp_stream_get_max_payload - get the stream's packet size 313d67c46b9STakashi Sakamoto * @s: the AMDTP stream 314d67c46b9STakashi Sakamoto * 315d67c46b9STakashi Sakamoto * This function must not be called before the stream has been configured 316d67c46b9STakashi Sakamoto * with amdtp_stream_set_parameters(). 317d67c46b9STakashi Sakamoto */ 318d67c46b9STakashi Sakamoto unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 319d67c46b9STakashi Sakamoto { 320d67c46b9STakashi Sakamoto unsigned int multiplier = 1; 32107ea238cSTakashi Sakamoto unsigned int cip_header_size = 0; 322d67c46b9STakashi Sakamoto 323d67c46b9STakashi Sakamoto if (s->flags & CIP_JUMBO_PAYLOAD) 3246a3ce97dSTakashi Sakamoto multiplier = IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES; 3253b196c39STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 32607ea238cSTakashi Sakamoto cip_header_size = sizeof(__be32) * 2; 327d67c46b9STakashi Sakamoto 32807ea238cSTakashi Sakamoto return cip_header_size + 32907ea238cSTakashi Sakamoto s->syt_interval * s->data_block_quadlets * sizeof(__be32) * multiplier; 330d67c46b9STakashi Sakamoto } 331d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_get_max_payload); 332d67c46b9STakashi Sakamoto 333d67c46b9STakashi Sakamoto /** 334d67c46b9STakashi Sakamoto * amdtp_stream_pcm_prepare - prepare PCM device for running 335d67c46b9STakashi Sakamoto * @s: the AMDTP stream 336d67c46b9STakashi Sakamoto * 337d67c46b9STakashi Sakamoto * This function should be called from the PCM device's .prepare callback. 338d67c46b9STakashi Sakamoto */ 339d67c46b9STakashi Sakamoto void amdtp_stream_pcm_prepare(struct amdtp_stream *s) 340d67c46b9STakashi Sakamoto { 3412b3d2987STakashi Iwai cancel_work_sync(&s->period_work); 342d67c46b9STakashi Sakamoto s->pcm_buffer_pointer = 0; 343d67c46b9STakashi Sakamoto s->pcm_period_pointer = 0; 344d67c46b9STakashi Sakamoto } 345d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_pcm_prepare); 346d67c46b9STakashi Sakamoto 347274fc355STakashi Sakamoto static unsigned int calculate_data_blocks(unsigned int *data_block_state, 348274fc355STakashi Sakamoto bool is_blocking, bool is_no_info, 349274fc355STakashi Sakamoto unsigned int syt_interval, enum cip_sfc sfc) 350d67c46b9STakashi Sakamoto { 351274fc355STakashi Sakamoto unsigned int data_blocks; 352d67c46b9STakashi Sakamoto 353d67c46b9STakashi Sakamoto /* Blocking mode. */ 354274fc355STakashi Sakamoto if (is_blocking) { 355d67c46b9STakashi Sakamoto /* This module generate empty packet for 'no data'. */ 356274fc355STakashi Sakamoto if (is_no_info) 357d67c46b9STakashi Sakamoto data_blocks = 0; 358d67c46b9STakashi Sakamoto else 359274fc355STakashi Sakamoto data_blocks = syt_interval; 360d67c46b9STakashi Sakamoto /* Non-blocking mode. */ 361d67c46b9STakashi Sakamoto } else { 362274fc355STakashi Sakamoto if (!cip_sfc_is_base_44100(sfc)) { 363d3d10a4aSTakashi Sakamoto // Sample_rate / 8000 is an integer, and precomputed. 364274fc355STakashi Sakamoto data_blocks = *data_block_state; 365d67c46b9STakashi Sakamoto } else { 366274fc355STakashi Sakamoto unsigned int phase = *data_block_state; 367d67c46b9STakashi Sakamoto 368d67c46b9STakashi Sakamoto /* 369d67c46b9STakashi Sakamoto * This calculates the number of data blocks per packet so that 370d67c46b9STakashi Sakamoto * 1) the overall rate is correct and exactly synchronized to 371d67c46b9STakashi Sakamoto * the bus clock, and 372d67c46b9STakashi Sakamoto * 2) packets with a rounded-up number of blocks occur as early 373d67c46b9STakashi Sakamoto * as possible in the sequence (to prevent underruns of the 374d67c46b9STakashi Sakamoto * device's buffer). 375d67c46b9STakashi Sakamoto */ 376274fc355STakashi Sakamoto if (sfc == CIP_SFC_44100) 377d67c46b9STakashi Sakamoto /* 6 6 5 6 5 6 5 ... */ 378d67c46b9STakashi Sakamoto data_blocks = 5 + ((phase & 1) ^ 379d67c46b9STakashi Sakamoto (phase == 0 || phase >= 40)); 380d67c46b9STakashi Sakamoto else 381d67c46b9STakashi Sakamoto /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */ 382274fc355STakashi Sakamoto data_blocks = 11 * (sfc >> 1) + (phase == 0); 383274fc355STakashi Sakamoto if (++phase >= (80 >> (sfc >> 1))) 384d67c46b9STakashi Sakamoto phase = 0; 385274fc355STakashi Sakamoto *data_block_state = phase; 386d67c46b9STakashi Sakamoto } 387d67c46b9STakashi Sakamoto } 388d67c46b9STakashi Sakamoto 389d67c46b9STakashi Sakamoto return data_blocks; 390d67c46b9STakashi Sakamoto } 391d67c46b9STakashi Sakamoto 392816d8482STakashi Sakamoto static unsigned int calculate_syt_offset(unsigned int *last_syt_offset, 393816d8482STakashi Sakamoto unsigned int *syt_offset_state, enum cip_sfc sfc) 394d67c46b9STakashi Sakamoto { 395816d8482STakashi Sakamoto unsigned int syt_offset; 396d67c46b9STakashi Sakamoto 397816d8482STakashi Sakamoto if (*last_syt_offset < TICKS_PER_CYCLE) { 398816d8482STakashi Sakamoto if (!cip_sfc_is_base_44100(sfc)) 399816d8482STakashi Sakamoto syt_offset = *last_syt_offset + *syt_offset_state; 400d67c46b9STakashi Sakamoto else { 401d67c46b9STakashi Sakamoto /* 402d67c46b9STakashi Sakamoto * The time, in ticks, of the n'th SYT_INTERVAL sample is: 403d67c46b9STakashi Sakamoto * n * SYT_INTERVAL * 24576000 / sample_rate 404d67c46b9STakashi Sakamoto * Modulo TICKS_PER_CYCLE, the difference between successive 405d67c46b9STakashi Sakamoto * elements is about 1386.23. Rounding the results of this 406d67c46b9STakashi Sakamoto * formula to the SYT precision results in a sequence of 407d67c46b9STakashi Sakamoto * differences that begins with: 408d67c46b9STakashi Sakamoto * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ... 409d67c46b9STakashi Sakamoto * This code generates _exactly_ the same sequence. 410d67c46b9STakashi Sakamoto */ 411816d8482STakashi Sakamoto unsigned int phase = *syt_offset_state; 412816d8482STakashi Sakamoto unsigned int index = phase % 13; 413816d8482STakashi Sakamoto 414816d8482STakashi Sakamoto syt_offset = *last_syt_offset; 415d67c46b9STakashi Sakamoto syt_offset += 1386 + ((index && !(index & 3)) || 416d67c46b9STakashi Sakamoto phase == 146); 417d67c46b9STakashi Sakamoto if (++phase >= 147) 418d67c46b9STakashi Sakamoto phase = 0; 419816d8482STakashi Sakamoto *syt_offset_state = phase; 420d67c46b9STakashi Sakamoto } 421d67c46b9STakashi Sakamoto } else 422816d8482STakashi Sakamoto syt_offset = *last_syt_offset - TICKS_PER_CYCLE; 423816d8482STakashi Sakamoto *last_syt_offset = syt_offset; 424d67c46b9STakashi Sakamoto 42583cfb5c5STakashi Sakamoto if (syt_offset >= TICKS_PER_CYCLE) 42683cfb5c5STakashi Sakamoto syt_offset = CIP_SYT_NO_INFO; 427d67c46b9STakashi Sakamoto 42883cfb5c5STakashi Sakamoto return syt_offset; 429d67c46b9STakashi Sakamoto } 430d67c46b9STakashi Sakamoto 431d67c46b9STakashi Sakamoto static void update_pcm_pointers(struct amdtp_stream *s, 432d67c46b9STakashi Sakamoto struct snd_pcm_substream *pcm, 433d67c46b9STakashi Sakamoto unsigned int frames) 434d67c46b9STakashi Sakamoto { 435d67c46b9STakashi Sakamoto unsigned int ptr; 436d67c46b9STakashi Sakamoto 437d67c46b9STakashi Sakamoto ptr = s->pcm_buffer_pointer + frames; 438d67c46b9STakashi Sakamoto if (ptr >= pcm->runtime->buffer_size) 439d67c46b9STakashi Sakamoto ptr -= pcm->runtime->buffer_size; 4406aa7de05SMark Rutland WRITE_ONCE(s->pcm_buffer_pointer, ptr); 441d67c46b9STakashi Sakamoto 442d67c46b9STakashi Sakamoto s->pcm_period_pointer += frames; 443d67c46b9STakashi Sakamoto if (s->pcm_period_pointer >= pcm->runtime->period_size) { 444d67c46b9STakashi Sakamoto s->pcm_period_pointer -= pcm->runtime->period_size; 4452b3d2987STakashi Iwai queue_work(system_highpri_wq, &s->period_work); 446d67c46b9STakashi Sakamoto } 447d67c46b9STakashi Sakamoto } 448d67c46b9STakashi Sakamoto 4492b3d2987STakashi Iwai static void pcm_period_work(struct work_struct *work) 450d67c46b9STakashi Sakamoto { 4512b3d2987STakashi Iwai struct amdtp_stream *s = container_of(work, struct amdtp_stream, 4522b3d2987STakashi Iwai period_work); 4536aa7de05SMark Rutland struct snd_pcm_substream *pcm = READ_ONCE(s->pcm); 454d67c46b9STakashi Sakamoto 455d67c46b9STakashi Sakamoto if (pcm) 456d67c46b9STakashi Sakamoto snd_pcm_period_elapsed(pcm); 457d67c46b9STakashi Sakamoto } 458d67c46b9STakashi Sakamoto 459e229853dSTakashi Sakamoto static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params, 460e229853dSTakashi Sakamoto bool sched_irq) 461d67c46b9STakashi Sakamoto { 4626007bf54STakashi Sakamoto int err; 463d67c46b9STakashi Sakamoto 464e229853dSTakashi Sakamoto params->interrupt = sched_irq; 4656007bf54STakashi Sakamoto params->tag = s->tag; 4666007bf54STakashi Sakamoto params->sy = 0; 467d67c46b9STakashi Sakamoto 4686007bf54STakashi Sakamoto err = fw_iso_context_queue(s->context, params, &s->buffer.iso_buffer, 469d67c46b9STakashi Sakamoto s->buffer.packets[s->packet_index].offset); 470d67c46b9STakashi Sakamoto if (err < 0) { 471d67c46b9STakashi Sakamoto dev_err(&s->unit->device, "queueing error: %d\n", err); 472d67c46b9STakashi Sakamoto goto end; 473d67c46b9STakashi Sakamoto } 474d67c46b9STakashi Sakamoto 475a0e02331STakashi Sakamoto if (++s->packet_index >= s->queue_size) 476d67c46b9STakashi Sakamoto s->packet_index = 0; 477d67c46b9STakashi Sakamoto end: 478d67c46b9STakashi Sakamoto return err; 479d67c46b9STakashi Sakamoto } 480d67c46b9STakashi Sakamoto 481d67c46b9STakashi Sakamoto static inline int queue_out_packet(struct amdtp_stream *s, 482e229853dSTakashi Sakamoto struct fw_iso_packet *params, bool sched_irq) 483d67c46b9STakashi Sakamoto { 484b18f0cfaSTakashi Sakamoto params->skip = 485b18f0cfaSTakashi Sakamoto !!(params->header_length == 0 && params->payload_length == 0); 486e229853dSTakashi Sakamoto return queue_packet(s, params, sched_irq); 487d67c46b9STakashi Sakamoto } 488d67c46b9STakashi Sakamoto 4896007bf54STakashi Sakamoto static inline int queue_in_packet(struct amdtp_stream *s, 49060dd4929STakashi Sakamoto struct fw_iso_packet *params) 491d67c46b9STakashi Sakamoto { 4926007bf54STakashi Sakamoto // Queue one packet for IR context. 4936007bf54STakashi Sakamoto params->header_length = s->ctx_data.tx.ctx_header_size; 4946007bf54STakashi Sakamoto params->payload_length = s->ctx_data.tx.max_ctx_payload_length; 4956007bf54STakashi Sakamoto params->skip = false; 49660dd4929STakashi Sakamoto return queue_packet(s, params, false); 497d67c46b9STakashi Sakamoto } 498d67c46b9STakashi Sakamoto 499252219c7STakashi Sakamoto static void generate_cip_header(struct amdtp_stream *s, __be32 cip_header[2], 500860d798cSTakashi Sakamoto unsigned int data_block_counter, unsigned int syt) 501252219c7STakashi Sakamoto { 502252219c7STakashi Sakamoto cip_header[0] = cpu_to_be32(READ_ONCE(s->source_node_id_field) | 503252219c7STakashi Sakamoto (s->data_block_quadlets << CIP_DBS_SHIFT) | 504252219c7STakashi Sakamoto ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) | 505860d798cSTakashi Sakamoto data_block_counter); 506252219c7STakashi Sakamoto cip_header[1] = cpu_to_be32(CIP_EOH | 507252219c7STakashi Sakamoto ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | 508252219c7STakashi Sakamoto ((s->ctx_data.rx.fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | 509252219c7STakashi Sakamoto (syt & CIP_SYT_MASK)); 510252219c7STakashi Sakamoto } 511252219c7STakashi Sakamoto 5126bc1a269STakashi Sakamoto static void build_it_pkt_header(struct amdtp_stream *s, unsigned int cycle, 5136bc1a269STakashi Sakamoto struct fw_iso_packet *params, 514860d798cSTakashi Sakamoto unsigned int data_blocks, 515860d798cSTakashi Sakamoto unsigned int data_block_counter, 516860d798cSTakashi Sakamoto unsigned int syt, unsigned int index) 517d67c46b9STakashi Sakamoto { 5180ebf3cebSTakashi Sakamoto unsigned int payload_length; 51916be4589STakashi Sakamoto __be32 *cip_header; 520d67c46b9STakashi Sakamoto 5210ebf3cebSTakashi Sakamoto payload_length = data_blocks * sizeof(__be32) * s->data_block_quadlets; 5220ebf3cebSTakashi Sakamoto params->payload_length = payload_length; 5230ebf3cebSTakashi Sakamoto 524b18f0cfaSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) { 5256bc1a269STakashi Sakamoto cip_header = (__be32 *)params->header; 526860d798cSTakashi Sakamoto generate_cip_header(s, cip_header, data_block_counter, syt); 5276bc1a269STakashi Sakamoto params->header_length = 2 * sizeof(__be32); 5280ebf3cebSTakashi Sakamoto payload_length += params->header_length; 529b18f0cfaSTakashi Sakamoto } else { 530b18f0cfaSTakashi Sakamoto cip_header = NULL; 531b18f0cfaSTakashi Sakamoto } 532d67c46b9STakashi Sakamoto 533213fa989STakashi Sakamoto trace_amdtp_packet(s, cycle, cip_header, payload_length, data_blocks, 534814b4312STakashi Sakamoto data_block_counter, s->packet_index, index); 5353b196c39STakashi Sakamoto } 5363b196c39STakashi Sakamoto 537e335425bSTakashi Sakamoto static int check_cip_header(struct amdtp_stream *s, const __be32 *buf, 538e335425bSTakashi Sakamoto unsigned int payload_length, 539a35463d1STakashi Sakamoto unsigned int *data_blocks, 540a35463d1STakashi Sakamoto unsigned int *data_block_counter, unsigned int *syt) 541d67c46b9STakashi Sakamoto { 542d67c46b9STakashi Sakamoto u32 cip_header[2]; 543e335425bSTakashi Sakamoto unsigned int sph; 544e335425bSTakashi Sakamoto unsigned int fmt; 545e335425bSTakashi Sakamoto unsigned int fdf; 546a35463d1STakashi Sakamoto unsigned int dbc; 547d67c46b9STakashi Sakamoto bool lost; 548d67c46b9STakashi Sakamoto 549e335425bSTakashi Sakamoto cip_header[0] = be32_to_cpu(buf[0]); 550e335425bSTakashi Sakamoto cip_header[1] = be32_to_cpu(buf[1]); 551d67c46b9STakashi Sakamoto 552d67c46b9STakashi Sakamoto /* 553d67c46b9STakashi Sakamoto * This module supports 'Two-quadlet CIP header with SYT field'. 554d67c46b9STakashi Sakamoto * For convenience, also check FMT field is AM824 or not. 555d67c46b9STakashi Sakamoto */ 5562128f78fSTakashi Sakamoto if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 5572128f78fSTakashi Sakamoto ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) && 5582128f78fSTakashi Sakamoto (!(s->flags & CIP_HEADER_WITHOUT_EOH))) { 559d67c46b9STakashi Sakamoto dev_info_ratelimited(&s->unit->device, 560d67c46b9STakashi Sakamoto "Invalid CIP header for AMDTP: %08X:%08X\n", 561d67c46b9STakashi Sakamoto cip_header[0], cip_header[1]); 562e335425bSTakashi Sakamoto return -EAGAIN; 563d67c46b9STakashi Sakamoto } 564d67c46b9STakashi Sakamoto 565d67c46b9STakashi Sakamoto /* Check valid protocol or not. */ 5669863874fSTakashi Sakamoto sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT; 567d67c46b9STakashi Sakamoto fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT; 5689863874fSTakashi Sakamoto if (sph != s->sph || fmt != s->fmt) { 5692a7e1713STakashi Sakamoto dev_info_ratelimited(&s->unit->device, 570d67c46b9STakashi Sakamoto "Detect unexpected protocol: %08x %08x\n", 571d67c46b9STakashi Sakamoto cip_header[0], cip_header[1]); 572e335425bSTakashi Sakamoto return -EAGAIN; 573d67c46b9STakashi Sakamoto } 574d67c46b9STakashi Sakamoto 575d67c46b9STakashi Sakamoto /* Calculate data blocks */ 576d67c46b9STakashi Sakamoto fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT; 577e335425bSTakashi Sakamoto if (payload_length < sizeof(__be32) * 2 || 578d67c46b9STakashi Sakamoto (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) { 579e335425bSTakashi Sakamoto *data_blocks = 0; 580d67c46b9STakashi Sakamoto } else { 581e335425bSTakashi Sakamoto unsigned int data_block_quadlets = 582d67c46b9STakashi Sakamoto (cip_header[0] & CIP_DBS_MASK) >> CIP_DBS_SHIFT; 583d67c46b9STakashi Sakamoto /* avoid division by zero */ 584d67c46b9STakashi Sakamoto if (data_block_quadlets == 0) { 585d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 586d67c46b9STakashi Sakamoto "Detect invalid value in dbs field: %08X\n", 587d67c46b9STakashi Sakamoto cip_header[0]); 588d67c46b9STakashi Sakamoto return -EPROTO; 589d67c46b9STakashi Sakamoto } 590d67c46b9STakashi Sakamoto if (s->flags & CIP_WRONG_DBS) 591d67c46b9STakashi Sakamoto data_block_quadlets = s->data_block_quadlets; 592d67c46b9STakashi Sakamoto 593e335425bSTakashi Sakamoto *data_blocks = (payload_length / sizeof(__be32) - 2) / 594ff0fb5aaSTakashi Sakamoto data_block_quadlets; 595d67c46b9STakashi Sakamoto } 596d67c46b9STakashi Sakamoto 597d67c46b9STakashi Sakamoto /* Check data block counter continuity */ 598a35463d1STakashi Sakamoto dbc = cip_header[0] & CIP_DBC_MASK; 599e335425bSTakashi Sakamoto if (*data_blocks == 0 && (s->flags & CIP_EMPTY_HAS_WRONG_DBC) && 600a35463d1STakashi Sakamoto *data_block_counter != UINT_MAX) 601a35463d1STakashi Sakamoto dbc = *data_block_counter; 602d67c46b9STakashi Sakamoto 603a35463d1STakashi Sakamoto if ((dbc == 0x00 && (s->flags & CIP_SKIP_DBC_ZERO_CHECK)) || 604a35463d1STakashi Sakamoto *data_block_counter == UINT_MAX) { 605d67c46b9STakashi Sakamoto lost = false; 606d67c46b9STakashi Sakamoto } else if (!(s->flags & CIP_DBC_IS_END_EVENT)) { 607a35463d1STakashi Sakamoto lost = dbc != *data_block_counter; 608d67c46b9STakashi Sakamoto } else { 609e335425bSTakashi Sakamoto unsigned int dbc_interval; 610e335425bSTakashi Sakamoto 611e335425bSTakashi Sakamoto if (*data_blocks > 0 && s->ctx_data.tx.dbc_interval > 0) 612d3d10a4aSTakashi Sakamoto dbc_interval = s->ctx_data.tx.dbc_interval; 613d67c46b9STakashi Sakamoto else 614e335425bSTakashi Sakamoto dbc_interval = *data_blocks; 615d67c46b9STakashi Sakamoto 616a35463d1STakashi Sakamoto lost = dbc != ((*data_block_counter + dbc_interval) & 0xff); 617d67c46b9STakashi Sakamoto } 618d67c46b9STakashi Sakamoto 619d67c46b9STakashi Sakamoto if (lost) { 620d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 621d67c46b9STakashi Sakamoto "Detect discontinuity of CIP: %02X %02X\n", 622a35463d1STakashi Sakamoto *data_block_counter, dbc); 623d67c46b9STakashi Sakamoto return -EIO; 624d67c46b9STakashi Sakamoto } 625d67c46b9STakashi Sakamoto 626753e7179STakashi Sakamoto *data_block_counter = dbc; 627753e7179STakashi Sakamoto 628e335425bSTakashi Sakamoto *syt = cip_header[1] & CIP_SYT_MASK; 629e335425bSTakashi Sakamoto 630e335425bSTakashi Sakamoto return 0; 631e335425bSTakashi Sakamoto } 632e335425bSTakashi Sakamoto 63398e3e43bSTakashi Sakamoto static int parse_ir_ctx_header(struct amdtp_stream *s, unsigned int cycle, 63498e3e43bSTakashi Sakamoto const __be32 *ctx_header, 63598e3e43bSTakashi Sakamoto unsigned int *payload_length, 636a35463d1STakashi Sakamoto unsigned int *data_blocks, 637a35463d1STakashi Sakamoto unsigned int *data_block_counter, 638814b4312STakashi Sakamoto unsigned int *syt, unsigned int packet_index, unsigned int index) 639e335425bSTakashi Sakamoto { 640f11453c7STakashi Sakamoto const __be32 *cip_header; 641395f41e2STakashi Sakamoto unsigned int cip_header_size; 642e335425bSTakashi Sakamoto int err; 643e335425bSTakashi Sakamoto 64498e3e43bSTakashi Sakamoto *payload_length = be32_to_cpu(ctx_header[0]) >> ISO_DATA_LENGTH_SHIFT; 645395f41e2STakashi Sakamoto 646395f41e2STakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 647395f41e2STakashi Sakamoto cip_header_size = 8; 648395f41e2STakashi Sakamoto else 649395f41e2STakashi Sakamoto cip_header_size = 0; 650395f41e2STakashi Sakamoto 651395f41e2STakashi Sakamoto if (*payload_length > cip_header_size + s->ctx_data.tx.max_ctx_payload_length) { 652e335425bSTakashi Sakamoto dev_err(&s->unit->device, 653e335425bSTakashi Sakamoto "Detect jumbo payload: %04x %04x\n", 654395f41e2STakashi Sakamoto *payload_length, cip_header_size + s->ctx_data.tx.max_ctx_payload_length); 655e335425bSTakashi Sakamoto return -EIO; 656e335425bSTakashi Sakamoto } 657e335425bSTakashi Sakamoto 658395f41e2STakashi Sakamoto if (cip_header_size > 0) { 659c09010eeSTakashi Sakamoto if (*payload_length >= cip_header_size) { 66098e3e43bSTakashi Sakamoto cip_header = ctx_header + 2; 661c09010eeSTakashi Sakamoto err = check_cip_header(s, cip_header, *payload_length, data_blocks, 662c09010eeSTakashi Sakamoto data_block_counter, syt); 663b8b0e24cSTakashi Sakamoto if (err < 0) 664e335425bSTakashi Sakamoto return err; 665947b437eSTakashi Sakamoto } else { 666c09010eeSTakashi Sakamoto // Handle the cycle so that empty packet arrives. 667c09010eeSTakashi Sakamoto cip_header = NULL; 668c09010eeSTakashi Sakamoto *data_blocks = 0; 669c09010eeSTakashi Sakamoto *syt = 0; 670c09010eeSTakashi Sakamoto } 671c09010eeSTakashi Sakamoto } else { 672947b437eSTakashi Sakamoto cip_header = NULL; 67376864868STakashi Sakamoto err = 0; 67498e3e43bSTakashi Sakamoto *data_blocks = *payload_length / sizeof(__be32) / 67598e3e43bSTakashi Sakamoto s->data_block_quadlets; 67698e3e43bSTakashi Sakamoto *syt = 0; 6777fbf9096STakashi Sakamoto 678a35463d1STakashi Sakamoto if (*data_block_counter == UINT_MAX) 679a35463d1STakashi Sakamoto *data_block_counter = 0; 680947b437eSTakashi Sakamoto } 681e335425bSTakashi Sakamoto 68298e3e43bSTakashi Sakamoto trace_amdtp_packet(s, cycle, cip_header, *payload_length, *data_blocks, 683814b4312STakashi Sakamoto *data_block_counter, packet_index, index); 68464d0bf4dSTakashi Sakamoto 68576864868STakashi Sakamoto return err; 686d67c46b9STakashi Sakamoto } 687d67c46b9STakashi Sakamoto 68826cd1e58STakashi Sakamoto // In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On 68926cd1e58STakashi Sakamoto // the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent 69026cd1e58STakashi Sakamoto // it. Thus, via Linux firewire subsystem, we can get the 3 bits for second. 69126cd1e58STakashi Sakamoto static inline u32 compute_cycle_count(__be32 ctx_header_tstamp) 69273fc7f08STakashi Sakamoto { 69326cd1e58STakashi Sakamoto u32 tstamp = be32_to_cpu(ctx_header_tstamp) & HEADER_TSTAMP_MASK; 69473fc7f08STakashi Sakamoto return (((tstamp >> 13) & 0x07) * 8000) + (tstamp & 0x1fff); 69573fc7f08STakashi Sakamoto } 69673fc7f08STakashi Sakamoto 69773fc7f08STakashi Sakamoto static inline u32 increment_cycle_count(u32 cycle, unsigned int addend) 69873fc7f08STakashi Sakamoto { 69973fc7f08STakashi Sakamoto cycle += addend; 70010aa8e4aSTakashi Sakamoto if (cycle >= OHCI_MAX_SECOND * CYCLES_PER_SECOND) 70110aa8e4aSTakashi Sakamoto cycle -= OHCI_MAX_SECOND * CYCLES_PER_SECOND; 70273fc7f08STakashi Sakamoto return cycle; 70373fc7f08STakashi Sakamoto } 70473fc7f08STakashi Sakamoto 70526cd1e58STakashi Sakamoto // Align to actual cycle count for the packet which is going to be scheduled. 706a0e02331STakashi Sakamoto // This module queued the same number of isochronous cycle as the size of queue 707a0e02331STakashi Sakamoto // to kip isochronous cycle, therefore it's OK to just increment the cycle by 708a0e02331STakashi Sakamoto // the size of queue for scheduled cycle. 709a0e02331STakashi Sakamoto static inline u32 compute_it_cycle(const __be32 ctx_header_tstamp, 710a0e02331STakashi Sakamoto unsigned int queue_size) 71126cd1e58STakashi Sakamoto { 71226cd1e58STakashi Sakamoto u32 cycle = compute_cycle_count(ctx_header_tstamp); 713a0e02331STakashi Sakamoto return increment_cycle_count(cycle, queue_size); 71426cd1e58STakashi Sakamoto } 71526cd1e58STakashi Sakamoto 716753e7179STakashi Sakamoto static int generate_device_pkt_descs(struct amdtp_stream *s, 717753e7179STakashi Sakamoto struct pkt_desc *descs, 718753e7179STakashi Sakamoto const __be32 *ctx_header, 719753e7179STakashi Sakamoto unsigned int packets) 720753e7179STakashi Sakamoto { 721753e7179STakashi Sakamoto unsigned int dbc = s->data_block_counter; 722814b4312STakashi Sakamoto unsigned int packet_index = s->packet_index; 723814b4312STakashi Sakamoto unsigned int queue_size = s->queue_size; 724753e7179STakashi Sakamoto int i; 725753e7179STakashi Sakamoto int err; 726753e7179STakashi Sakamoto 727753e7179STakashi Sakamoto for (i = 0; i < packets; ++i) { 728753e7179STakashi Sakamoto struct pkt_desc *desc = descs + i; 729753e7179STakashi Sakamoto unsigned int cycle; 730753e7179STakashi Sakamoto unsigned int payload_length; 731753e7179STakashi Sakamoto unsigned int data_blocks; 732753e7179STakashi Sakamoto unsigned int syt; 733753e7179STakashi Sakamoto 734753e7179STakashi Sakamoto cycle = compute_cycle_count(ctx_header[1]); 735753e7179STakashi Sakamoto 736753e7179STakashi Sakamoto err = parse_ir_ctx_header(s, cycle, ctx_header, &payload_length, 737814b4312STakashi Sakamoto &data_blocks, &dbc, &syt, packet_index, i); 738753e7179STakashi Sakamoto if (err < 0) 739753e7179STakashi Sakamoto return err; 740753e7179STakashi Sakamoto 741753e7179STakashi Sakamoto desc->cycle = cycle; 742753e7179STakashi Sakamoto desc->syt = syt; 743753e7179STakashi Sakamoto desc->data_blocks = data_blocks; 744753e7179STakashi Sakamoto desc->data_block_counter = dbc; 745814b4312STakashi Sakamoto desc->ctx_payload = s->buffer.packets[packet_index].buffer; 746753e7179STakashi Sakamoto 747753e7179STakashi Sakamoto if (!(s->flags & CIP_DBC_IS_END_EVENT)) 748753e7179STakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 749753e7179STakashi Sakamoto 750753e7179STakashi Sakamoto ctx_header += 751753e7179STakashi Sakamoto s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header); 752814b4312STakashi Sakamoto 753814b4312STakashi Sakamoto packet_index = (packet_index + 1) % queue_size; 754753e7179STakashi Sakamoto } 755753e7179STakashi Sakamoto 756753e7179STakashi Sakamoto s->data_block_counter = dbc; 757753e7179STakashi Sakamoto 758753e7179STakashi Sakamoto return 0; 759753e7179STakashi Sakamoto } 760753e7179STakashi Sakamoto 76183cfb5c5STakashi Sakamoto static unsigned int compute_syt(unsigned int syt_offset, unsigned int cycle, 76283cfb5c5STakashi Sakamoto unsigned int transfer_delay) 76383cfb5c5STakashi Sakamoto { 76483cfb5c5STakashi Sakamoto unsigned int syt; 76583cfb5c5STakashi Sakamoto 76683cfb5c5STakashi Sakamoto syt_offset += transfer_delay; 76783cfb5c5STakashi Sakamoto syt = ((cycle + syt_offset / TICKS_PER_CYCLE) << 12) | 76883cfb5c5STakashi Sakamoto (syt_offset % TICKS_PER_CYCLE); 76983cfb5c5STakashi Sakamoto return syt & CIP_SYT_MASK; 77083cfb5c5STakashi Sakamoto } 77183cfb5c5STakashi Sakamoto 77269efd5c4STakashi Sakamoto static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs, 77369efd5c4STakashi Sakamoto const __be32 *ctx_header, unsigned int packets, 77469efd5c4STakashi Sakamoto const struct seq_desc *seq_descs, 77569efd5c4STakashi Sakamoto unsigned int seq_size) 776f4f6ae7bSTakashi Sakamoto { 777f4f6ae7bSTakashi Sakamoto unsigned int dbc = s->data_block_counter; 77869efd5c4STakashi Sakamoto unsigned int seq_index = s->ctx_data.rx.seq_index; 779f4f6ae7bSTakashi Sakamoto int i; 780f4f6ae7bSTakashi Sakamoto 781f4f6ae7bSTakashi Sakamoto for (i = 0; i < packets; ++i) { 782f4f6ae7bSTakashi Sakamoto struct pkt_desc *desc = descs + i; 783a0e02331STakashi Sakamoto unsigned int index = (s->packet_index + i) % s->queue_size; 78469efd5c4STakashi Sakamoto const struct seq_desc *seq = seq_descs + seq_index; 78569efd5c4STakashi Sakamoto unsigned int syt; 786f4f6ae7bSTakashi Sakamoto 787a0e02331STakashi Sakamoto desc->cycle = compute_it_cycle(*ctx_header, s->queue_size); 78869efd5c4STakashi Sakamoto 78969efd5c4STakashi Sakamoto syt = seq->syt_offset; 79069efd5c4STakashi Sakamoto if (syt != CIP_SYT_NO_INFO) { 79169efd5c4STakashi Sakamoto syt = compute_syt(syt, desc->cycle, 79283cfb5c5STakashi Sakamoto s->ctx_data.rx.transfer_delay); 79383cfb5c5STakashi Sakamoto } 79469efd5c4STakashi Sakamoto desc->syt = syt; 79569efd5c4STakashi Sakamoto desc->data_blocks = seq->data_blocks; 796f4f6ae7bSTakashi Sakamoto 797f4f6ae7bSTakashi Sakamoto if (s->flags & CIP_DBC_IS_END_EVENT) 798f4f6ae7bSTakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 799f4f6ae7bSTakashi Sakamoto 800f4f6ae7bSTakashi Sakamoto desc->data_block_counter = dbc; 801f4f6ae7bSTakashi Sakamoto 802f4f6ae7bSTakashi Sakamoto if (!(s->flags & CIP_DBC_IS_END_EVENT)) 803f4f6ae7bSTakashi Sakamoto dbc = (dbc + desc->data_blocks) & 0xff; 804f4f6ae7bSTakashi Sakamoto 805f4f6ae7bSTakashi Sakamoto desc->ctx_payload = s->buffer.packets[index].buffer; 806f4f6ae7bSTakashi Sakamoto 80769efd5c4STakashi Sakamoto seq_index = (seq_index + 1) % seq_size; 80869efd5c4STakashi Sakamoto 809f4f6ae7bSTakashi Sakamoto ++ctx_header; 810f4f6ae7bSTakashi Sakamoto } 811f4f6ae7bSTakashi Sakamoto 812f4f6ae7bSTakashi Sakamoto s->data_block_counter = dbc; 81369efd5c4STakashi Sakamoto s->ctx_data.rx.seq_index = seq_index; 814f4f6ae7bSTakashi Sakamoto } 815f4f6ae7bSTakashi Sakamoto 816fce9b013STakashi Sakamoto static inline void cancel_stream(struct amdtp_stream *s) 817fce9b013STakashi Sakamoto { 818fce9b013STakashi Sakamoto s->packet_index = -1; 8192b3d2987STakashi Iwai if (current_work() == &s->period_work) 820fce9b013STakashi Sakamoto amdtp_stream_pcm_abort(s); 821fce9b013STakashi Sakamoto WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); 822fce9b013STakashi Sakamoto } 823fce9b013STakashi Sakamoto 8240f5cfcb2STakashi Sakamoto static void process_ctx_payloads(struct amdtp_stream *s, 8250f5cfcb2STakashi Sakamoto const struct pkt_desc *descs, 8260f5cfcb2STakashi Sakamoto unsigned int packets) 8270f5cfcb2STakashi Sakamoto { 8289a738ad1STakashi Sakamoto struct snd_pcm_substream *pcm; 8290f5cfcb2STakashi Sakamoto unsigned int pcm_frames; 8300f5cfcb2STakashi Sakamoto 8319a738ad1STakashi Sakamoto pcm = READ_ONCE(s->pcm); 8329a738ad1STakashi Sakamoto pcm_frames = s->process_ctx_payloads(s, descs, packets, pcm); 8339a738ad1STakashi Sakamoto if (pcm) 8340f5cfcb2STakashi Sakamoto update_pcm_pointers(s, pcm, pcm_frames); 8350f5cfcb2STakashi Sakamoto } 8360f5cfcb2STakashi Sakamoto 83773fc7f08STakashi Sakamoto static void out_stream_callback(struct fw_iso_context *context, u32 tstamp, 838d67c46b9STakashi Sakamoto size_t header_length, void *header, 839d67c46b9STakashi Sakamoto void *private_data) 840d67c46b9STakashi Sakamoto { 841d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 84269efd5c4STakashi Sakamoto const struct amdtp_domain *d = s->domain; 84326cd1e58STakashi Sakamoto const __be32 *ctx_header = header; 8446d60b7a3STakashi Sakamoto unsigned int events_per_period = d->events_per_period; 84560dd4929STakashi Sakamoto unsigned int event_count = s->ctx_data.rx.event_count; 846a0e02331STakashi Sakamoto unsigned int packets; 8470dcb4efbSTakashi Sakamoto int i; 848d67c46b9STakashi Sakamoto 849d67c46b9STakashi Sakamoto if (s->packet_index < 0) 850d67c46b9STakashi Sakamoto return; 851d67c46b9STakashi Sakamoto 852a0e02331STakashi Sakamoto // Calculate the number of packets in buffer and check XRUN. 853a0e02331STakashi Sakamoto packets = header_length / sizeof(*ctx_header); 854a0e02331STakashi Sakamoto 855*d32872f3STakashi Sakamoto generate_pkt_descs(s, s->pkt_descs, ctx_header, packets, d->seq.descs, 856*d32872f3STakashi Sakamoto d->seq.size); 857f4f6ae7bSTakashi Sakamoto 8580f5cfcb2STakashi Sakamoto process_ctx_payloads(s, s->pkt_descs, packets); 8595e2ece0fSTakashi Sakamoto 8605e2ece0fSTakashi Sakamoto for (i = 0; i < packets; ++i) { 8615e2ece0fSTakashi Sakamoto const struct pkt_desc *desc = s->pkt_descs + i; 862f4f6ae7bSTakashi Sakamoto unsigned int syt; 8636bc1a269STakashi Sakamoto struct { 8646bc1a269STakashi Sakamoto struct fw_iso_packet params; 8656bc1a269STakashi Sakamoto __be32 header[IT_PKT_HEADER_SIZE_CIP / sizeof(__be32)]; 8666bc1a269STakashi Sakamoto } template = { {0}, {0} }; 867e229853dSTakashi Sakamoto bool sched_irq = false; 868860d798cSTakashi Sakamoto 869f4f6ae7bSTakashi Sakamoto if (s->ctx_data.rx.syt_override < 0) 870f4f6ae7bSTakashi Sakamoto syt = desc->syt; 871f4f6ae7bSTakashi Sakamoto else 8723baf3053STakashi Sakamoto syt = s->ctx_data.rx.syt_override; 8733baf3053STakashi Sakamoto 874f4f6ae7bSTakashi Sakamoto build_it_pkt_header(s, desc->cycle, &template.params, 875f4f6ae7bSTakashi Sakamoto desc->data_blocks, desc->data_block_counter, 876f4f6ae7bSTakashi Sakamoto syt, i); 8776bc1a269STakashi Sakamoto 8782472cfb3STakashi Sakamoto if (s == s->domain->irq_target) { 879e229853dSTakashi Sakamoto event_count += desc->data_blocks; 880e229853dSTakashi Sakamoto if (event_count >= events_per_period) { 881e229853dSTakashi Sakamoto event_count -= events_per_period; 882e229853dSTakashi Sakamoto sched_irq = true; 883e229853dSTakashi Sakamoto } 88460dd4929STakashi Sakamoto } 885e229853dSTakashi Sakamoto 886e229853dSTakashi Sakamoto if (queue_out_packet(s, &template.params, sched_irq) < 0) { 887fce9b013STakashi Sakamoto cancel_stream(s); 888d67c46b9STakashi Sakamoto return; 889d67c46b9STakashi Sakamoto } 890d67c46b9STakashi Sakamoto } 891d67c46b9STakashi Sakamoto 89260dd4929STakashi Sakamoto s->ctx_data.rx.event_count = event_count; 893d67c46b9STakashi Sakamoto } 894d67c46b9STakashi Sakamoto 89573fc7f08STakashi Sakamoto static void in_stream_callback(struct fw_iso_context *context, u32 tstamp, 896d67c46b9STakashi Sakamoto size_t header_length, void *header, 897d67c46b9STakashi Sakamoto void *private_data) 898d67c46b9STakashi Sakamoto { 899d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 900cc4f8e91STakashi Sakamoto __be32 *ctx_header = header; 901e229853dSTakashi Sakamoto unsigned int packets; 902753e7179STakashi Sakamoto int i; 903753e7179STakashi Sakamoto int err; 904d67c46b9STakashi Sakamoto 905d67c46b9STakashi Sakamoto if (s->packet_index < 0) 906d67c46b9STakashi Sakamoto return; 907d67c46b9STakashi Sakamoto 908a0e02331STakashi Sakamoto // Calculate the number of packets in buffer and check XRUN. 909d3d10a4aSTakashi Sakamoto packets = header_length / s->ctx_data.tx.ctx_header_size; 910f90e2dedSTakashi Sakamoto 911753e7179STakashi Sakamoto err = generate_device_pkt_descs(s, s->pkt_descs, ctx_header, packets); 912753e7179STakashi Sakamoto if (err < 0) { 913753e7179STakashi Sakamoto if (err != -EAGAIN) { 914753e7179STakashi Sakamoto cancel_stream(s); 915753e7179STakashi Sakamoto return; 916753e7179STakashi Sakamoto } 9175e2ece0fSTakashi Sakamoto } else { 9180f5cfcb2STakashi Sakamoto process_ctx_payloads(s, s->pkt_descs, packets); 9195e2ece0fSTakashi Sakamoto } 9205e2ece0fSTakashi Sakamoto 9215e2ece0fSTakashi Sakamoto for (i = 0; i < packets; ++i) { 9225e2ece0fSTakashi Sakamoto struct fw_iso_packet params = {0}; 923a35463d1STakashi Sakamoto 92460dd4929STakashi Sakamoto if (queue_in_packet(s, ¶ms) < 0) { 925753e7179STakashi Sakamoto cancel_stream(s); 926753e7179STakashi Sakamoto return; 927753e7179STakashi Sakamoto } 928d67c46b9STakashi Sakamoto } 929d67c46b9STakashi Sakamoto } 930d67c46b9STakashi Sakamoto 9311a4be183STakashi Sakamoto static void pool_ideal_seq_descs(struct amdtp_domain *d, unsigned int packets) 9321a4be183STakashi Sakamoto { 9331a4be183STakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 934*d32872f3STakashi Sakamoto unsigned int seq_tail = d->seq.tail; 935*d32872f3STakashi Sakamoto unsigned int seq_size = d->seq.size; 9361a4be183STakashi Sakamoto unsigned int min_avail; 9371a4be183STakashi Sakamoto struct amdtp_stream *s; 9381a4be183STakashi Sakamoto 939*d32872f3STakashi Sakamoto min_avail = d->seq.size; 9401a4be183STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 9411a4be183STakashi Sakamoto unsigned int seq_index; 9421a4be183STakashi Sakamoto unsigned int avail; 9431a4be183STakashi Sakamoto 9441a4be183STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) 9451a4be183STakashi Sakamoto continue; 9461a4be183STakashi Sakamoto 9471a4be183STakashi Sakamoto seq_index = s->ctx_data.rx.seq_index; 948*d32872f3STakashi Sakamoto avail = d->seq.tail; 9491a4be183STakashi Sakamoto if (seq_index > avail) 950*d32872f3STakashi Sakamoto avail += d->seq.size; 9511a4be183STakashi Sakamoto avail -= seq_index; 9521a4be183STakashi Sakamoto 9531a4be183STakashi Sakamoto if (avail < min_avail) 9541a4be183STakashi Sakamoto min_avail = avail; 9551a4be183STakashi Sakamoto } 9561a4be183STakashi Sakamoto 9571a4be183STakashi Sakamoto while (min_avail < packets) { 958*d32872f3STakashi Sakamoto struct seq_desc *desc = d->seq.descs + seq_tail; 9591a4be183STakashi Sakamoto 9601a4be183STakashi Sakamoto desc->syt_offset = calculate_syt_offset(&d->last_syt_offset, 9611a4be183STakashi Sakamoto &d->syt_offset_state, irq_target->sfc); 9621a4be183STakashi Sakamoto desc->data_blocks = calculate_data_blocks(&d->data_block_state, 9631a4be183STakashi Sakamoto !!(irq_target->flags & CIP_BLOCKING), 9641a4be183STakashi Sakamoto desc->syt_offset == CIP_SYT_NO_INFO, 9651a4be183STakashi Sakamoto irq_target->syt_interval, irq_target->sfc); 9661a4be183STakashi Sakamoto 9671a4be183STakashi Sakamoto ++seq_tail; 9681a4be183STakashi Sakamoto seq_tail %= seq_size; 9691a4be183STakashi Sakamoto 9701a4be183STakashi Sakamoto ++min_avail; 9711a4be183STakashi Sakamoto } 9721a4be183STakashi Sakamoto 973*d32872f3STakashi Sakamoto d->seq.tail = seq_tail; 9741a4be183STakashi Sakamoto } 9751a4be183STakashi Sakamoto 9762472cfb3STakashi Sakamoto static void irq_target_callback(struct fw_iso_context *context, u32 tstamp, 9772472cfb3STakashi Sakamoto size_t header_length, void *header, 9782472cfb3STakashi Sakamoto void *private_data) 97960dd4929STakashi Sakamoto { 9802472cfb3STakashi Sakamoto struct amdtp_stream *irq_target = private_data; 9812472cfb3STakashi Sakamoto struct amdtp_domain *d = irq_target->domain; 9821a4be183STakashi Sakamoto unsigned int packets = header_length / sizeof(__be32); 98360dd4929STakashi Sakamoto struct amdtp_stream *s; 98460dd4929STakashi Sakamoto 9851a4be183STakashi Sakamoto // Record enough entries with extra 3 cycles at least. 9861a4be183STakashi Sakamoto pool_ideal_seq_descs(d, packets + 3); 9871a4be183STakashi Sakamoto 98860dd4929STakashi Sakamoto out_stream_callback(context, tstamp, header_length, header, irq_target); 98960dd4929STakashi Sakamoto if (amdtp_streaming_error(irq_target)) 99060dd4929STakashi Sakamoto goto error; 99160dd4929STakashi Sakamoto 99260dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 99360dd4929STakashi Sakamoto if (s != irq_target && amdtp_stream_running(s)) { 99460dd4929STakashi Sakamoto fw_iso_context_flush_completions(s->context); 99560dd4929STakashi Sakamoto if (amdtp_streaming_error(s)) 99660dd4929STakashi Sakamoto goto error; 99760dd4929STakashi Sakamoto } 99860dd4929STakashi Sakamoto } 99960dd4929STakashi Sakamoto 100060dd4929STakashi Sakamoto return; 100160dd4929STakashi Sakamoto error: 100260dd4929STakashi Sakamoto if (amdtp_stream_running(irq_target)) 100360dd4929STakashi Sakamoto cancel_stream(irq_target); 100460dd4929STakashi Sakamoto 100560dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 100660dd4929STakashi Sakamoto if (amdtp_stream_running(s)) 100760dd4929STakashi Sakamoto cancel_stream(s); 100860dd4929STakashi Sakamoto } 100960dd4929STakashi Sakamoto } 101060dd4929STakashi Sakamoto 101160dd4929STakashi Sakamoto // this is executed one time. 1012d67c46b9STakashi Sakamoto static void amdtp_stream_first_callback(struct fw_iso_context *context, 101373fc7f08STakashi Sakamoto u32 tstamp, size_t header_length, 1014d67c46b9STakashi Sakamoto void *header, void *private_data) 1015d67c46b9STakashi Sakamoto { 1016d67c46b9STakashi Sakamoto struct amdtp_stream *s = private_data; 101726cd1e58STakashi Sakamoto const __be32 *ctx_header = header; 1018a04513f8STakashi Sakamoto u32 cycle; 1019d67c46b9STakashi Sakamoto 1020d67c46b9STakashi Sakamoto /* 1021d67c46b9STakashi Sakamoto * For in-stream, first packet has come. 1022d67c46b9STakashi Sakamoto * For out-stream, prepared to transmit first packet 1023d67c46b9STakashi Sakamoto */ 1024d67c46b9STakashi Sakamoto s->callbacked = true; 1025d67c46b9STakashi Sakamoto wake_up(&s->callback_wait); 1026d67c46b9STakashi Sakamoto 1027cc4f8e91STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 102826cd1e58STakashi Sakamoto cycle = compute_cycle_count(ctx_header[1]); 1029a04513f8STakashi Sakamoto 1030d67c46b9STakashi Sakamoto context->callback.sc = in_stream_callback; 1031a04513f8STakashi Sakamoto } else { 1032a0e02331STakashi Sakamoto cycle = compute_it_cycle(*ctx_header, s->queue_size); 103326cd1e58STakashi Sakamoto 10342472cfb3STakashi Sakamoto if (s == s->domain->irq_target) 10352472cfb3STakashi Sakamoto context->callback.sc = irq_target_callback; 10362472cfb3STakashi Sakamoto else 1037d67c46b9STakashi Sakamoto context->callback.sc = out_stream_callback; 1038a04513f8STakashi Sakamoto } 1039a04513f8STakashi Sakamoto 1040a04513f8STakashi Sakamoto s->start_cycle = cycle; 1041d67c46b9STakashi Sakamoto 104273fc7f08STakashi Sakamoto context->callback.sc(context, tstamp, header_length, header, s); 1043d67c46b9STakashi Sakamoto } 1044d67c46b9STakashi Sakamoto 1045d67c46b9STakashi Sakamoto /** 1046d67c46b9STakashi Sakamoto * amdtp_stream_start - start transferring packets 1047d67c46b9STakashi Sakamoto * @s: the AMDTP stream to start 1048d67c46b9STakashi Sakamoto * @channel: the isochronous channel on the bus 1049d67c46b9STakashi Sakamoto * @speed: firewire speed code 1050acfedcbeSTakashi Sakamoto * @start_cycle: the isochronous cycle to start the context. Start immediately 1051acfedcbeSTakashi Sakamoto * if negative value is given. 1052af86b0b1STakashi Sakamoto * @queue_size: The number of packets in the queue. 1053af86b0b1STakashi Sakamoto * @idle_irq_interval: the interval to queue packet during initial state. 1054d67c46b9STakashi Sakamoto * 1055d67c46b9STakashi Sakamoto * The stream cannot be started until it has been configured with 1056d67c46b9STakashi Sakamoto * amdtp_stream_set_parameters() and it must be started before any PCM or MIDI 1057d67c46b9STakashi Sakamoto * device can be started. 1058d67c46b9STakashi Sakamoto */ 1059a0e02331STakashi Sakamoto static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed, 1060af86b0b1STakashi Sakamoto int start_cycle, unsigned int queue_size, 1061af86b0b1STakashi Sakamoto unsigned int idle_irq_interval) 1062d67c46b9STakashi Sakamoto { 10632472cfb3STakashi Sakamoto bool is_irq_target = (s == s->domain->irq_target); 1064d3d10a4aSTakashi Sakamoto unsigned int ctx_header_size; 1065f11453c7STakashi Sakamoto unsigned int max_ctx_payload_size; 1066d67c46b9STakashi Sakamoto enum dma_data_direction dir; 1067d67c46b9STakashi Sakamoto int type, tag, err; 1068d67c46b9STakashi Sakamoto 1069d67c46b9STakashi Sakamoto mutex_lock(&s->mutex); 1070d67c46b9STakashi Sakamoto 1071d67c46b9STakashi Sakamoto if (WARN_ON(amdtp_stream_running(s) || 1072d67c46b9STakashi Sakamoto (s->data_block_quadlets < 1))) { 1073d67c46b9STakashi Sakamoto err = -EBADFD; 1074d67c46b9STakashi Sakamoto goto err_unlock; 1075d67c46b9STakashi Sakamoto } 1076d67c46b9STakashi Sakamoto 1077d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 107860dd4929STakashi Sakamoto // NOTE: IT context should be used for constant IRQ. 107960dd4929STakashi Sakamoto if (is_irq_target) { 108060dd4929STakashi Sakamoto err = -EINVAL; 108160dd4929STakashi Sakamoto goto err_unlock; 108260dd4929STakashi Sakamoto } 108360dd4929STakashi Sakamoto 1084d67c46b9STakashi Sakamoto s->data_block_counter = UINT_MAX; 1085d3d10a4aSTakashi Sakamoto } else { 1086d67c46b9STakashi Sakamoto s->data_block_counter = 0; 1087d3d10a4aSTakashi Sakamoto } 1088d67c46b9STakashi Sakamoto 10891be4f21dSTakashi Sakamoto // initialize packet buffer. 10901be4f21dSTakashi Sakamoto max_ctx_payload_size = amdtp_stream_get_max_payload(s); 1091d67c46b9STakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1092d67c46b9STakashi Sakamoto dir = DMA_FROM_DEVICE; 1093d67c46b9STakashi Sakamoto type = FW_ISO_CONTEXT_RECEIVE; 10941be4f21dSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) { 10951be4f21dSTakashi Sakamoto max_ctx_payload_size -= 8; 1096f11453c7STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_CIP; 10971be4f21dSTakashi Sakamoto } else { 1098f11453c7STakashi Sakamoto ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP; 10991be4f21dSTakashi Sakamoto } 1100d67c46b9STakashi Sakamoto } else { 1101d67c46b9STakashi Sakamoto dir = DMA_TO_DEVICE; 1102d67c46b9STakashi Sakamoto type = FW_ISO_CONTEXT_TRANSMIT; 1103df9160b9STakashi Sakamoto ctx_header_size = 0; // No effect for IT context. 1104f11453c7STakashi Sakamoto 1105b18f0cfaSTakashi Sakamoto if (!(s->flags & CIP_NO_HEADER)) 1106b18f0cfaSTakashi Sakamoto max_ctx_payload_size -= IT_PKT_HEADER_SIZE_CIP; 1107b18f0cfaSTakashi Sakamoto } 1108f11453c7STakashi Sakamoto 1109af86b0b1STakashi Sakamoto err = iso_packets_buffer_init(&s->buffer, s->unit, queue_size, 1110f11453c7STakashi Sakamoto max_ctx_payload_size, dir); 1111d67c46b9STakashi Sakamoto if (err < 0) 1112d67c46b9STakashi Sakamoto goto err_unlock; 1113af86b0b1STakashi Sakamoto s->queue_size = queue_size; 111460dd4929STakashi Sakamoto 1115d67c46b9STakashi Sakamoto s->context = fw_iso_context_create(fw_parent_device(s->unit)->card, 1116d3d10a4aSTakashi Sakamoto type, channel, speed, ctx_header_size, 11172472cfb3STakashi Sakamoto amdtp_stream_first_callback, s); 1118d67c46b9STakashi Sakamoto if (IS_ERR(s->context)) { 1119d67c46b9STakashi Sakamoto err = PTR_ERR(s->context); 1120d67c46b9STakashi Sakamoto if (err == -EBUSY) 1121d67c46b9STakashi Sakamoto dev_err(&s->unit->device, 1122d67c46b9STakashi Sakamoto "no free stream on this controller\n"); 1123d67c46b9STakashi Sakamoto goto err_buffer; 1124d67c46b9STakashi Sakamoto } 1125d67c46b9STakashi Sakamoto 1126d67c46b9STakashi Sakamoto amdtp_stream_update(s); 1127d67c46b9STakashi Sakamoto 1128d3d10a4aSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1129f11453c7STakashi Sakamoto s->ctx_data.tx.max_ctx_payload_length = max_ctx_payload_size; 1130d3d10a4aSTakashi Sakamoto s->ctx_data.tx.ctx_header_size = ctx_header_size; 1131d3d10a4aSTakashi Sakamoto } 113252759c09STakashi Sakamoto 11333b196c39STakashi Sakamoto if (s->flags & CIP_NO_HEADER) 11343b196c39STakashi Sakamoto s->tag = TAG_NO_CIP_HEADER; 11353b196c39STakashi Sakamoto else 11363b196c39STakashi Sakamoto s->tag = TAG_CIP; 11373b196c39STakashi Sakamoto 1138a0e02331STakashi Sakamoto s->pkt_descs = kcalloc(s->queue_size, sizeof(*s->pkt_descs), 113904130cf8STakashi Sakamoto GFP_KERNEL); 114004130cf8STakashi Sakamoto if (!s->pkt_descs) { 114104130cf8STakashi Sakamoto err = -ENOMEM; 114204130cf8STakashi Sakamoto goto err_context; 114304130cf8STakashi Sakamoto } 114404130cf8STakashi Sakamoto 1145d67c46b9STakashi Sakamoto s->packet_index = 0; 1146d67c46b9STakashi Sakamoto do { 11476007bf54STakashi Sakamoto struct fw_iso_packet params; 1148e229853dSTakashi Sakamoto 1149b18f0cfaSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 115060dd4929STakashi Sakamoto err = queue_in_packet(s, ¶ms); 1151b18f0cfaSTakashi Sakamoto } else { 115260dd4929STakashi Sakamoto bool sched_irq = false; 115360dd4929STakashi Sakamoto 1154b18f0cfaSTakashi Sakamoto params.header_length = 0; 1155b18f0cfaSTakashi Sakamoto params.payload_length = 0; 115660dd4929STakashi Sakamoto 115760dd4929STakashi Sakamoto if (is_irq_target) { 115860dd4929STakashi Sakamoto sched_irq = !((s->packet_index + 1) % 115960dd4929STakashi Sakamoto idle_irq_interval); 116060dd4929STakashi Sakamoto } 116160dd4929STakashi Sakamoto 1162e229853dSTakashi Sakamoto err = queue_out_packet(s, ¶ms, sched_irq); 1163b18f0cfaSTakashi Sakamoto } 1164d67c46b9STakashi Sakamoto if (err < 0) 116504130cf8STakashi Sakamoto goto err_pkt_descs; 1166d67c46b9STakashi Sakamoto } while (s->packet_index > 0); 1167d67c46b9STakashi Sakamoto 1168d67c46b9STakashi Sakamoto /* NOTE: TAG1 matches CIP. This just affects in stream. */ 1169d67c46b9STakashi Sakamoto tag = FW_ISO_CONTEXT_MATCH_TAG1; 11703b196c39STakashi Sakamoto if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER)) 1171d67c46b9STakashi Sakamoto tag |= FW_ISO_CONTEXT_MATCH_TAG0; 1172d67c46b9STakashi Sakamoto 1173d67c46b9STakashi Sakamoto s->callbacked = false; 1174acfedcbeSTakashi Sakamoto err = fw_iso_context_start(s->context, start_cycle, 0, tag); 1175d67c46b9STakashi Sakamoto if (err < 0) 117604130cf8STakashi Sakamoto goto err_pkt_descs; 1177d67c46b9STakashi Sakamoto 1178d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1179d67c46b9STakashi Sakamoto 1180d67c46b9STakashi Sakamoto return 0; 118104130cf8STakashi Sakamoto err_pkt_descs: 118204130cf8STakashi Sakamoto kfree(s->pkt_descs); 1183d67c46b9STakashi Sakamoto err_context: 1184d67c46b9STakashi Sakamoto fw_iso_context_destroy(s->context); 1185d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 1186d67c46b9STakashi Sakamoto err_buffer: 1187d67c46b9STakashi Sakamoto iso_packets_buffer_destroy(&s->buffer, s->unit); 1188d67c46b9STakashi Sakamoto err_unlock: 1189d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1190d67c46b9STakashi Sakamoto 1191d67c46b9STakashi Sakamoto return err; 1192d67c46b9STakashi Sakamoto } 1193d67c46b9STakashi Sakamoto 1194d67c46b9STakashi Sakamoto /** 1195f890f9a0STakashi Sakamoto * amdtp_domain_stream_pcm_pointer - get the PCM buffer position 1196f890f9a0STakashi Sakamoto * @d: the AMDTP domain. 1197d67c46b9STakashi Sakamoto * @s: the AMDTP stream that transports the PCM data 1198d67c46b9STakashi Sakamoto * 1199d67c46b9STakashi Sakamoto * Returns the current buffer position, in frames. 1200d67c46b9STakashi Sakamoto */ 1201f890f9a0STakashi Sakamoto unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, 1202f890f9a0STakashi Sakamoto struct amdtp_stream *s) 1203d67c46b9STakashi Sakamoto { 1204f890f9a0STakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 1205f890f9a0STakashi Sakamoto 1206f890f9a0STakashi Sakamoto if (irq_target && amdtp_stream_running(irq_target)) { 1207f890f9a0STakashi Sakamoto // This function is called in software IRQ context of 12082b3d2987STakashi Iwai // period_work or process context. 1209f890f9a0STakashi Sakamoto // 1210f890f9a0STakashi Sakamoto // When the software IRQ context was scheduled by software IRQ 1211f890f9a0STakashi Sakamoto // context of IT contexts, queued packets were already handled. 1212f890f9a0STakashi Sakamoto // Therefore, no need to flush the queue in buffer furthermore. 1213f890f9a0STakashi Sakamoto // 1214f890f9a0STakashi Sakamoto // When the process context reach here, some packets will be 1215f890f9a0STakashi Sakamoto // already queued in the buffer. These packets should be handled 1216f890f9a0STakashi Sakamoto // immediately to keep better granularity of PCM pointer. 1217f890f9a0STakashi Sakamoto // 1218f890f9a0STakashi Sakamoto // Later, the process context will sometimes schedules software 12192b3d2987STakashi Iwai // IRQ context of the period_work. Then, no need to flush the 1220f890f9a0STakashi Sakamoto // queue by the same reason as described in the above 12212b3d2987STakashi Iwai if (current_work() != &s->period_work) { 1222f890f9a0STakashi Sakamoto // Queued packet should be processed without any kernel 1223f890f9a0STakashi Sakamoto // preemption to keep latency against bus cycle. 1224f890f9a0STakashi Sakamoto preempt_disable(); 1225f890f9a0STakashi Sakamoto fw_iso_context_flush_completions(irq_target->context); 1226f890f9a0STakashi Sakamoto preempt_enable(); 1227f890f9a0STakashi Sakamoto } 1228f890f9a0STakashi Sakamoto } 1229d67c46b9STakashi Sakamoto 12306aa7de05SMark Rutland return READ_ONCE(s->pcm_buffer_pointer); 1231d67c46b9STakashi Sakamoto } 1232f890f9a0STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stream_pcm_pointer); 1233d67c46b9STakashi Sakamoto 1234d67c46b9STakashi Sakamoto /** 1235e6dcc92fSTakashi Sakamoto * amdtp_domain_stream_pcm_ack - acknowledge queued PCM frames 1236e6dcc92fSTakashi Sakamoto * @d: the AMDTP domain. 1237875becf8STakashi Sakamoto * @s: the AMDTP stream that transfers the PCM frames 1238875becf8STakashi Sakamoto * 1239875becf8STakashi Sakamoto * Returns zero always. 1240875becf8STakashi Sakamoto */ 1241e6dcc92fSTakashi Sakamoto int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s) 1242875becf8STakashi Sakamoto { 1243e6dcc92fSTakashi Sakamoto struct amdtp_stream *irq_target = d->irq_target; 1244e6dcc92fSTakashi Sakamoto 1245e6dcc92fSTakashi Sakamoto // Process isochronous packets for recent isochronous cycle to handle 1246e6dcc92fSTakashi Sakamoto // queued PCM frames. 1247e6dcc92fSTakashi Sakamoto if (irq_target && amdtp_stream_running(irq_target)) { 1248e6dcc92fSTakashi Sakamoto // Queued packet should be processed without any kernel 1249e6dcc92fSTakashi Sakamoto // preemption to keep latency against bus cycle. 1250e6dcc92fSTakashi Sakamoto preempt_disable(); 1251e6dcc92fSTakashi Sakamoto fw_iso_context_flush_completions(irq_target->context); 1252e6dcc92fSTakashi Sakamoto preempt_enable(); 1253e6dcc92fSTakashi Sakamoto } 1254875becf8STakashi Sakamoto 1255875becf8STakashi Sakamoto return 0; 1256875becf8STakashi Sakamoto } 1257e6dcc92fSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stream_pcm_ack); 1258875becf8STakashi Sakamoto 1259875becf8STakashi Sakamoto /** 1260d67c46b9STakashi Sakamoto * amdtp_stream_update - update the stream after a bus reset 1261d67c46b9STakashi Sakamoto * @s: the AMDTP stream 1262d67c46b9STakashi Sakamoto */ 1263d67c46b9STakashi Sakamoto void amdtp_stream_update(struct amdtp_stream *s) 1264d67c46b9STakashi Sakamoto { 1265d67c46b9STakashi Sakamoto /* Precomputing. */ 12666aa7de05SMark Rutland WRITE_ONCE(s->source_node_id_field, 12676aa7de05SMark Rutland (fw_parent_device(s->unit)->card->node_id << CIP_SID_SHIFT) & CIP_SID_MASK); 1268d67c46b9STakashi Sakamoto } 1269d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_update); 1270d67c46b9STakashi Sakamoto 1271d67c46b9STakashi Sakamoto /** 1272d67c46b9STakashi Sakamoto * amdtp_stream_stop - stop sending packets 1273d67c46b9STakashi Sakamoto * @s: the AMDTP stream to stop 1274d67c46b9STakashi Sakamoto * 1275d67c46b9STakashi Sakamoto * All PCM and MIDI devices of the stream must be stopped before the stream 1276d67c46b9STakashi Sakamoto * itself can be stopped. 1277d67c46b9STakashi Sakamoto */ 127874f94e41STakashi Sakamoto static void amdtp_stream_stop(struct amdtp_stream *s) 1279d67c46b9STakashi Sakamoto { 1280d67c46b9STakashi Sakamoto mutex_lock(&s->mutex); 1281d67c46b9STakashi Sakamoto 1282d67c46b9STakashi Sakamoto if (!amdtp_stream_running(s)) { 1283d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1284d67c46b9STakashi Sakamoto return; 1285d67c46b9STakashi Sakamoto } 1286d67c46b9STakashi Sakamoto 12872b3d2987STakashi Iwai cancel_work_sync(&s->period_work); 1288d67c46b9STakashi Sakamoto fw_iso_context_stop(s->context); 1289d67c46b9STakashi Sakamoto fw_iso_context_destroy(s->context); 1290d67c46b9STakashi Sakamoto s->context = ERR_PTR(-1); 1291d67c46b9STakashi Sakamoto iso_packets_buffer_destroy(&s->buffer, s->unit); 129204130cf8STakashi Sakamoto kfree(s->pkt_descs); 1293d67c46b9STakashi Sakamoto 1294d67c46b9STakashi Sakamoto s->callbacked = false; 1295d67c46b9STakashi Sakamoto 1296d67c46b9STakashi Sakamoto mutex_unlock(&s->mutex); 1297d67c46b9STakashi Sakamoto } 1298d67c46b9STakashi Sakamoto 1299d67c46b9STakashi Sakamoto /** 1300d67c46b9STakashi Sakamoto * amdtp_stream_pcm_abort - abort the running PCM device 1301d67c46b9STakashi Sakamoto * @s: the AMDTP stream about to be stopped 1302d67c46b9STakashi Sakamoto * 1303d67c46b9STakashi Sakamoto * If the isochronous stream needs to be stopped asynchronously, call this 1304d67c46b9STakashi Sakamoto * function first to stop the PCM device. 1305d67c46b9STakashi Sakamoto */ 1306d67c46b9STakashi Sakamoto void amdtp_stream_pcm_abort(struct amdtp_stream *s) 1307d67c46b9STakashi Sakamoto { 1308d67c46b9STakashi Sakamoto struct snd_pcm_substream *pcm; 1309d67c46b9STakashi Sakamoto 13106aa7de05SMark Rutland pcm = READ_ONCE(s->pcm); 1311d67c46b9STakashi Sakamoto if (pcm) 1312d67c46b9STakashi Sakamoto snd_pcm_stop_xrun(pcm); 1313d67c46b9STakashi Sakamoto } 1314d67c46b9STakashi Sakamoto EXPORT_SYMBOL(amdtp_stream_pcm_abort); 13153ec3d7a3STakashi Sakamoto 13163ec3d7a3STakashi Sakamoto /** 13173ec3d7a3STakashi Sakamoto * amdtp_domain_init - initialize an AMDTP domain structure 13183ec3d7a3STakashi Sakamoto * @d: the AMDTP domain to initialize. 13193ec3d7a3STakashi Sakamoto */ 13203ec3d7a3STakashi Sakamoto int amdtp_domain_init(struct amdtp_domain *d) 13213ec3d7a3STakashi Sakamoto { 13223ec3d7a3STakashi Sakamoto INIT_LIST_HEAD(&d->streams); 13233ec3d7a3STakashi Sakamoto 1324d68c3123STakashi Sakamoto d->events_per_period = 0; 1325d68c3123STakashi Sakamoto 1326*d32872f3STakashi Sakamoto d->seq.descs = NULL; 132725babf29STakashi Sakamoto 13283ec3d7a3STakashi Sakamoto return 0; 13293ec3d7a3STakashi Sakamoto } 13303ec3d7a3STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_init); 13313ec3d7a3STakashi Sakamoto 13323ec3d7a3STakashi Sakamoto /** 13333ec3d7a3STakashi Sakamoto * amdtp_domain_destroy - destroy an AMDTP domain structure 13343ec3d7a3STakashi Sakamoto * @d: the AMDTP domain to destroy. 13353ec3d7a3STakashi Sakamoto */ 13363ec3d7a3STakashi Sakamoto void amdtp_domain_destroy(struct amdtp_domain *d) 13373ec3d7a3STakashi Sakamoto { 13388d0d5c3fSTakashi Sakamoto // At present nothing to do. 13398d0d5c3fSTakashi Sakamoto return; 13403ec3d7a3STakashi Sakamoto } 13413ec3d7a3STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_destroy); 13426261f90bSTakashi Sakamoto 13436261f90bSTakashi Sakamoto /** 1344157a53eeSTakashi Sakamoto * amdtp_domain_add_stream - register isoc context into the domain. 1345157a53eeSTakashi Sakamoto * @d: the AMDTP domain. 1346157a53eeSTakashi Sakamoto * @s: the AMDTP stream. 1347157a53eeSTakashi Sakamoto * @channel: the isochronous channel on the bus. 1348157a53eeSTakashi Sakamoto * @speed: firewire speed code. 1349157a53eeSTakashi Sakamoto */ 1350157a53eeSTakashi Sakamoto int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, 1351157a53eeSTakashi Sakamoto int channel, int speed) 1352157a53eeSTakashi Sakamoto { 1353157a53eeSTakashi Sakamoto struct amdtp_stream *tmp; 1354157a53eeSTakashi Sakamoto 1355157a53eeSTakashi Sakamoto list_for_each_entry(tmp, &d->streams, list) { 1356157a53eeSTakashi Sakamoto if (s == tmp) 1357157a53eeSTakashi Sakamoto return -EBUSY; 1358157a53eeSTakashi Sakamoto } 1359157a53eeSTakashi Sakamoto 1360157a53eeSTakashi Sakamoto list_add(&s->list, &d->streams); 1361157a53eeSTakashi Sakamoto 1362157a53eeSTakashi Sakamoto s->channel = channel; 1363157a53eeSTakashi Sakamoto s->speed = speed; 13642472cfb3STakashi Sakamoto s->domain = d; 1365157a53eeSTakashi Sakamoto 1366157a53eeSTakashi Sakamoto return 0; 1367157a53eeSTakashi Sakamoto } 1368157a53eeSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_add_stream); 1369157a53eeSTakashi Sakamoto 1370acfedcbeSTakashi Sakamoto static int get_current_cycle_time(struct fw_card *fw_card, int *cur_cycle) 1371acfedcbeSTakashi Sakamoto { 1372acfedcbeSTakashi Sakamoto int generation; 1373acfedcbeSTakashi Sakamoto int rcode; 1374acfedcbeSTakashi Sakamoto __be32 reg; 1375acfedcbeSTakashi Sakamoto u32 data; 1376acfedcbeSTakashi Sakamoto 1377acfedcbeSTakashi Sakamoto // This is a request to local 1394 OHCI controller and expected to 1378acfedcbeSTakashi Sakamoto // complete without any event waiting. 1379acfedcbeSTakashi Sakamoto generation = fw_card->generation; 1380acfedcbeSTakashi Sakamoto smp_rmb(); // node_id vs. generation. 1381acfedcbeSTakashi Sakamoto rcode = fw_run_transaction(fw_card, TCODE_READ_QUADLET_REQUEST, 1382acfedcbeSTakashi Sakamoto fw_card->node_id, generation, SCODE_100, 1383acfedcbeSTakashi Sakamoto CSR_REGISTER_BASE + CSR_CYCLE_TIME, 1384acfedcbeSTakashi Sakamoto ®, sizeof(reg)); 1385acfedcbeSTakashi Sakamoto if (rcode != RCODE_COMPLETE) 1386acfedcbeSTakashi Sakamoto return -EIO; 1387acfedcbeSTakashi Sakamoto 1388acfedcbeSTakashi Sakamoto data = be32_to_cpu(reg); 1389acfedcbeSTakashi Sakamoto *cur_cycle = data >> 12; 1390acfedcbeSTakashi Sakamoto 1391acfedcbeSTakashi Sakamoto return 0; 1392acfedcbeSTakashi Sakamoto } 1393acfedcbeSTakashi Sakamoto 1394157a53eeSTakashi Sakamoto /** 13959b4702b0STakashi Sakamoto * amdtp_domain_start - start sending packets for isoc context in the domain. 13969b4702b0STakashi Sakamoto * @d: the AMDTP domain. 1397acfedcbeSTakashi Sakamoto * @ir_delay_cycle: the cycle delay to start all IR contexts. 13989b4702b0STakashi Sakamoto */ 1399acfedcbeSTakashi Sakamoto int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle) 14009b4702b0STakashi Sakamoto { 14011a4be183STakashi Sakamoto static const struct { 14021a4be183STakashi Sakamoto unsigned int data_block; 14031a4be183STakashi Sakamoto unsigned int syt_offset; 14041a4be183STakashi Sakamoto } *entry, initial_state[] = { 14051a4be183STakashi Sakamoto [CIP_SFC_32000] = { 4, 3072 }, 14061a4be183STakashi Sakamoto [CIP_SFC_48000] = { 6, 1024 }, 14071a4be183STakashi Sakamoto [CIP_SFC_96000] = { 12, 1024 }, 14081a4be183STakashi Sakamoto [CIP_SFC_192000] = { 24, 1024 }, 14091a4be183STakashi Sakamoto [CIP_SFC_44100] = { 0, 67 }, 14101a4be183STakashi Sakamoto [CIP_SFC_88200] = { 0, 67 }, 14111a4be183STakashi Sakamoto [CIP_SFC_176400] = { 0, 67 }, 14121a4be183STakashi Sakamoto }; 1413af86b0b1STakashi Sakamoto unsigned int events_per_buffer = d->events_per_buffer; 1414af86b0b1STakashi Sakamoto unsigned int events_per_period = d->events_per_period; 1415af86b0b1STakashi Sakamoto unsigned int idle_irq_interval; 1416af86b0b1STakashi Sakamoto unsigned int queue_size; 14179b4702b0STakashi Sakamoto struct amdtp_stream *s; 1418acfedcbeSTakashi Sakamoto int cycle; 1419acfedcbeSTakashi Sakamoto int err; 14209b4702b0STakashi Sakamoto 142160dd4929STakashi Sakamoto // Select an IT context as IRQ target. 14229b4702b0STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 142360dd4929STakashi Sakamoto if (s->direction == AMDTP_OUT_STREAM) 14249b4702b0STakashi Sakamoto break; 14259b4702b0STakashi Sakamoto } 142660dd4929STakashi Sakamoto if (!s) 142760dd4929STakashi Sakamoto return -ENXIO; 142860dd4929STakashi Sakamoto d->irq_target = s; 14299b4702b0STakashi Sakamoto 1430af86b0b1STakashi Sakamoto // This is a case that AMDTP streams in domain run just for MIDI 1431af86b0b1STakashi Sakamoto // substream. Use the number of events equivalent to 10 msec as 1432af86b0b1STakashi Sakamoto // interval of hardware IRQ. 1433af86b0b1STakashi Sakamoto if (events_per_period == 0) 1434af86b0b1STakashi Sakamoto events_per_period = amdtp_rate_table[d->irq_target->sfc] / 100; 1435af86b0b1STakashi Sakamoto if (events_per_buffer == 0) 1436af86b0b1STakashi Sakamoto events_per_buffer = events_per_period * 3; 1437af86b0b1STakashi Sakamoto 1438af86b0b1STakashi Sakamoto queue_size = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_buffer, 1439af86b0b1STakashi Sakamoto amdtp_rate_table[d->irq_target->sfc]); 1440af86b0b1STakashi Sakamoto 1441*d32872f3STakashi Sakamoto d->seq.descs = kcalloc(queue_size, sizeof(*d->seq.descs), GFP_KERNEL); 1442*d32872f3STakashi Sakamoto if (!d->seq.descs) 144325babf29STakashi Sakamoto return -ENOMEM; 1444*d32872f3STakashi Sakamoto d->seq.size = queue_size; 1445*d32872f3STakashi Sakamoto d->seq.tail = 0; 144625babf29STakashi Sakamoto 14471a4be183STakashi Sakamoto entry = &initial_state[s->sfc]; 14481a4be183STakashi Sakamoto d->data_block_state = entry->data_block; 14491a4be183STakashi Sakamoto d->syt_offset_state = entry->syt_offset; 14501a4be183STakashi Sakamoto d->last_syt_offset = TICKS_PER_CYCLE; 14511a4be183STakashi Sakamoto 1452acfedcbeSTakashi Sakamoto if (ir_delay_cycle > 0) { 1453acfedcbeSTakashi Sakamoto struct fw_card *fw_card = fw_parent_device(s->unit)->card; 1454acfedcbeSTakashi Sakamoto 1455acfedcbeSTakashi Sakamoto err = get_current_cycle_time(fw_card, &cycle); 1456acfedcbeSTakashi Sakamoto if (err < 0) 145725babf29STakashi Sakamoto goto error; 1458acfedcbeSTakashi Sakamoto 1459acfedcbeSTakashi Sakamoto // No need to care overflow in cycle field because of enough 1460acfedcbeSTakashi Sakamoto // width. 1461acfedcbeSTakashi Sakamoto cycle += ir_delay_cycle; 1462acfedcbeSTakashi Sakamoto 1463acfedcbeSTakashi Sakamoto // Round up to sec field. 1464acfedcbeSTakashi Sakamoto if ((cycle & 0x00001fff) >= CYCLES_PER_SECOND) { 1465acfedcbeSTakashi Sakamoto unsigned int sec; 1466acfedcbeSTakashi Sakamoto 1467acfedcbeSTakashi Sakamoto // The sec field can overflow. 1468acfedcbeSTakashi Sakamoto sec = (cycle & 0xffffe000) >> 13; 1469acfedcbeSTakashi Sakamoto cycle = (++sec << 13) | 1470acfedcbeSTakashi Sakamoto ((cycle & 0x00001fff) / CYCLES_PER_SECOND); 1471acfedcbeSTakashi Sakamoto } 1472acfedcbeSTakashi Sakamoto 1473acfedcbeSTakashi Sakamoto // In OHCI 1394 specification, lower 2 bits are available for 1474acfedcbeSTakashi Sakamoto // sec field. 1475acfedcbeSTakashi Sakamoto cycle &= 0x00007fff; 1476acfedcbeSTakashi Sakamoto } else { 1477acfedcbeSTakashi Sakamoto cycle = -1; 1478acfedcbeSTakashi Sakamoto } 1479acfedcbeSTakashi Sakamoto 148060dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) { 1481acfedcbeSTakashi Sakamoto int cycle_match; 1482acfedcbeSTakashi Sakamoto 1483acfedcbeSTakashi Sakamoto if (s->direction == AMDTP_IN_STREAM) { 1484acfedcbeSTakashi Sakamoto cycle_match = cycle; 1485acfedcbeSTakashi Sakamoto } else { 1486acfedcbeSTakashi Sakamoto // IT context starts immediately. 1487acfedcbeSTakashi Sakamoto cycle_match = -1; 14881a4be183STakashi Sakamoto s->ctx_data.rx.seq_index = 0; 1489acfedcbeSTakashi Sakamoto } 1490acfedcbeSTakashi Sakamoto 149160dd4929STakashi Sakamoto if (s != d->irq_target) { 14922472cfb3STakashi Sakamoto err = amdtp_stream_start(s, s->channel, s->speed, 1493af86b0b1STakashi Sakamoto cycle_match, queue_size, 0); 149460dd4929STakashi Sakamoto if (err < 0) 149560dd4929STakashi Sakamoto goto error; 149660dd4929STakashi Sakamoto } 14979b4702b0STakashi Sakamoto } 14989b4702b0STakashi Sakamoto 149960dd4929STakashi Sakamoto s = d->irq_target; 1500af86b0b1STakashi Sakamoto s->ctx_data.rx.event_count = 0; 15011a4be183STakashi Sakamoto s->ctx_data.rx.seq_index = 0; 1502af86b0b1STakashi Sakamoto 1503af86b0b1STakashi Sakamoto idle_irq_interval = DIV_ROUND_UP(CYCLES_PER_SECOND * events_per_period, 1504af86b0b1STakashi Sakamoto amdtp_rate_table[d->irq_target->sfc]); 1505af86b0b1STakashi Sakamoto err = amdtp_stream_start(s, s->channel, s->speed, -1, queue_size, 1506af86b0b1STakashi Sakamoto idle_irq_interval); 150760dd4929STakashi Sakamoto if (err < 0) 150860dd4929STakashi Sakamoto goto error; 150960dd4929STakashi Sakamoto 151060dd4929STakashi Sakamoto return 0; 151160dd4929STakashi Sakamoto error: 151260dd4929STakashi Sakamoto list_for_each_entry(s, &d->streams, list) 151360dd4929STakashi Sakamoto amdtp_stream_stop(s); 1514*d32872f3STakashi Sakamoto kfree(d->seq.descs); 1515*d32872f3STakashi Sakamoto d->seq.descs = NULL; 15169b4702b0STakashi Sakamoto return err; 15179b4702b0STakashi Sakamoto } 15189b4702b0STakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_start); 15199b4702b0STakashi Sakamoto 15209b4702b0STakashi Sakamoto /** 15216261f90bSTakashi Sakamoto * amdtp_domain_stop - stop sending packets for isoc context in the same domain. 15226261f90bSTakashi Sakamoto * @d: the AMDTP domain to which the isoc contexts belong. 15236261f90bSTakashi Sakamoto */ 15246261f90bSTakashi Sakamoto void amdtp_domain_stop(struct amdtp_domain *d) 15256261f90bSTakashi Sakamoto { 15266261f90bSTakashi Sakamoto struct amdtp_stream *s, *next; 15276261f90bSTakashi Sakamoto 152860dd4929STakashi Sakamoto if (d->irq_target) 152960dd4929STakashi Sakamoto amdtp_stream_stop(d->irq_target); 153060dd4929STakashi Sakamoto 15316261f90bSTakashi Sakamoto list_for_each_entry_safe(s, next, &d->streams, list) { 15326261f90bSTakashi Sakamoto list_del(&s->list); 15336261f90bSTakashi Sakamoto 153460dd4929STakashi Sakamoto if (s != d->irq_target) 15356261f90bSTakashi Sakamoto amdtp_stream_stop(s); 15366261f90bSTakashi Sakamoto } 1537d68c3123STakashi Sakamoto 1538d68c3123STakashi Sakamoto d->events_per_period = 0; 153960dd4929STakashi Sakamoto d->irq_target = NULL; 154025babf29STakashi Sakamoto 1541*d32872f3STakashi Sakamoto kfree(d->seq.descs); 1542*d32872f3STakashi Sakamoto d->seq.descs = NULL; 15436261f90bSTakashi Sakamoto } 15446261f90bSTakashi Sakamoto EXPORT_SYMBOL_GPL(amdtp_domain_stop); 1545