/****************************************************************************
*
*  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;
}