Lines Matching +full:timer +full:- +full:dsp
1 // SPDX-License-Identifier: GPL-2.0-or-later
36 /* registers used on the DSP (port 2) */
59 #define PCXHR_INPB(mgr,x) inb((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
60 #define PCXHR_INPL(mgr,x) inl((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
61 #define PCXHR_OUTPB(mgr,x,data) outb((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
62 #define PCXHR_OUTPL(mgr,x,data) outl((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
105 * pcxhr_check_reg_bit - wait for the specified bit is set/reset on a register
109 * @time: time-out of loop in msec
123 dev_dbg(&mgr->pci->dev, in pcxhr_check_reg_bit()
130 dev_err(&mgr->pci->dev, in pcxhr_check_reg_bit()
133 return -EIO; in pcxhr_check_reg_bit()
207 dev_err(&mgr->pci->dev, "pcxhr_send_it_dsp : TIMEOUT CVR\n"); in pcxhr_send_it_dsp()
218 dev_err(&mgr->pci->dev, in pcxhr_send_it_dsp()
249 /* let's reset the DSP */ in pcxhr_reset_dsp()
285 dev_err(&mgr->pci->dev, "error loading first xilinx\n"); in pcxhr_load_xilinx_binary()
286 return -EINVAL; in pcxhr_load_xilinx_binary()
293 image = xilinx->data; in pcxhr_load_xilinx_binary()
294 for (i = 0; i < xilinx->size; i++, image++) { in pcxhr_load_xilinx_binary()
318 * send an executable file to the DSP
320 static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp) in pcxhr_download_dsp() argument
328 if (dsp->size <= 0) in pcxhr_download_dsp()
329 return -EINVAL; in pcxhr_download_dsp()
330 if (dsp->size % 3) in pcxhr_download_dsp()
331 return -EINVAL; in pcxhr_download_dsp()
332 if (snd_BUG_ON(!dsp->data)) in pcxhr_download_dsp()
333 return -EINVAL; in pcxhr_download_dsp()
334 /* transfert data buffer from PC to DSP */ in pcxhr_download_dsp()
335 for (i = 0; i < dsp->size; i += 3) { in pcxhr_download_dsp()
336 data = dsp->data + i; in pcxhr_download_dsp()
342 if (len && (dsp->size != (len + 2) * 3)) in pcxhr_download_dsp()
343 return -EINVAL; in pcxhr_download_dsp()
345 /* wait DSP ready for new transfer */ in pcxhr_download_dsp()
351 dev_err(&mgr->pci->dev, in pcxhr_download_dsp()
352 "dsp loading error at position %d\n", i); in pcxhr_download_dsp()
363 /* give some time to boot the DSP */ in pcxhr_download_dsp()
387 dev_dbg(&mgr->pci->dev, "no need to load eeprom boot\n"); in pcxhr_load_eeprom_binary()
406 unsigned int physaddr = mgr->hostport.addr; in pcxhr_load_boot_binary()
409 /* send the hostport address to the DSP (only the upper 24 bit !) */ in pcxhr_load_boot_binary()
411 return -EINVAL; in pcxhr_load_boot_binary()
430 * load the final dsp image
432 int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp) in pcxhr_load_dsp_binary() argument
442 err = pcxhr_download_dsp(mgr, dsp); in pcxhr_load_dsp_binary()
467 * Array of DSP commands
541 if (rmh->stat_len < PCXHR_SIZE_MAX_STATUS) in pcxhr_read_rmh_status()
543 else max_stat_len = rmh->stat_len; in pcxhr_read_rmh_status()
545 for (i = 0; i < rmh->stat_len; i++) { in pcxhr_read_rmh_status()
552 dev_err(&mgr->pci->dev, in pcxhr_read_rmh_status()
562 /* need to update rmh->stat_len on the fly ?? */ in pcxhr_read_rmh_status()
564 if (rmh->dsp_stat != RMH_SSIZE_FIXED) { in pcxhr_read_rmh_status()
565 if (rmh->dsp_stat == RMH_SSIZE_ARG) { in pcxhr_read_rmh_status()
566 rmh->stat_len = (data & 0x0000ff) + 1; in pcxhr_read_rmh_status()
569 /* rmh->dsp_stat == RMH_SSIZE_MASK */ in pcxhr_read_rmh_status()
570 rmh->stat_len = 1; in pcxhr_read_rmh_status()
574 rmh->stat_len++; in pcxhr_read_rmh_status()
581 if (rmh->cmd_idx < CMD_LAST_INDEX) in pcxhr_read_rmh_status()
582 dev_dbg(&mgr->pci->dev, " stat[%d]=%x\n", i, data); in pcxhr_read_rmh_status()
585 rmh->stat[i] = data; in pcxhr_read_rmh_status()
587 if (rmh->stat_len > max_stat_len) { in pcxhr_read_rmh_status()
588 dev_dbg(&mgr->pci->dev, "PCXHR : rmh->stat_len=%x too big\n", in pcxhr_read_rmh_status()
589 rmh->stat_len); in pcxhr_read_rmh_status()
590 rmh->stat_len = max_stat_len; in pcxhr_read_rmh_status()
602 if (snd_BUG_ON(rmh->cmd_len >= PCXHR_SIZE_MAX_CMD)) in pcxhr_send_msg_nolock()
603 return -EINVAL; in pcxhr_send_msg_nolock()
606 dev_err(&mgr->pci->dev, in pcxhr_send_msg_nolock()
625 data = rmh->cmd[0]; in pcxhr_send_msg_nolock()
627 if (rmh->cmd_len > 1) in pcxhr_send_msg_nolock()
632 if (rmh->cmd_idx < CMD_LAST_INDEX) in pcxhr_send_msg_nolock()
633 dev_dbg(&mgr->pci->dev, "MSG cmd[0]=%x (%s)\n", in pcxhr_send_msg_nolock()
634 data, cmd_names[rmh->cmd_idx]); in pcxhr_send_msg_nolock()
645 if (rmh->cmd_len > 1) { in pcxhr_send_msg_nolock()
647 data = rmh->cmd_len - 1; in pcxhr_send_msg_nolock()
658 for (i=1; i < rmh->cmd_len; i++) { in pcxhr_send_msg_nolock()
660 data = rmh->cmd[i]; in pcxhr_send_msg_nolock()
662 if (rmh->cmd_idx < CMD_LAST_INDEX) in pcxhr_send_msg_nolock()
663 dev_dbg(&mgr->pci->dev, in pcxhr_send_msg_nolock()
690 dev_err(&mgr->pci->dev, in pcxhr_send_msg_nolock()
698 dev_err(&mgr->pci->dev, "ERROR RMH(%d): 0x%x\n", in pcxhr_send_msg_nolock()
699 rmh->cmd_idx, data); in pcxhr_send_msg_nolock()
700 err = -EINVAL; in pcxhr_send_msg_nolock()
707 return -EIO; in pcxhr_send_msg_nolock()
713 * pcxhr_init_rmh - initialize the RMH instance
721 rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode; in pcxhr_init_rmh()
722 rmh->cmd_len = 1; in pcxhr_init_rmh()
723 rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length; in pcxhr_init_rmh()
724 rmh->dsp_stat = pcxhr_dsp_cmds[cmd].st_type; in pcxhr_init_rmh()
725 rmh->cmd_idx = cmd; in pcxhr_init_rmh()
735 rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */ in pcxhr_set_pipe_cmd_params()
737 rmh->cmd[0] |= (param1 << FIELD_SIZE); in pcxhr_set_pipe_cmd_params()
740 rmh->cmd[0] |= param2; in pcxhr_set_pipe_cmd_params()
744 rmh->cmd[1] = param3; in pcxhr_set_pipe_cmd_params()
745 rmh->cmd_len = 2; in pcxhr_set_pipe_cmd_params()
750 * pcxhr_send_msg - send a DSP message with spinlock
759 mutex_lock(&mgr->msg_lock); in pcxhr_send_msg()
761 mutex_unlock(&mgr->msg_lock); in pcxhr_send_msg()
774 dev_dbg(&mgr->pci->dev, "CMD_PIPE_STATE MBOX2=0x%06x\n", start_mask); in pcxhr_pipes_running()
797 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - in pcxhr_prepair_pipe_start()
803 dev_err(&mgr->pci->dev, in pcxhr_prepair_pipe_start()
835 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - in pcxhr_stop_pipes()
841 dev_err(&mgr->pci->dev, in pcxhr_stop_pipes()
867 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET)); in pcxhr_toggle_pipes()
870 dev_err(&mgr->pci->dev, in pcxhr_toggle_pipes()
883 dev_err(&mgr->pci->dev, in pcxhr_toggle_pipes()
908 dev_dbg(&mgr->pci->dev, in pcxhr_set_pipe_state()
940 dev_err(&mgr->pci->dev, "error pipe start/stop\n"); in pcxhr_set_pipe_state()
941 return -EBUSY; in pcxhr_set_pipe_state()
953 dev_dbg(&mgr->pci->dev, "***SET PIPE STATE*** TIME = %ld (err = %x)\n", in pcxhr_set_pipe_state()
965 mutex_lock(&mgr->msg_lock); in pcxhr_write_io_num_reg_cont()
966 if ((mgr->io_num_reg_cont & mask) == value) { in pcxhr_write_io_num_reg_cont()
967 dev_dbg(&mgr->pci->dev, in pcxhr_write_io_num_reg_cont()
972 mutex_unlock(&mgr->msg_lock); in pcxhr_write_io_num_reg_cont()
982 mgr->io_num_reg_cont &= ~mask; in pcxhr_write_io_num_reg_cont()
983 mgr->io_num_reg_cont |= value; in pcxhr_write_io_num_reg_cont()
987 mutex_unlock(&mgr->msg_lock); in pcxhr_write_io_num_reg_cont()
1021 dev_dbg(&mgr->pci->dev, "CMD_ASYNC : Error %s %s Pipe %d err=%x\n", in pcxhr_handle_async_err()
1025 mgr->async_err_stream_xrun++; in pcxhr_handle_async_err()
1027 mgr->async_err_pipe_xrun++; in pcxhr_handle_async_err()
1029 mgr->async_err_other_last = (int)err; in pcxhr_handle_async_err()
1036 struct pcxhr_rmh *prmh = mgr->prmh; in pcxhr_msg_thread()
1040 if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE) in pcxhr_msg_thread()
1041 dev_dbg(&mgr->pci->dev, in pcxhr_msg_thread()
1043 if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE) in pcxhr_msg_thread()
1044 dev_dbg(&mgr->pci->dev, in pcxhr_msg_thread()
1046 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) in pcxhr_msg_thread()
1047 dev_dbg(&mgr->pci->dev, in pcxhr_msg_thread()
1049 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) { in pcxhr_msg_thread()
1053 dev_dbg(&mgr->pci->dev, "CMD_TEST_IT : err=%x, stat=%x\n", in pcxhr_msg_thread()
1054 err, prmh->stat[0]); in pcxhr_msg_thread()
1056 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { in pcxhr_msg_thread()
1057 dev_dbg(&mgr->pci->dev, in pcxhr_msg_thread()
1061 prmh->cmd[0] |= 1; /* add SEL_ASYNC_EVENTS */ in pcxhr_msg_thread()
1063 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS; in pcxhr_msg_thread()
1066 dev_err(&mgr->pci->dev, "ERROR pcxhr_msg_thread=%x;\n", in pcxhr_msg_thread()
1069 while (i < prmh->stat_len) { in pcxhr_msg_thread()
1070 int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) & in pcxhr_msg_thread()
1072 int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) & in pcxhr_msg_thread()
1074 int pipe = prmh->stat[i] & MASK_FIRST_FIELD; in pcxhr_msg_thread()
1075 int is_capture = prmh->stat[i] & 0x400000; in pcxhr_msg_thread()
1078 if (prmh->stat[i] & 0x800000) { /* if BIT_END */ in pcxhr_msg_thread()
1079 dev_dbg(&mgr->pci->dev, in pcxhr_msg_thread()
1085 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1]; in pcxhr_msg_thread()
1092 err2 = prmh->stat[i] ? in pcxhr_msg_thread()
1093 prmh->stat[i] : prmh->stat[i+1]; in pcxhr_msg_thread()
1102 err2 = prmh->stat[i] ? in pcxhr_msg_thread()
1103 prmh->stat[i] : prmh->stat[i+1]; in pcxhr_msg_thread()
1122 stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number; in pcxhr_stream_read_position()
1126 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, in pcxhr_stream_read_position()
1127 stream->pipe->first_audio, 0, stream_mask); in pcxhr_stream_read_position()
1137 dev_dbg(&mgr->pci->dev, in pcxhr_stream_read_position()
1138 "stream %c%d : abs samples real(%llu) timer(%llu)\n", in pcxhr_stream_read_position()
1139 stream->pipe->is_capture ? 'C' : 'P', in pcxhr_stream_read_position()
1140 stream->substream->number, in pcxhr_stream_read_position()
1142 stream->timer_abs_periods + stream->timer_period_frag + in pcxhr_stream_read_position()
1143 mgr->granularity); in pcxhr_stream_read_position()
1151 if (stream->substream && in pcxhr_update_timer_pos()
1152 (stream->status == PCXHR_STREAM_STATUS_RUNNING)) { in pcxhr_update_timer_pos()
1156 struct snd_pcm_runtime *runtime = stream->substream->runtime; in pcxhr_update_timer_pos()
1159 stream->timer_is_synced = 0; in pcxhr_update_timer_pos()
1161 samples_to_add = mgr->granularity; in pcxhr_update_timer_pos()
1164 if (!stream->timer_is_synced) { in pcxhr_update_timer_pos()
1165 if ((stream->timer_abs_periods != 0) || in pcxhr_update_timer_pos()
1166 ((stream->timer_period_frag + samples_to_add) >= in pcxhr_update_timer_pos()
1167 runtime->period_size)) { in pcxhr_update_timer_pos()
1171 if (new_sample_count >= mgr->granularity) { in pcxhr_update_timer_pos()
1174 * dsp time (MBOX4) in pcxhr_update_timer_pos()
1176 new_sample_count -= mgr->granularity; in pcxhr_update_timer_pos()
1177 stream->timer_is_synced = 1; in pcxhr_update_timer_pos()
1183 * by PCXHR_GRANULARITY every timer interrupt in pcxhr_update_timer_pos()
1185 new_sample_count = stream->timer_abs_periods + in pcxhr_update_timer_pos()
1186 stream->timer_period_frag + samples_to_add; in pcxhr_update_timer_pos()
1189 u_int64_t new_elapse_pos = stream->timer_abs_periods + in pcxhr_update_timer_pos()
1190 runtime->period_size; in pcxhr_update_timer_pos()
1194 stream->timer_buf_periods++; in pcxhr_update_timer_pos()
1195 if (stream->timer_buf_periods >= runtime->periods) in pcxhr_update_timer_pos()
1196 stream->timer_buf_periods = 0; in pcxhr_update_timer_pos()
1197 stream->timer_abs_periods = new_elapse_pos; in pcxhr_update_timer_pos()
1199 if (new_sample_count >= stream->timer_abs_periods) { in pcxhr_update_timer_pos()
1200 stream->timer_period_frag = in pcxhr_update_timer_pos()
1201 (u_int32_t)(new_sample_count - in pcxhr_update_timer_pos()
1202 stream->timer_abs_periods); in pcxhr_update_timer_pos()
1204 dev_err(&mgr->pci->dev, in pcxhr_update_timer_pos()
1210 mutex_unlock(&mgr->lock); in pcxhr_update_timer_pos()
1211 snd_pcm_period_elapsed(stream->substream); in pcxhr_update_timer_pos()
1212 mutex_lock(&mgr->lock); in pcxhr_update_timer_pos()
1233 /* timer irq occurred */ in pcxhr_interrupt()
1236 if (timer_toggle == mgr->timer_toggle) { in pcxhr_interrupt()
1237 dev_dbg(&mgr->pci->dev, "ERROR TIMER TOGGLE\n"); in pcxhr_interrupt()
1238 mgr->dsp_time_err++; in pcxhr_interrupt()
1241 mgr->timer_toggle = timer_toggle; in pcxhr_interrupt()
1242 mgr->src_it_dsp = reg; in pcxhr_interrupt()
1253 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; in pcxhr_interrupt()
1255 mgr->src_it_dsp = reg; in pcxhr_interrupt()
1260 dev_dbg(&mgr->pci->dev, "FATAL DSP ERROR : %x\n", reg); in pcxhr_interrupt()
1272 mutex_lock(&mgr->lock); in pcxhr_threaded_irq()
1273 if (mgr->src_it_dsp & PCXHR_IRQ_TIMER) { in pcxhr_threaded_irq()
1277 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last; in pcxhr_threaded_irq()
1280 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { in pcxhr_threaded_irq()
1281 /* handle dsp counter wraparound without resync */ in pcxhr_threaded_irq()
1283 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1284 "WARNING DSP timestamp old(%d) new(%d)", in pcxhr_threaded_irq()
1285 mgr->dsp_time_last, dsp_time_new); in pcxhr_threaded_irq()
1286 if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) { in pcxhr_threaded_irq()
1287 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1288 "-> timestamp wraparound OK: " in pcxhr_threaded_irq()
1292 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1293 "-> resynchronize all streams\n"); in pcxhr_threaded_irq()
1294 mgr->dsp_time_err++; in pcxhr_threaded_irq()
1299 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1300 "ERROR DSP TIME NO DIFF time(%d)\n", in pcxhr_threaded_irq()
1302 else if (dsp_time_diff >= (2*mgr->granularity)) in pcxhr_threaded_irq()
1303 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1304 "ERROR DSP TIME TOO BIG old(%d) add(%d)\n", in pcxhr_threaded_irq()
1305 mgr->dsp_time_last, in pcxhr_threaded_irq()
1306 dsp_time_new - mgr->dsp_time_last); in pcxhr_threaded_irq()
1307 else if (dsp_time_diff % mgr->granularity) in pcxhr_threaded_irq()
1308 dev_dbg(&mgr->pci->dev, in pcxhr_threaded_irq()
1309 "ERROR DSP TIME increased by %d\n", in pcxhr_threaded_irq()
1312 mgr->dsp_time_last = dsp_time_new; in pcxhr_threaded_irq()
1314 for (i = 0; i < mgr->num_cards; i++) { in pcxhr_threaded_irq()
1315 chip = mgr->chip[i]; in pcxhr_threaded_irq()
1316 for (j = 0; j < chip->nb_streams_capt; j++) in pcxhr_threaded_irq()
1318 &chip->capture_stream[j], in pcxhr_threaded_irq()
1321 for (i = 0; i < mgr->num_cards; i++) { in pcxhr_threaded_irq()
1322 chip = mgr->chip[i]; in pcxhr_threaded_irq()
1323 for (j = 0; j < chip->nb_streams_play; j++) in pcxhr_threaded_irq()
1325 &chip->playback_stream[j], in pcxhr_threaded_irq()
1331 mutex_unlock(&mgr->lock); in pcxhr_threaded_irq()