Example #1
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
}
/*
 *  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 {