/**************************************************************************** * * Function Name: void csl_caph_dma_stop_transfer(CSL_CAPH_DMA_CHNL_e chnl) * * Description: stop the channel * ****************************************************************************/ void csl_caph_dma_stop_transfer(CSL_CAPH_DMA_CHNL_e chnl) { aTrace(LOG_AUDIO_CSL, "%s:: %d\n", __func__, chnl); if (chnl != CSL_CAPH_DMA_NONE) { /* Disable the DMA and its fifo status to make a complete * reset */ if (cpu_is_rhea_B0()) /*refer to HWRHEA-2394*/ chal_caph_dma_set_ddrfifo_status(handle, csl_caph_dma_get_chal_chnl (chnl), CAPH_READY_NONE); chal_caph_dma_clr_channel_fifo(handle, csl_caph_dma_get_chal_chnl (chnl)); chal_caph_dma_disable(handle, csl_caph_dma_get_chal_chnl(chnl)); } return; }
/**************************************************************************** * * Function Name: cVoid chal_caph_dma_set_ddrfifo_status(CHAL_HANDLE handle, * CAPH_DMA_CHANNEL_e channel, * CAPH_DMA_CHNL_FIFO_STATUS_e status) * * Description: set CAPH DMA ddr fifo status * ****************************************************************************/ static cVoid chal_caph_dma_rheaB0_set_ddrfifo_status(CHAL_HANDLE handle, CAPH_DMA_CHANNEL_e channel, CAPH_DMA_CHNL_FIFO_STATUS_e status) { cUInt32 base = ((chal_caph_dma_cb_t *) handle)->base; cUInt8 index; cUInt32 cr = 0; if (cpu_is_rhea_B0()) { /*-- Rhea B0-- */ for (index = 0; index < CHAL_CAPH_DMA_MAX_CHANNELS; index++) { if ((1UL << index) & channel) { /* found the channel, Set the DDR fifo status */ cr = BRCM_READ_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE)); if (status == CAPH_READY_NONE) { cr &= (~CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_MASK); cr &= (~CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_HIGH_MASK); BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); } else { #if 0 /* this secion of code has a bug: */ if (status & CAPH_READY_LOW) { cr = CAPH_READY_LOW << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); } if (status & CAPH_READY_HIGH) { cr |= CAPH_READY_HIGH << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); } #else cr |= (status << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT); BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); #endif } break; } } } else { /*-- Rhea B1 --*/ /* Find the channel we are looking for */ for (index = 0; index < CHAL_CAPH_DMA_MAX_CHANNELS; index++) { if ((1UL << index) & channel) { /* found the channel we are looking for, Set the DDR fifo status */ cr = BRCM_READ_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE)); /* mark to preserve HW_RDY bits */ cr |= CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_LOW_MASK | CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_HIGH_MASK; if (status == CAPH_READY_NONE) { /* set Reset bit */ cr |= CPH_AADMAC_CH1_AADMAC_SR_1_CH1_AADMAC_FIFO_RST_MASK; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); /* clear Reset bit */ cr = BRCM_READ_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index*CHAL_CAPH_DMA_CH_REG_SIZE)); cr &= ~CPH_AADMAC_CH1_AADMAC_SR_1_CH1_AADMAC_FIFO_RST_MASK; cr |= CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_LOW_MASK | CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_HIGH_MASK; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); return; } /* cr already set to CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_LOW_MASK | CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_HIGH_MASK */ #if 0 /*no need to separate low and high writes*/ if (status & CAPH_READY_LOW) { cr |= CAPH_READY_LOW << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); } if (status & CAPH_READY_HIGH) { cr = CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_LOW_MASK | CPH_AADMAC_CH1_AADMAC_SR_1_CH1_HW_READY_HIGH_MASK; cr |= CAPH_READY_HIGH << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT; BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); } #else cr |= (status << CPH_AADMAC_CH1_AADMAC_SR_1_CH1_SW_READY_LOW_SHIFT); BRCM_WRITE_REG_IDX(base, CPH_AADMAC_CH1_AADMAC_SR_1, (index * CHAL_CAPH_DMA_CH_REG_SIZE), cr); #endif break; } } } return; }
/**************************************************************************** * * Function Name:void csl_caph_dma_config_channel(CSL_CAPH_DMA_CONFIG_t * chnl_config) * * Description: assign and configure CAPH DMA channel * ****************************************************************************/ void csl_caph_dma_config_channel(CSL_CAPH_DMA_CONFIG_t chnl_config) { CAPH_DMA_CHANNEL_e caph_aadmac_ch = CAPH_DMA_CH_VOID; CAPH_CFIFO_e caph_cfifo_fifo = CAPH_CFIFO_VOID; CAPH_CFIFO_CHNL_DIRECTION_e direction = CAPH_CFIFO_IN; aTrace(LOG_AUDIO_CSL, "%s::dir %d fifo %d dma %d mem %p size %ld Tsize %d dmaCB %p " "n_dma_buf %d dma_buf_size %d\n", __func__, chnl_config.direction, chnl_config.fifo, chnl_config.dma_ch, chnl_config.mem_addr, chnl_config.mem_size, chnl_config.Tsize, chnl_config.dmaCB, chnl_config.n_dma_buf, chnl_config.dma_buf_size); if ((chnl_config.fifo == CSL_CAPH_CFIFO_NONE) || (chnl_config.dma_ch == CSL_CAPH_DMA_NONE)) return; caph_aadmac_ch = csl_caph_dma_get_chal_chnl(chnl_config.dma_ch); caph_cfifo_fifo = csl_caph_cfifo_get_chal_fifo(chnl_config.fifo); chal_caph_dma_clear_register(handle, caph_aadmac_ch); chal_caph_dma_set_cfifo(handle, caph_aadmac_ch, caph_cfifo_fifo); direction = csl_caph_dma_get_chal_direction(chnl_config.direction); chal_caph_dma_set_direction(handle, caph_aadmac_ch, direction); chal_caph_dma_set_buffer(handle, caph_aadmac_ch, (cUInt32) (chnl_config.mem_addr), chnl_config.mem_size); chal_caph_dma_set_tsize(handle, caph_aadmac_ch, chnl_config.Tsize); /*On B1, FIFO_RST will clear SW_RDY bits*/ if (cpu_is_rhea_B0()) { chal_caph_dma_set_ddrfifo_status(handle, caph_aadmac_ch, CAPH_READY_HIGHLOW); chal_caph_dma_clr_channel_fifo(handle, caph_aadmac_ch); } else { chal_caph_dma_clr_channel_fifo(handle, caph_aadmac_ch); chal_caph_dma_set_ddrfifo_status(handle, caph_aadmac_ch, CAPH_READY_HIGHLOW); } dmaCH_ctrl[chnl_config.dma_ch].caphDmaCb = chnl_config.dmaCB; if (chnl_config.n_dma_buf) { chal_caph_dma_set_hibuffer(handle, caph_aadmac_ch, (cUInt32) (chnl_config.mem_addr + chnl_config.dma_buf_size), 0); chal_caph_dma_en_hibuffer(handle, caph_aadmac_ch); } return; }