Пример #1
0
/**
 * abe_write_fifo
 * @mem_bank: currently only ABE_DMEM supported
 * @addr: FIFO descriptor address ( descriptor fields : READ ptr, WRITE ptr,
 * FIFO START_ADDR, FIFO END_ADDR)
 * @data: data to write to FIFO
 * @number: number of 32-bit words to write to DMEM FIFO
 *
 * write DMEM FIFO and update FIFO descriptor,
 * it is assumed that FIFO descriptor is located in DMEM
 */
void abe_write_fifo(u32 memory_bank, u32 descr_addr, u32 *data, u32 nb_data32)
{
	u32 fifo_addr[4];
	u32 i;
	/* read FIFO descriptor from DMEM */
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, descr_addr,
		       &fifo_addr[0], 4 * sizeof(u32));
	/* WRITE ptr < FIFO start address */
	if (fifo_addr[1] < fifo_addr[2])
		abe_dbg_error_log(ABE_FW_FIFO_WRITE_PTR_ERR);
	/* WRITE ptr > FIFO end address */
	if (fifo_addr[1] > fifo_addr[3])
		abe_dbg_error_log(ABE_FW_FIFO_WRITE_PTR_ERR);
	switch (memory_bank) {
	case ABE_DMEM:
		for (i = 0; i < nb_data32; i++) {
			abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM,
				       (s32) fifo_addr[1], (u32 *) (data + i),
				       4);
			/* increment WRITE pointer */
			fifo_addr[1] = fifo_addr[1] + 4;
			if (fifo_addr[1] > fifo_addr[3])
				fifo_addr[1] = fifo_addr[2];
			if (fifo_addr[1] == fifo_addr[0])
				abe_dbg_error_log(ABE_FW_FIFO_WRITE_PTR_ERR);
		}
		/* update WRITE pointer in DMEM */
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, descr_addr +
			       sizeof(u32), &fifo_addr[1], 4);
		break;
	default:
		break;
	}
}
Пример #2
0
/*
 *  ABE_WRITE_EVENT_GENERATOR
 *
 *  Parameter  :
 *	e: Event Generation Counter, McPDM, DMIC or default.
 *
 *  Operations :
 *	load the AESS event generator hardware source. Loads the firmware parameters
 *	accordingly. Indicates to the FW which data stream is the most important to preserve
 *	in case all the streams are asynchronous. If the parameter is "default", let the HAL
 *	decide which Event source is the best appropriate based on the opened ports.
 *
 *	When neither the DMIC and the McPDM are activated the AE will have its EVENT generator programmed
 *	with the EVENT_COUNTER. The event counter will be tuned in order to deliver a pulse frequency higher
 *	than 96 kHz. The DPLL output at 100% OPP is MCLK = (32768kHz x6000) = 196.608kHz
 *	The ratio is (MCLK/96000)+(1<<1) = 2050
 *	(1<<1) in order to have the same speed at 50% and 100% OPP (only 15 MSB bits are used at OPP50%)
 *
 *  Return value :
 *	None.
 */
void abe_write_event_generator(abe_event_id e)
{
	abe_uint32 event, selection, counter, start;

	_lock_enter
	_log(id_write_event_generator,e,0,0)

	counter = EVENT_GENERATOR_COUNTER_DEFAULT;
	start = EVENT_GENERATOR_ON;
	abe_current_event_id = e;

	switch (e) {
	case EVENT_MCPDM:
		selection = EVENT_SOURCE_DMA;
		event = ABE_ATC_MCPDMDL_DMA_REQ;
		break;
	case EVENT_DMIC:
		selection = EVENT_SOURCE_DMA;
		event = ABE_ATC_DMIC_DMA_REQ;
		break;
	case EVENT_TIMER:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		break;
	case EVENT_McBSP:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		break;
	case EVENT_McASP:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		break;
	case EVENT_SLIMBUS:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		break;
	case EVENT_44100:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		counter = EVENT_GENERATOR_COUNTER_44100;
		break;
	case EVENT_DEFAULT:
		selection = EVENT_SOURCE_COUNTER;
		event = 0;
		break;
	default:
		abe_dbg_param |= ERR_API;
		abe_dbg_error_log(ABE_BLOCK_COPY_ERR);
	}

	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_GENERATOR_COUNTER, &counter, 4);
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_SOURCE_SELECTION, &selection, 4);
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_GENERATOR_START, &start, 4);
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, AUDIO_ENGINE_SCHEDULER, &event, 4);

	_lock_exit
}
Пример #3
0
/*
 *	ABE_IRQ_PROCESSING
 *
 *	Parameter  :
 *		No parameter
 *
 *	Operations :
 *		This subroutine is call upon reception of "MA_IRQ_99 ABE_MPU_IRQ" ABE interrupt
 *		This subroutine will check the IRQ_FIFO from the AE and act accordingly.
 *		Some IRQ source are originated for the delivery of "end of time sequenced tasks"
 *		notifications, some are originated from the Ping-Pong protocols, some are generated from
 *		the embedded debugger when the firmware stops on programmable break-points, etc …
 *
 *	Return value :
 *		None.
 */
void abe_irq_processing(void)
{
	abe_uint32 clear_abe_irq;
	abe_uint32 abe_irq_dbg_write_ptr, i, cmem_src, sm_cm = 0;
	abe_irq_data_t IRQ_data;
       _lock_enter
        _log(id_irq_processing,0,0,0)

#define IrqFiFoMask ((D_McuIrqFifo_sizeof >> 2) - 1)

	/* extract the write pointer index from CMEM memory (INITPTR format) */
	/* CMEM address of the write pointer in bytes */
	cmem_src = MCU_IRQ_FIFO_ptr_labelID * 4;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_CMEM, cmem_src,
		(abe_uint32*)&abe_irq_dbg_write_ptr,
			sizeof (abe_irq_dbg_write_ptr));
	abe_irq_dbg_write_ptr = sm_cm >> 16;	/* AESS left-pointer index located on MSBs */
	abe_irq_dbg_write_ptr &= 0xFF;

	/* loop on the IRQ FIFO content */
	for (i = 0; i < D_McuIrqFifo_sizeof; i++) {
		/* stop when the FIFO is empty */
		if (abe_irq_dbg_write_ptr == abe_irq_dbg_read_ptr)
			break;
		/* read the IRQ/DBG FIFO */
		abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM,
			D_McuIrqFifo_ADDR + (i << 2), (abe_uint32 *)&IRQ_data,
					sizeof (IRQ_data));
		abe_irq_dbg_read_ptr = (abe_irq_dbg_read_ptr + 1) & IrqFiFoMask;

		/* select the source of the interrupt */
		switch (IRQ_data.tag) {
		case IRQtag_APS:
			_log(id_irq_processing,(abe_uint32)(IRQ_data.data),0,1)
			abe_irq_aps (IRQ_data.data);
			break;
		case IRQtag_PP:
			_log(id_irq_processing,0,0,2)
			abe_irq_ping_pong ();
			break;
		case IRQtag_COUNT:
			_log(id_irq_processing,(abe_uint32)(IRQ_data.data),0,3)
			abe_irq_check_for_sequences (IRQ_data.data);
			break;
		default:
		break;
		}
	}

	abe_monitoring();

	clear_abe_irq = 1;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, ABE_MCU_IRQSTATUS,
							     &clear_abe_irq, 4);
	_lock_exit
}
Пример #4
0
/*
 *  ABE_SET_DMIC_FILTER
 *
 *  Parameter  :
 *	DMIC decimation ratio : 16/25/32/40
 *
 *  Operations :
 *	Loads in CMEM a specific list of coefficients depending on the DMIC sampling
 *	frequency (2.4MHz or 3.84MHz). This table compensates the DMIC decimator roll-off at 20kHz.
 *	The default table is loaded with the DMIC 2.4MHz recommended configuration.
 *
 *  Return value :
 *	None.
 */
void abe_set_dmic_filter(abe_dmic_ratio_t d)
{
	abe_int32 *src;

	_lock_enter
	_log(id_set_dmic_filter,d,0,0)

	switch(d) {
	case ABE_DEC16:
		src = (abe_int32 *)abe_dmic_16;
		break;
	case ABE_DEC25:
		src = (abe_int32 *) abe_dmic_25;
		break;
	case ABE_DEC32:
		src = (abe_int32 *) abe_dmic_32;
		break;
	default:
	case ABE_DEC40:
		src = (abe_int32 *) abe_dmic_40;
		break;
	}
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM,
		C_98_48_LP_Coefs_ADDR,
		(abe_uint32 *)src, C_98_48_LP_Coefs_sizeof << 2);
	_lock_exit
}
Пример #5
0
/**
 * abe_1616_irq_pingpong_player_1616bits
 *
 * generates data for the cache-flush buffer  MODE 16+16 BITS
 * Return value:
 * None.
 */
void abe_1616_irq_pingpong_player_1616bits_441(void)
{
#if ENABLE_DEFAULT_PLAYERS
	/* ping-pong access to MM_DL at 44.1kHz stereo 1616 with 20ms packet sizes, 2205Hz */
	static s32 idx;
	u32 i, dst, n_samples, n_bytes;
	s32 temp[N_SAMPLES_MAX], audio_sample;
#define DATA_SIZE 20	
	const s32 audio_pattern[DATA_SIZE] = {
		0, 2531, 4815, 6627, 7791, 8192, 7791, 6627, 4815, 2531, 0,
	    -2531, -4815, -6627, -7791, -8192, -7791, -6627, -4815, -2531
	};
	/* read the address of the Pong buffer */
	abe_read_next_ping_pong_buffer(MM_DL_PORT, &dst, &n_bytes);
	/* each stereo sample weights 4 bytes (format 16+16) */
	n_samples = n_bytes / 4;
	/* generate a test pattern */
	for (i = 0; i < n_samples; i++) {
		/* circular addressing */
		audio_sample = audio_pattern[idx];
		idx = (idx >= (DATA_SIZE - 1)) ? 0 : (idx + 1);
		temp[i] = (audio_sample << 16) | (audio_sample & 0x0000FFFF);
		//temp[i] = (i << 16)| ((i  )& 0x0000FFFF);
	}
	abe_set_ping_pong_buffer(MM_DL_PORT, 0);
	/* copy the pattern (flush it) to DMEM pointer update
	 * not necessary here because the buffer size do not
	 * change from one ping to the other pong
	 */
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst,
		       (u32 *) &(temp[0]), n_bytes);
	abe_set_ping_pong_buffer(MM_DL_PORT, n_bytes);
#endif
}
Пример #6
0
/**
 * abe_1616_irq_pingpong_player_1616bits
 *
 * generates data for the cache-flush buffer  MODE 16+16 BITS
 * Return value:
 * None.
 */
void abe_1616_irq_pingpong_player_1616bits(void)
{
#if ENABLE_DEFAULT_PLAYERS
	/* ping-pong access to MM_DL at 48kHz Mono with 20ms packet sizes */
	static s32 idx;
	u32 i, dst, n_samples, n_bytes;
	s32 temp[N_SAMPLES_MAX], audio_sample;
#define DATA_SIZE 20		/*  t = [0:N-1]/N; x = round(16383*sin(2*pi*t)) */
	const s32 audio_pattern[DATA_SIZE] = {
		0, 5063, 9630, 13254, 15581, 16383, 15581, 13254,
		9630, 5063, 0, -5063, -9630, -13254, -15581, -16383,
		-15581, -13254, -9630, -5063
	};
	/* read the address of the Pong buffer */
	abe_read_next_ping_pong_buffer(MM_DL_PORT, &dst, &n_bytes);
	/* each stereo sample weights 4 bytes (format 16+16) */
	n_samples = n_bytes / 4;
	/* generate a test pattern */
	for (i = 0; i < n_samples; i++) {
		/* circular addressing */
		audio_sample = audio_pattern[idx];
		idx = (idx >= (DATA_SIZE - 1)) ? 0 : (idx + 1);
		temp[i] = (audio_sample << 16) | (audio_sample & 0x0000FFFF);
	}
	abe_set_ping_pong_buffer(MM_DL_PORT, 0);
	/* copy the pattern (flush it) to DMEM pointer update
	 * not necessary here because the buffer size do not
	 * change from one ping to the other pong
	 */
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst,
		       (u32 *) &(temp[0]), n_bytes);
	abe_set_ping_pong_buffer(MM_DL_PORT, n_bytes);
#endif
}
Пример #7
0
/*
 *  ABE_READ_NEXT_PING_PONG_BUFFER
 *
 *  Parameter  :
 *	Port_ID :
 *	Returned address to the next buffer (byte offset from DMEM start)
 *
 *  Operations :
 *	Tell the next base address of the next ping_pong Buffer and its size
 *
 *
 */
void abe_read_next_ping_pong_buffer(abe_port_id port, abe_uint32 *p, abe_uint32 *n)
{
	abe_uint32 sio_pp_desc_address;
	ABE_SPingPongDescriptor desc_pp;

	_lock_enter
	_log(id_read_next_ping_pong_buffer,port,0,0)

	/* ping_pong is only supported on MM_DL */
	if (port != MM_DL_PORT) {
		abe_dbg_param |= ERR_API;
		abe_dbg_error_log(ABE_PARAMETER_ERROR);
	}

	/* read the port SIO descriptor and extract the current pointer address  after reading the counter */
	sio_pp_desc_address = D_PingPongDesc_ADDR;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_pp_desc_address, (abe_uint32*)&desc_pp, sizeof(ABE_SPingPongDescriptor));

	if ((desc_pp.counter & 0x1) == 0) {
		(*p) = desc_pp.nextbuff0_BaseAddr;
	} else {
		(*p) = desc_pp.nextbuff1_BaseAddr;
	}

	/* translates the number of samples in bytes */
	(*n) = abe_size_pingpong;

	_lock_exit
}
Пример #8
0
/*
 *  ABE_SET_SEQUENCE_TIME_ACCURACY
 *
 *  Parameter  :
 *	patch bit field used to guarantee the code compatibility without conditionnal compilation
 *	Sequence index
 *
 *  Operations : two counters are implemented in the firmware:
 *  -	one "fast" counter, generating an IRQ to the HAL for sequences scheduling, the rate is in the range 1ms .. 100ms
 *  -	one "slow" counter, generating an IRQ to the HAL for the management of ASRC drift, the rate is in the range 1s .. 100s
 *
 *  Return value :
 *	None.
 */
void abe_set_sequence_time_accuracy(abe_micros_t fast, abe_micros_t slow)
{
	abe_uint32 data;

	_lock_enter
	_log(id_set_sequence_time_accuracy,fast,slow,0)

	data = minimum(MAX_UINT16, (abe_uint32) fast / FW_SCHED_LOOP_FREQ_DIV1000);
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_fastCounter_ADDR,
					(abe_uint32 *)&data, sizeof (data));

	data = minimum(MAX_UINT16, (abe_uint32) slow / FW_SCHED_LOOP_FREQ_DIV1000);
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_slowCounter_ADDR,
				(abe_uint32 *)&data, sizeof (data));

	_lock_exit
}
Пример #9
0
/*
 *  ABE_SET_PING_PONG_BUFFER
 *
 *  Parameter  :
 *	Port_ID :
 *	New data
 *
 *  Operations :
 *	Updates the next ping-pong buffer with "size" bytes copied from the
 *	host processor. This API notifies the FW that the data transfer is done.
 */
void abe_set_ping_pong_buffer(abe_port_id port, abe_uint32 n_bytes)
{
	abe_uint32 sio_pp_desc_address, struct_offset, *src, n_samples, datasize, base_and_size;
	ABE_SPingPongDescriptor desc_pp;

	_lock_enter
	_log(id_set_ping_pong_buffer,port,n_bytes,n_bytes>>8)

	/* ping_pong is only supported on MM_DL */
	if (port != MM_DL_PORT) {
	    abe_dbg_param |= ERR_API;
	    abe_dbg_error_log(ABE_PARAMETER_ERROR);
	}
	/* translates the number of bytes in samples */
	/* data size in DMEM words */
	datasize = abe_dma_port_iter_factor(&((abe_port[port]).format));
	/* data size in bytes */
	datasize = datasize << 2;
	n_samples = n_bytes / datasize;

	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_PingPongDesc_ADDR,
					(abe_uint32 *)&desc_pp, sizeof(desc_pp));

	/*
	 * read the port SIO descriptor and extract the current pointer
	 * address  after reading the counter
	 */
	if ((desc_pp.counter & 0x1) == 0) {
		struct_offset = (abe_uint32)&(desc_pp.nextbuff0_BaseAddr) -
							(abe_uint32)&(desc_pp);
		base_and_size = desc_pp.nextbuff0_BaseAddr;
	} else {
		struct_offset = (abe_uint32)&(desc_pp.nextbuff1_BaseAddr) -
							(abe_uint32)&(desc_pp);
		base_and_size = desc_pp.nextbuff1_BaseAddr;
	}

	base_and_size = (base_and_size & 0xFFFFL) + ((abe_uint32)n_samples << 16);

	sio_pp_desc_address = D_PingPongDesc_ADDR + struct_offset;
	src = &base_and_size;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_pp_desc_address,
				(abe_uint32 *)&base_and_size, sizeof(abe_uint32));

	_lock_exit
}
Пример #10
0
/*
 *  ABE_SET_OPP_PROCESSING
 *
 *  Parameter  :
 *	New processing network and OPP:
 *	  0: Ultra Lowest power consumption audio player (no post-processing, no mixer)
 *	  1: OPP 25% (simple multimedia features, including low-power player)
 *	  2: OPP 50% (multimedia and voice calls)
 *	  3: OPP100% (EANC, multimedia complex use-cases)
 *
 *  Operations :
 *	Rearranges the FW task network to the corresponding OPP list of features.
 *	The corresponding AE ports are supposed to be set/reset accordingly before this switch.
 *
 *  Return value :
 *	error code when the new OPP do not corresponds the list of activated features
 */
void abe_set_opp_processing(abe_opp_t opp)
{
	abe_uint32 dOppMode32, sio_desc_address;
	ABE_SIODescriptor desc;

	_lock_enter
	_log(id_set_opp_processing,opp,0,0)

	switch(opp){
	case ABE_OPP25:
		/* OPP25% */
		dOppMode32 = DOPPMODE32_OPP25;
		break;
	case ABE_OPP50:
		/* OPP50% */
		dOppMode32 = DOPPMODE32_OPP50;
		break;
	default:
		abe_dbg_param |= ERR_API;
		abe_dbg_error_log(ABE_BLOCK_COPY_ERR);
		case ABE_OPP100:
		/* OPP100% */
		dOppMode32 = DOPPMODE32_OPP100;
		break;
	}

	/* Write Multiframe inside DMEM */
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM,
		D_maxTaskBytesInSlot_ADDR, &dOppMode32, sizeof(abe_uint32));

	sio_desc_address = dmem_port_descriptors + (MM_DL_PORT * sizeof(ABE_SIODescriptor));
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_desc_address,
					(abe_uint32*)&desc, sizeof (desc));
	if (dOppMode32 == DOPPMODE32_OPP100)
		desc.smem_addr1 = smem_mm_dl_opp100; /* ASRC input buffer, size 40 */
	else
		desc.smem_addr1 = smem_mm_dl_opp25; /* at OPP 25/50 or without ASRC  */
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_desc_address,
					(abe_uint32*)&desc, sizeof (desc));

	_lock_exit

}
Пример #11
0
/*
 *  ABE_HW_CONFIGURATION
 *
 *  Parameter  :
 *
 *  Operations :
 *
 *
 *  Return value :
 *
 */
void abe_hw_configuration()
{
	abe_uint32 atc_reg;
	abe_port_protocol_t *protocol;
	abe_data_format_t format;

	/* initializes the ABE ATC descriptors in DMEM - MCPDM_UL */
	protocol = &(abe_port[PDM_UL_PORT].protocol);   format = abe_port[PDM_UL_PORT].format;
	abe_init_atc(PDM_UL_PORT);
	abe_init_io_tasks(PDM_UL_PORT, &format, protocol);

	/* initializes the ABE ATC descriptors in DMEM - MCPDM_DL */
	protocol = &(abe_port[PDM_DL1_PORT].protocol);	format = abe_port[PDM_DL1_PORT].format;
	abe_init_atc(PDM_DL1_PORT);
	abe_init_io_tasks(PDM_DL1_PORT, &format, protocol);

	/* one DMIC port enabled = all DMICs enabled, since there is a single DMIC path for all DMICs */
	protocol = &(abe_port[DMIC_PORT1].protocol);	format = abe_port[DMIC_PORT1].format;
	abe_init_atc(DMIC_PORT1);
	abe_init_io_tasks(DMIC_PORT1, &format, protocol);

	/* enables the DMAreq from AESS  AESS_DMAENABLE_SET = 255 */
	atc_reg = 0xFF;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x60, &atc_reg, 4);

#if 0
	/* let the EVENT be configured once the ports are already programmed */
	/* enables EVENT_GENERATOR_START=6C from McPDM */
	atc_reg = 0x01;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x6C, &atc_reg, 4);

	// set McPDM_DL as EVENT_SOURCE_SELECTION
	event = 0L;						// source = DMAreq
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x70, &event, 4);

	event = 2L;						// source = MCPDM_DL to AUDIO_ENGINE_SCHEDULER
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x74, &event, 4);
#endif
}
Пример #12
0
/**
 * abe_dbg_log - Log ABE trace inside circular buffer
 * @x: data to be logged
 * @y: data to be logged
 * @z: data to be logged
 * @t: data to be logged
 *  Parameter  :
 *
 *	abe_dbg_activity_log : global circular buffer holding the data
 *	abe_dbg_activity_log_write_pointer : circular write pointer
 *
 *	saves data in the log file
 */
void abe_dbg_log(u32 x, u32 y, u32 z, u32 t)
{
	u32 time_stamp, data;
	if (abe_dbg_activity_log_write_pointer >= (D_DEBUG_HAL_TASK_sizeof - 2))
		abe_dbg_activity_log_write_pointer = 0;
	/* copy in DMEM trace buffer and CortexA9 local buffer and a small 7
	   words circular buffer of the DMA trace ending with 0x55555555
	   (tag for last word) */
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_loopCounter_ADDR,
		       (u32 *) &time_stamp, sizeof(time_stamp));
	abe_dbg_activity_log[abe_dbg_activity_log_write_pointer] = time_stamp;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_DEBUG_HAL_TASK_ADDR +
		       (abe_dbg_activity_log_write_pointer << 2),
		       (u32 *) &time_stamp, sizeof(time_stamp));
	abe_dbg_activity_log_write_pointer++;
	data = ((x & MAX_UINT8) << 24) | ((y & MAX_UINT8) << 16) |
		((z & MAX_UINT8) << 8)
		| (t & MAX_UINT8);
	abe_dbg_activity_log[abe_dbg_activity_log_write_pointer] = data;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_DEBUG_HAL_TASK_ADDR +
		       (abe_dbg_activity_log_write_pointer << 2),
		       (u32 *) &data, sizeof(data));
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM,
		       D_DEBUG_FIFO_HAL_ADDR +
		       ((abe_dbg_activity_log_write_pointer << 2) &
			(D_DEBUG_FIFO_HAL_sizeof - 1)), (u32 *) &data,
		       sizeof(data));
	data = ABE_DBG_MAGIC_NUMBER;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_DEBUG_FIFO_HAL_ADDR +
		       (((abe_dbg_activity_log_write_pointer +
			  1) << 2) & (D_DEBUG_FIFO_HAL_sizeof - 1)),
		       (u32 *) &data, sizeof(data));
	abe_dbg_activity_log_write_pointer++;
	if (abe_dbg_activity_log_write_pointer >= D_DEBUG_HAL_TASK_sizeof)
		abe_dbg_activity_log_write_pointer = 0;
}
Пример #13
0
/**
* @fn abe_load_fwl()
*
*  Operations :
*      loads the Audio Engine firmware, generate a single pulse on the Event generator
*      to let execution start, read the version number returned from this execution.
*
* @see	ABE_API.h
*/
void abe_load_fw_param(abe_uint32 *PMEM, abe_uint32 PMEM_SIZE,
			abe_uint32 *CMEM, abe_uint32 CMEM_SIZE,
				abe_uint32 *SMEM, abe_uint32 SMEM_SIZE,
					abe_uint32 *DMEM, abe_uint32 DMEM_SIZE)
{
	static abe_uint32 warm_boot;
	abe_uint32 event_gen;

	_lock_enter
	_log(id_load_fw_param,0,0,0)

#if PC_SIMULATION
	/* the code is loaded from the Checkers */
#else
	/* do not load PMEM */
	if (warm_boot) {
		/* Stop the event Generator */
		event_gen = 0;
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC,
				EVENT_GENERATOR_START, &event_gen, 4);

		/* Now we are sure the firmware is stalled */
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 0, CMEM, CMEM_SIZE);
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, 0, SMEM, SMEM_SIZE);
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, 0, DMEM, DMEM_SIZE);

		/* Restore the event Generator status */
		event_gen = 1;
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC,
				EVENT_GENERATOR_START, &event_gen, 4);
	} else {
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_PMEM, 0, PMEM, PMEM_SIZE);
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 0, CMEM, CMEM_SIZE);
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, 0, SMEM, SMEM_SIZE);
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, 0, DMEM, DMEM_SIZE);
	}

	warm_boot = 1;
#endif
	_lock_exit
}
Пример #14
0
/**
 * abe_default_irq_pingpong_player
 *
 * generates data for the cache-flush buffer MODE 16+16
 */
void abe_default_irq_pingpong_player(void)
{
#if ENABLE_DEFAULT_PLAYERS
/* ping-pong access to MM_DL at 48kHz Mono with 20ms packet sizes */
#define N_SAMPLES_MAX ((int)(1024))
	static s32 idx;
	u32 i, dst, n_samples, n_bytes;
	s32 temp[N_SAMPLES_MAX], audio_sample;
#define DATA_SIZE 20		/* t = [0:N-1]/N; x = round(16383*sin(2*pi*t)) */
	const s32 audio_pattern[DATA_SIZE] = {
		0, 5063, 9630, 13254, 15581, 16383, 15581, 13254, 9630,
		5063, 0, -5063, -9630, -13254, -15581, -16383, -15581,
		-13254, -9630, -5063
	};
#if 0
#define DATA_SIZE 8
	const s32 audio_pattern[DATA_SIZE] = {
		0, 11585, 16384, 11585, 0, -11586, -16384, -11586
	};
#define DATA_SIZE 12
	const s32 audio_pattern[DATA_SIZE] = {
		0, 8191, 14188, 16383, 14188, 8191, 0,
		-8192, -14188, -16383, -14188, -8192
	};
	const s32 audio_pattern[8] = {
		16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384
	};
#endif
	/* read the address of the Pong buffer */
	abe_read_next_ping_pong_buffer(MM_DL_PORT, &dst, &n_bytes);
	/* each stereo sample weights 4 bytes (format 16|16) */
	n_samples = n_bytes / 4;
	/* generate a test pattern */
	for (i = 0; i < n_samples; i++) {
		audio_sample = audio_pattern[idx];
		idx = (idx >= (DATA_SIZE - 1)) ? 0 : (idx + 1);
		/* format 16|16 */
		temp[i] = ((audio_sample << 16) + audio_sample);
	}
	/* copy the pattern (flush it) to DMEM pointer update
	 * not necessary here because the buffer size do not
	 * change from one ping to the other pong
	 */
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst,
		       (u32 *) &(temp[0]), n_bytes);
	abe_set_ping_pong_buffer(MM_DL_PORT, n_bytes);
#endif
}
Пример #15
0
/*
 *  ABE_SELECT_MAIN_PORT
 *
 *  Parameter  :
 *	id : audio port name
 *
 *  Operations :
 *	tells the FW which is the reference stream for adjusting
 *	the processing on 23/24/25 slots
 *
 *  Return value:
 *	None.
 */
void abe_select_main_port (abe_port_id id)
{
	abe_uint32 selection;

	_lock_enter
	_log(id_select_main_port,id,0,0)

	/* flow control */
	selection = D_IOdescr_ADDR + id*sizeof(ABE_SIODescriptor) + flow_counter_;
	/* Is port is McPDM UL no synchronization as algorithm is not working */
	if (PDM_UL_PORT == id)
		selection = 0;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_Slot23_ctrl_ADDR, &selection, 4);

	_lock_exit
}
Пример #16
0
/*
 *  ABE_READ_REMAINING_DATA
 *
 *  Parameter  :
 *	Port_ID :
 *	size : pointer to the remaining number of 32bits words
 *
 *  Operations :
 *	computes the remaining amount of data in the buffer.
 *
 *  Return value :
 *	error code
 */
void abe_read_remaining_data(abe_port_id port, abe_uint32 *n)
{
	abe_uint32 sio_pp_desc_address;
	ABE_SPingPongDescriptor desc_pp;

	_lock_enter
	_log(id_read_remaining_data,port,0,0)

	/*
	 * read the port SIO descriptor and extract the
	 * current pointer address  after reading the counter
	 */
	sio_pp_desc_address = D_PingPongDesc_ADDR;
	abe_block_copy (COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_pp_desc_address,
		(abe_uint32*)&desc_pp, sizeof(ABE_SPingPongDescriptor));
	(*n) = desc_pp.workbuff_Samples;

	_lock_exit
}
Пример #17
0
/**
 * abe_load_embeddded_patterns
 *
 * load test patterns
 *
 *  S = power (2, 31) * 0.25;
 *  N =  4; B = 2; F=[1/N 1/N];
 *	gen_and_save('dbg_8k_2.txt',  B, F, N, S);
 *  N =  8; B = 2; F=[1/N 2/N];
 *	gen_and_save('dbg_16k_2.txt', B, F, N, S);
 *  N = 12; B = 2; F=[1/N 2/N];
 *	gen_and_save('dbg_48k_2.txt', B, F, N, S);
 *  N = 60; B = 2; F=[4/N 8/N];
 *	gen_and_save('dbg_amic.txt', B, F, N, S);
 *  N = 10; B = 6; F=[1/N 2/N 3/N 1/N 2/N 3/N];
 *	gen_and_save('dbg_dmic.txt', B, F, N, S);
*/
void abe_load_embeddded_patterns(void)
{
	u32 i;
#define patterns_96k_len 48
	const long patterns_96k[patterns_96k_len] = {
		1620480, 1452800,
		1452800, 838656,
		1186304, 0,
		838656, -838912,
		434176, -1453056,
		0, -1677824,
		-434432, -1453056,
		-838912, -838912,
		-1186560, -256,
		-1453056, 838656,
		-1620736, 1452800,
		-1677824, 1677568,
		-1620736, 1452800,
		-1453056, 838656,
		-1186560, 0,
		-838912, -838912,
		-434432, -1453056,
		-256, -1677824,
		434176, -1453056,
		838656, -838912,
		1186304, -256,
		1452800, 838656,
		1620480, 1452800,
		1677568, 1677568,
	};
#define patterns_48k_len 24
	const long patterns_48k[patterns_48k_len] = {
		1452800, 838656,
		838656, -838912,
		0, -1677824,
		-838912, -838912,
		-1453056, 838656,
		-1677824, 1677568,
		-1453056, 838656,
		-838912, -838912,
		-256, -1677824,
		838656, -838912,
		1452800, 838656,
		1677568, 1677568,
	};
#define patterns_24k_len 12
	const long patterns_24k[patterns_24k_len] = {
		838656, -838912,
		-838912, -838912,
		-1677824, 1677568,
		-838912, -838912,
		838656, -838912,
		1677568, 1677568,
	};
#define patterns_16k_len 8
	const long patterns_16k[patterns_16k_len] = {
		0, 0,
		-1677824, -1677824,
		-256, -256,
		1677568, 1677568,
	};
#define patterns_8k_len 4
	const long patterns_8k[patterns_8k_len] = {
		1677568, -1677824,
		1677568, 1677568,
	};
	for (i = 0; i < patterns_8k_len; i++)
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM,
			       (S_DBG_8K_PATTERN_ADDR * 8) + (i * 4),
			       (u32 *) (&(patterns_8k[i])), 4);
	for (i = 0; i < patterns_16k_len; i++)
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM,
			       (S_DBG_16K_PATTERN_ADDR * 8) + (i * 4),
			       (u32 *) (&(patterns_16k[i])), 4);
	for (i = 0; i < patterns_24k_len; i++)
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM,
			       (S_DBG_24K_PATTERN_ADDR * 8) + (i * 4),
			       (u32 *) (&(patterns_24k[i])), 4);
	for (i = 0; i < patterns_48k_len; i++)
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM,
			       (S_DBG_48K_PATTERN_ADDR * 8) + (i * 4),
			       (u32 *) (&(patterns_48k[i])), 4);
	for (i = 0; i < patterns_96k_len; i++)
		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM,
			       (S_DBG_96K_PATTERN_ADDR * 8) + (i * 4),
			       (u32 *) (&(patterns_96k[i])), 4);
}
Пример #18
0
/**
 * abe_monitoring
 *
 * checks the internal status of ABE and HAL
 */
void abe_monitoring(void)
{
	int i, reset;
	
	abe->dbg_param = 0;
	
	/* Check AMIC UL filter */
	reset = 0;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_SMEM,
			S_AMIC_96_48_data_ADDR << 3, &filter_value[0],
			S_AMIC_96_48_data_sizeof << 3);

	for (i =0; i < S_AMIC_96_48_data_sizeof << 1; i++)
		if (filter_value[i] >= 0x700000 && filter_value[i] <= 0x900000)
			reset = 1;

	if (reset == 1) {
		printk(KERN_ERR "Reset AMIC filter \n");
		abe_reset_mem(ABE_SMEM, S_AMIC_96_48_data_ADDR << 3,
				 S_AMIC_96_48_data_sizeof << 3);
	}
	/* Check VX UL HP filter */
	reset = 0;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_SMEM,
			S_VX_UL_48_8_HP_data_ADDR << 3, &filter_value[0],
			S_VX_UL_48_8_HP_data_sizeof << 3);

	for (i = 0; i < S_VX_UL_48_8_HP_data_sizeof << 1; i++)
		if (filter_value[i] >= 0x700000 && filter_value[i] <= 0x900000)
			reset = 1;

/*	if (reset == 1) {
		printk(KERN_ERR "Reset VX UL HP filter \n");
		abe_reset_mem(ABE_SMEM, S_VX_UL_48_8_HP_data_ADDR << 3,
				S_VX_UL_48_8_HP_data_sizeof << 3);
	}*/

	/* Check VX UL LP filter */
//	reset = 0;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_SMEM,
			S_VX_UL_48_8_LP_data_ADDR << 3, &filter_value[0],
			S_VX_UL_48_8_LP_data_sizeof << 3);

	for (i = 0; i < S_VX_UL_48_8_LP_data_sizeof << 1; i++)
		if (filter_value[i] >= 0x700000 && filter_value[i] <= 0x900000)
			reset = 1;

	if (reset == 1) {
//		printk(KERN_ERR "Reset VX UL LP filter \n");
		printk(KERN_ERR "Reset VX UL filter \n");
		abe_reset_mem(ABE_SMEM, S_VX_UL_48_8_LP_data_ADDR << 3,
				S_VX_UL_48_8_LP_data_sizeof << 3);
		abe_reset_mem(ABE_SMEM, S_VX_UL_48_8_HP_data_ADDR << 3,
				S_VX_UL_48_8_HP_data_sizeof << 3);				
	}
	
	/* Check VX DL HP filter */
	reset = 0;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_SMEM,
			S_VX_DL_8_48_HP_data_ADDR << 3, &filter_value[0],
			S_VX_DL_8_48_HP_data_sizeof << 3);

	for (i = 0; i < S_VX_DL_8_48_HP_data_sizeof << 1; i++)
		if (filter_value[i] >= 0x700000 && filter_value[i] <= 0x900000)
			reset = 1;
				
//	reset = 0;
	abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_SMEM,
			S_VX_DL_8_48_LP_data_ADDR << 3, &filter_value[0],
			S_VX_DL_8_48_LP_data_sizeof << 3);

	for (i = 0; i < S_VX_DL_8_48_LP_data_sizeof << 1; i++)
		if (filter_value[i] >= 0x700000 && filter_value[i] <= 0x900000)
			reset = 1;

	if (reset == 1) {
//		printk(KERN_ERR "Reset VX DL LP filter \n");
		printk(KERN_ERR "Reset VX DL filter \n");
		abe_reset_mem(ABE_SMEM, S_VX_DL_8_48_LP_data_ADDR << 3,
				S_VX_DL_8_48_LP_data_sizeof << 3);
		abe_reset_mem(ABE_SMEM, S_VX_DL_8_48_HP_data_ADDR << 3,
				S_VX_DL_8_48_HP_data_sizeof << 3);				
	}	
	
}
Пример #19
0
/*
 *  ABE_BUILD_SCHEDULER_TABLE
 *
 *  Parameter  :
 *
 *  Operations :
 *
 *
 *  Return value :
 *
 */
void abe_build_scheduler_table()
{
	short VirtAudio_aMultiFrame[PROCESSING_SLOTS][TASKS_IN_SLOT];
	abe_uint16 i, n;
	abe_uint8 *ptr;
	char  aUplinkMuxing[16];
	abe_uint32 dFastLoopback;

	for (ptr = (abe_uint8 *)&(VirtAudio_aMultiFrame[0][0]), i=0; i < sizeof(VirtAudio_aMultiFrame); i++)
		*ptr++ = 0;

	VirtAudio_aMultiFrame[0][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_AMIC;
	VirtAudio_aMultiFrame[0][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_DL;
	//VirtAudio_aMultiFrame[0][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_8;

	VirtAudio_aMultiFrame[1][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_BP;
	VirtAudio_aMultiFrame[1][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_0SR;
	VirtAudio_aMultiFrame[1][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_LP;
	VirtAudio_aMultiFrame[1][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_DL;

	// VirtAudio_aMultiFrame[2][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_MM_DL;
	VirtAudio_aMultiFrame[2][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_MM_UL_ROUTING;
	VirtAudio_aMultiFrame[2][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_MM_UL2_ROUTING;
	//VirtAudio_aMultiFrame[2][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_UL;
#if 0
	VirtAudio_aMultiFrame[3][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_TONES_DL;
#endif
	VirtAudio_aMultiFrame[3][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VXRECMixer;
	VirtAudio_aMultiFrame[3][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VXREC_SPLIT;
	VirtAudio_aMultiFrame[3][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_SideTone;

	VirtAudio_aMultiFrame[4][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1Mixer;
	VirtAudio_aMultiFrame[4][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2Mixer;
	VirtAudio_aMultiFrame[4][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_SDTMixer;
	VirtAudio_aMultiFrame[4][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_UL2;

	VirtAudio_aMultiFrame[5][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EchoMixer;
	VirtAudio_aMultiFrame[5][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_EQ;
	VirtAudio_aMultiFrame[5][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_EQ;
	VirtAudio_aMultiFrame[5][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_GAIN;

	VirtAudio_aMultiFrame[6][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_EQ;
	VirtAudio_aMultiFrame[6][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_EQ;
	VirtAudio_aMultiFrame[6][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_GAIN;

	VirtAudio_aMultiFrame[8][0]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EchoMixer;

	VirtAudio_aMultiFrame[9][1]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_0SR;
	VirtAudio_aMultiFrame[9][2]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP;
	VirtAudio_aMultiFrame[9][3]  = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP;

	VirtAudio_aMultiFrame[10][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_0SR;
	VirtAudio_aMultiFrame[10][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP;
	VirtAudio_aMultiFrame[10][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP;

	VirtAudio_aMultiFrame[11][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL;

	VirtAudio_aMultiFrame[12][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_AMIC;
	VirtAudio_aMultiFrame[12][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_LP;
	VirtAudio_aMultiFrame[12][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_DEC;
	VirtAudio_aMultiFrame[12][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_EQ;

	VirtAudio_aMultiFrame[13][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_96_48_LP;
	VirtAudio_aMultiFrame[13][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_96_48_DEC;
	VirtAudio_aMultiFrame[13][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_EQ;
	VirtAudio_aMultiFrame[13][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_SPLIT;

	VirtAudio_aMultiFrame[14][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_96_48_LP;
	VirtAudio_aMultiFrame[14][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_96_48_DEC;
	VirtAudio_aMultiFrame[14][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_EQ;
	VirtAudio_aMultiFrame[14][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_SPLIT;

	VirtAudio_aMultiFrame[15][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_96_48_LP;
	VirtAudio_aMultiFrame[15][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_96_48_DEC;
	VirtAudio_aMultiFrame[15][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_EQ;
	VirtAudio_aMultiFrame[15][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_SPLIT;

	VirtAudio_aMultiFrame[16][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_SPLIT;
	VirtAudio_aMultiFrame[16][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_IIR;
	VirtAudio_aMultiFrame[16][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_CORE;

	VirtAudio_aMultiFrame[17][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_IIR;
	VirtAudio_aMultiFrame[17][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_SPLIT;
	VirtAudio_aMultiFrame[17][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_L_APS_CORE;
	VirtAudio_aMultiFrame[17][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_R_APS_CORE;

	VirtAudio_aMultiFrame[21][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_ROUTING;
	VirtAudio_aMultiFrame[21][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ULMixer;

	VirtAudio_aMultiFrame[22][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_LP;
	VirtAudio_aMultiFrame[22][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_DEC1;
	VirtAudio_aMultiFrame[22][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_BP;

	VirtAudio_aMultiFrame[23][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL;
	//VirtAudio_aMultiFrame[23][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_8;
	VirtAudio_aMultiFrame[23][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_UL;
	VirtAudio_aMultiFrame[23][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_GAIN_UPDATE;

	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof(VirtAudio_aMultiFrame));

	/* DMIC Fast Loopback */
	dFastLoopback = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_DMIC;
	dFastLoopback = dFastLoopback << 16;
	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, 0x116C,
		(abe_uint32*)&dFastLoopback, sizeof(dFastLoopback));

	/* reset the uplink router */
	n = D_aUplinkRouting_ADDR_END - D_aUplinkRouting_ADDR + 1;
	for(i = 0; i < n; i++)
		aUplinkMuxing[i] = ZERO_labelID;

	abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_aUplinkRouting_ADDR, (abe_uint32 *)aUplinkMuxing, sizeof(aUplinkMuxing));
}
Пример #20
0
/*
 *  ABE_INIT_ATC
 *
 *  Parameter  :
 *      prot : protocol being used
 *
 *  Operations :
 *      load the DMEM ATC/AESS descriptors
 *
 *  Return value :
 *
 */
void abe_init_atc(abe_port_id id)
{
	abe_satcdescriptor_aess desc;
	abe_uint8 thr, thr1, thr2, iter, data_shift;
	abe_int32 iterfactor;

	// load default values of the descriptor
	desc.rdpt = desc.wrpt = desc.irqdest = desc.cberr = desc.desen =0;
	desc.reserved0 = desc.reserved1 = desc.reserved2 = 0;
	desc.srcid = desc.destid = desc.badd = desc.iter = desc.cbsize = 0;


	switch ((abe_port[id]).protocol.protocol_switch) {
	case SLIMBUS_PORT_PROT:
		desc.cbdir = (abe_port[id]).protocol.direction;
		desc.cbsize = (abe_port[id]).protocol.p.prot_slimbus.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_slimbus.buf_addr1) >> 4;
		desc.iter = (abe_port[id]).protocol.p.prot_slimbus.iter;
		desc.srcid = abe_atc_srcid [(abe_port[id]).protocol.p.prot_slimbus.desc_addr1 >> 3];
		desc.nw = 1;

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, (abe_port[id]).protocol.p.prot_slimbus.desc_addr1, (abe_uint32*)&desc, sizeof(desc));

		desc.badd = (abe_port[id]).protocol.p.prot_slimbus.buf_addr2;
		desc.srcid = abe_atc_srcid [(abe_port[id]).protocol.p.prot_slimbus.desc_addr2 >> 3];

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, (abe_port[id]).protocol.p.prot_slimbus.desc_addr2, (abe_uint32*)&desc, sizeof(desc));
		break;
	case SERIAL_PORT_PROT:
		desc.cbdir = (abe_port[id]).protocol.direction;
		desc.cbsize = (abe_port[id]).protocol.p.prot_serial.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_serial.buf_addr) >> 4;
		desc.iter = (abe_port[id]).protocol.p.prot_serial.iter;
		desc.srcid = abe_atc_srcid [(abe_port[id]).protocol.p.prot_serial.desc_addr >> 3];
		desc.nw = 1;

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, (abe_port[id]).protocol.p.prot_serial.desc_addr, (abe_uint32*)&desc, sizeof(desc));
		break;
	case DMIC_PORT_PROT:
		desc.cbdir = ABE_ATC_DIRECTION_IN;
		desc.cbsize = (abe_port[id]).protocol.p.prot_dmic.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_dmic.buf_addr) >> 4;
		desc.iter = DMIC_ITER;
		desc.srcid = abe_atc_srcid [ABE_ATC_DMIC_DMA_REQ];
		desc.nw = 1;

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, ABE_ATC_DMIC_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc));
		break;
	case MCPDMDL_PORT_PROT:
		abe_global_mcpdm_control = abe_port[id].protocol.p.prot_mcpdmdl.control;	/* Control allowed on McPDM DL */
		desc.cbdir = ABE_ATC_DIRECTION_OUT;
		desc.cbsize = (abe_port[id]).protocol.p.prot_mcpdmdl.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_mcpdmdl.buf_addr) >> 4;
		desc.iter = MCPDM_DL_ITER;
		desc.destid = abe_atc_dstid [ABE_ATC_MCPDMDL_DMA_REQ];
		desc.nw = 0;
		desc.wrpt = desc.iter;		/* @@@ pre-load the ATC buffer (?) */
		desc.desen = 1;

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, ABE_ATC_MCPDMDL_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc));
		break;
	case MCPDMUL_PORT_PROT:
		desc.cbdir = ABE_ATC_DIRECTION_IN;
		desc.cbsize = (abe_port[id]).protocol.p.prot_mcpdmul.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_mcpdmul.buf_addr) >> 4;
		desc.iter = MCPDM_UL_ITER;
		desc.srcid = abe_atc_srcid [ABE_ATC_MCPDMUL_DMA_REQ];
		desc.wrpt = MCPDM_UL_ITER;				  /* @@@ pre-load the ATC buffer (Virtio bug) */
		desc.nw = 1;
		desc.desen = 1;

		abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, ABE_ATC_MCPDMUL_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc));
		break;
	case PINGPONG_PORT_PROT:
		/* software protocol, nothing to do on ATC */
		break;
	case DMAREQ_PORT_PROT:
		desc.cbdir = (abe_port[id]).protocol.direction;
		desc.cbsize = (abe_port[id]).protocol.p.prot_dmareq.buf_size;
		desc.badd = ((abe_port[id]).protocol.p.prot_dmareq.buf_addr) >> 4;
		desc.iter = 1;	/* CBPr needs ITER=1. this is the eDMA job to do the iterations */
		desc.nw = 0;	/* data is sent on DMAreq, and never before data is prepared */

		thr = (abe_int8) abe_port[id].protocol.p.prot_dmareq.thr_flow;
		iterfactor = abe_dma_port_iter_factor (&((abe_port[id]).format));
		data_shift = (abe_uint8)((iterfactor > 1)? 1:0);    /* shift = 0 for mono, shift = 1 for stereo - see update of ATC pointers in IOtasks */
		thr = (abe_uint8)(thr * iterfactor);	      /* scales the data threshold to the number of words in DMEM per sample */
		iter = (abe_uint8) abe_dma_port_iteration(&((abe_port[id]).format));

		/* check is input from ABE point of view */
		if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) {
			/* Firmware compares X+Drift to Thresholds */
			thr2 = (abe_uint8)(iter - thr);
			thr1 = (abe_uint8)(iter + thr);
			desc.wrpt = ((thr1 + thr2) >> 1) + 2;
		} else {