Example #1
0
/**
* @fn abe_connect_cbpr_dmareq_port()
*
*  Operations : enables the data echange between a DMA and the ABE through the
*	CBPr registers of AESS.
*
*   Parameters :
*   id: port name
*   f : desired data format
*   d : desired dma_request line (0..7)
*   a : returned pointer to the base address of the CBPr register and number of
*	samples to exchange during a DMA_request.
*
* @see	ABE_API.h
*/
void abe_connect_cbpr_dmareq_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *returned_dma_t)
{
	_lock_enter
	_log(id_connect_cbpr_dmareq_port,id,f->f,f->samp_format)

	abe_port[id] = ((abe_port_t *)abe_port_init)[id];

	abe_port[id].format = *f;
	abe_port[id].protocol.protocol_switch = DMAREQ_PORT_PROT;
	abe_port[id].protocol.p.prot_dmareq.iter = abe_dma_port_iteration(f);
	abe_port[id].protocol.p.prot_dmareq.dma_addr = ABE_DMASTATUS_RAW;
	abe_port[id].protocol.p.prot_dmareq.dma_data = (1 << d);

	abe_port[id].status = RUN_P;

	/* load the micro-task parameters */
	abe_init_io_tasks(id, &((abe_port [id]).format), &((abe_port [id]).protocol));

	/* load the dma_t with physical information from AE memory mapping */
	abe_init_dma_t(id, &((abe_port [id]).protocol));

	/* load the ATC descriptors - disabled */
	abe_init_atc(id);

	/* return the dma pointer address */
	abe_read_port_address(id, returned_dma_t);

	_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 {