コード例 #1
0
int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info)
{
	int i_ret = 0;
	unsigned long base = p_dma_info->base;
	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
	P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo,
							    MTK_BTIF_DMA_VFIFO,
							    vfifo);

	if (DMA_DIR_RX == p_dma_info->dir) {
/*Rx DMA*/
/*do hardware reset*/
//		BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);
//		BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);
		
		BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST);
		while((0x01 & BTIF_READ32(RX_DMA_EN(base))));
/*write vfifo base address to VFF_ADDR*/
		btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base));
/*write vfifo length to VFF_LEN*/
		btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base));
/*write wpt to VFF_WPT*/
		btif_reg_sync_writel(p_mtk_dma_vfifo->wpt,
				     RX_DMA_VFF_WPT(base));
		btif_reg_sync_writel(p_mtk_dma_vfifo->rpt,
					 RX_DMA_VFF_RPT(base));
/*write vff_thre to VFF_THRESHOLD*/
		btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base));
/*clear Rx DMA's interrupt status*/
		BTIF_SET_BIT(RX_DMA_INT_FLAG(base),
			     RX_DMA_INT_DONE | RX_DMA_INT_THRE);

/*enable Rx IER by default*/
		btif_rx_dma_ier_ctrl(p_dma_info, true);
	} else {
/*Tx DMA*/
/*do hardware reset*/
//		BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);
//		BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);
		BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST);
		while((0x01 & BTIF_READ32(TX_DMA_EN(base))));
/*write vfifo base address to VFF_ADDR*/
		btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base));
/*write vfifo length to VFF_LEN*/
		btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base));
/*write wpt to VFF_WPT*/
		btif_reg_sync_writel(p_mtk_dma_vfifo->wpt,
				     TX_DMA_VFF_WPT(base));
		btif_reg_sync_writel(p_mtk_dma_vfifo->rpt,
				     TX_DMA_VFF_RPT(base));
/*write vff_thre to VFF_THRESHOLD*/
		btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base));

		BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK);

		hal_btif_dma_ier_ctrl(p_dma_info, false);
	}

	return i_ret;
}
コード例 #2
0
/*****************************************************************************
* FUNCTION
*  hal_rx_dma_irq_handler
* DESCRIPTION
*  lower level rx interrupt handler
* PARAMETERS
* p_dma_info   [IN]        pointer to BTIF dma channel's information
* p_buf     [IN/OUT] pointer to rx data buffer
* max_len  [IN]        max length of rx buffer
* RETURNS
*  0 means success, negative means fail
*****************************************************************************/
int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info,
			   unsigned char *p_buf, const unsigned int max_len)
{
	int i_ret = -1;
	unsigned int valid_len = 0;
	unsigned int wpt_wrap = 0;
	unsigned int rpt_wrap = 0;
	unsigned int wpt = 0;
	unsigned int rpt = 0;
	unsigned int tail_len = 0;
	unsigned int real_len = 0;
	unsigned int base = p_dma_info->base;
	P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo;
	dma_rx_buf_write rx_cb = p_dma_info->rx_cb;
	unsigned char *p_vff_buf = NULL;
	unsigned char *vff_base = p_vfifo->p_vir_addr;
	unsigned int vff_size = p_vfifo->vfifo_size;
	P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo,
							MTK_BTIF_DMA_VFIFO,
							vfifo);
	unsigned long flag = 0;

	spin_lock_irqsave(&(g_clk_cg_spinlock), flag);
	if (0 == clock_is_on(MTK_BTIF_APDMA_CLK_CG)) {
		spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
		BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n",
			      __FILE__);
		return i_ret;
	}
/*disable DMA Rx IER*/
	hal_btif_dma_ier_ctrl(p_dma_info, false);

/*clear Rx DMA's interrupt status*/
	BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE);

	valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));
	rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
	wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
	if ((0 == valid_len) && (rpt == wpt)) {
		BTIF_DBG_FUNC
		    ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n",
		     rpt, wpt);
	}

	i_ret = 0;

	while ((0 < valid_len) || (rpt != wpt)) {
		rpt_wrap = rpt & DMA_RPT_WRAP;
		wpt_wrap = wpt & DMA_WPT_WRAP;
		rpt &= DMA_RPT_MASK;
		wpt &= DMA_WPT_MASK;

/*calcaute length of available data  in vFIFO*/
		if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) {
			real_len = wpt + vff_size - rpt;
		} else {
			real_len = wpt - rpt;
		}

		if (NULL != rx_cb) {
			tail_len = vff_size - rpt;
			p_vff_buf = vff_base + rpt;
			if (tail_len >= real_len) {
				(*rx_cb) (p_dma_info, p_vff_buf, real_len);
			} else {
				(*rx_cb) (p_dma_info, p_vff_buf, tail_len);
				p_vff_buf = vff_base;
				(*rx_cb) (p_dma_info, p_vff_buf, real_len -
					  tail_len);
			}
			i_ret += real_len;
		} else {
			BTIF_ERR_FUNC
			    ("no rx_cb found, please check your init process\n");
		}
		dsb();
		rpt += real_len;
		if (rpt >= vff_size) {
/*read wrap bit should be revert*/
			rpt_wrap ^= DMA_RPT_WRAP;
			rpt %= vff_size;
		}
		rpt |= rpt_wrap;
/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/
		p_mtk_vfifo->wpt = wpt;
		p_mtk_vfifo->last_wpt_wrap = wpt_wrap;

		p_mtk_vfifo->rpt = rpt;
		p_mtk_vfifo->last_rpt_wrap = rpt_wrap;

/*update rpt information to DMA controller*/
		btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base));

/*get vff valid size again and check if rx data is processed completely*/
		valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));

		rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
		wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
	}

/*enable DMA Rx IER*/
	hal_btif_dma_ier_ctrl(p_dma_info, true);
	spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag);
	return i_ret;
}
コード例 #3
0
static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info,
			       ENUM_BTIF_REG_ID flag)
{
	int i_ret = -1;
	unsigned int base = p_dma_info->base;
	unsigned int int_flag = 0;
	unsigned int enable = 0;
	unsigned int stop = 0;
	unsigned int flush = 0;
	unsigned int wpt = 0;
	unsigned int rpt = 0;
	unsigned int int_buf = 0;
	unsigned int valid_size = 0;
	/*unsigned long irq_flag = 0;*/

	/*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/
	if (0 == clock_is_on(MTK_BTIF_APDMA_CLK_CG)) {
		/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/
		BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n",
			      __FILE__);
		return i_ret;
	}

	int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base));
	enable = BTIF_READ32(RX_DMA_EN(base));
	stop = BTIF_READ32(RX_DMA_STOP(base));
	flush = BTIF_READ32(RX_DMA_FLUSH(base));
	wpt = BTIF_READ32(RX_DMA_VFF_WPT(base));
	rpt = BTIF_READ32(RX_DMA_VFF_RPT(base));
	int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base));
	valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base));
	/*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/

	BTIF_INFO_FUNC("DMA's clock is on\n");
	BTIF_INFO_FUNC("Rx DMA's base address: 0x%x\n", base);

	if (REG_RX_DMA_ALL == flag) {
		BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable);
		BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop);
		BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush);
		BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag);
		BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt);
		BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt);
		BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf);
		BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size);
		BTIF_INFO_FUNC("INT_EN:0x%x\n",
			       BTIF_READ32(RX_DMA_INT_EN(base)));
		BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base)));
		BTIF_INFO_FUNC("VFF_ADDR:0x%x\n",
			       BTIF_READ32(RX_DMA_VFF_ADDR(base)));
		BTIF_INFO_FUNC("VFF_LEN:0x%x\n",
			       BTIF_READ32(RX_DMA_VFF_LEN(base)));
		BTIF_INFO_FUNC("RX_THRE:0x%x\n",
			       BTIF_READ32(RX_DMA_VFF_THRE(base)));
		BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n",
			       BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base)));
		BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n",
			       BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base)));
		BTIF_INFO_FUNC("DBG_STATUS:0x%x\n",
			       BTIF_READ32(RX_DMA_DEBUG_STATUS(base)));
		i_ret = 0;
	} else {
		BTIF_WARN_FUNC("unknown flag:%d\n", flag);
	}
	BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) &&
		       (!(stop && DMA_STOP_BIT)) ? "enabled" : "stoped");
	BTIF_INFO_FUNC("data in rx dma is %s by driver\n",
		       ((wpt == rpt) &&
			(int_buf == 0)) ? "received" : "not received");

	return i_ret;
}