/** * @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 {