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