/*----------------------------------------------------------------------------*/ static VOID HifGdmaReset( IN void *HifInfoSrc ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; UINT32 LoopCnt; /* do warm reset: DMA will wait for current traction finished */ printk("\nDMA> do warm reset...\n"); /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_RST, 0x01); for(LoopCnt=0; LoopCnt<10000; LoopCnt++) { if (!HifGdmaPollStart(HifInfo)) break; /* reset ok */ } if (HifGdmaPollStart(HifInfo)) { /* do hard reset because warm reset fails */ printk("\nDMA> do hard reset...\n"); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_RST, 0x02); msleep(1); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_RST, 0x00); } }
/*----------------------------------------------------------------------------*/ static VOID HifGdmaStop( IN void *HifInfoSrc ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; UINT32 RegVal; // UINT32 pollcnt; /* Disable interrupt */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_INT_EN); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); #if 0 /* DE says we donot need to do it */ /* Stop DMA */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_STOP); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_STOP, (RegVal | ADH_CR_STOP)); /* Polling START bit turn to 0 */ pollcnt = 0; do { RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_EN); if (pollcnt++ > 100000) { /* TODO: warm reset GDMA */ } } while(RegVal&ADH_CR_EN); #endif } /* End of HifGdmaStop */
/*----------------------------------------------------------------------------*/ static VOID HifGdmaStart( IN GL_HIF_INFO_T *HifInfo ) { UINT32 RegVal; /* Enable interrupt */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_INT_EN); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); /* Start DMA */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_EN); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_EN, (RegVal | ADH_CR_EN | ADH_CR_CONN_BUR_EN)); GDMA_DBG(("GDMA> HifGdmaStart...\n")); } /* End of HifGdmaStart */
/*----------------------------------------------------------------------------*/ static VOID HifPdmaStart( IN void *HifInfoSrc ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; UINT_32 RegVal; /* Enable interrupt */ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); /* Start DMA */ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); PDMA_DBG(("PDMA> HifPdmaStart...\n")); } /* End of HifPdmaStart */
/*----------------------------------------------------------------------------*/ static VOID HifPdmaConfig ( IN void *HifInfoSrc, IN void *Param ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *)Param; UINT_32 RegVal; /* Assign fixed value */ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ Conf->Fix_en = FALSE; /* AP_P_DMA_G_DMA_2_CON */ PDMA_DBG(("PDMA> Conf->Dir = %d\n", Conf->Dir)); /* AP_DMA_HIF_0_CON */ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); RegVal |= (((Conf->Burst<<ADH_CR_BURST_LEN_OFFSET)&ADH_CR_BURST_LEN) | \ (Conf->Fix_en<<ADH_CR_FIX_EN_OFFSET) | \ (Conf->Dir)); HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); PDMA_DBG(("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal)); /* AP_DMA_HIF_0_SRC_ADDR */ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); PDMA_DBG(("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08x\n", Conf->Src)); /* AP_DMA_HIF_0_DST_ADDR */ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); PDMA_DBG(("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08x\n", Conf->Dst)); /* AP_DMA_HIF_0_LEN */ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); PDMA_DBG(("PDMA> AP_DMA_HIF_0_LEN = %u\n", (Conf->Count & ADH_CR_LEN))); }/* End of HifPdmaConfig */
/*----------------------------------------------------------------------------*/ static VOID HifGdmaAckIntr( IN GL_HIF_INFO_T *HifInfo ) { UINT32 RegVal; /* Write 0 to clear interrupt */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_INT_FLAG); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); } /* End of HifGdmaAckIntr */
/*----------------------------------------------------------------------------*/ static VOID HifPdmaAckIntr( IN void *HifInfoSrc ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; UINT_32 RegVal; /* Write 0 to clear interrupt */ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); } /* End of HifPdmaAckIntr */
/*----------------------------------------------------------------------------*/ static VOID HifGdmaConfig ( IN void *HifInfoSrc, IN void *Param ) { GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *)HifInfoSrc; MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *)Param; UINT32 RegVal; /* Assign fixed value */ Conf->Ratio = HIF_GDMA_RATIO_1; Conf->Connect = HIF_GDMA_CONNECT_SET1; Conf->Wsize = HIF_GDMA_WRITE_2; Conf->Burst = HIF_GDMA_BURST_4_8; Conf->Fix_en = TRUE; /* AP_P_DMA_G_DMA_2_CON */ GDMA_DBG(("GDMA> Conf->Dir = %d\n", Conf->Dir)); RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_CON); RegVal &= ~(ADH_CR_FLAG_FINISH | ADH_CR_RSIZE | ADH_CR_WSIZE | \ ADH_CR_BURST_LEN | ADH_CR_WADDR_FIX_EN | ADH_CR_RADDR_FIX_EN); if (Conf->Dir == HIF_DMA_DIR_TX) { RegVal |= (((Conf->Wsize<<ADH_CR_WSIZE_OFFSET)&ADH_CR_WSIZE) | \ ((Conf->Burst<<ADH_CR_BURST_LEN_OFFSET)&ADH_CR_BURST_LEN) | \ ((Conf->Fix_en<<ADH_CR_WADDR_FIX_EN_OFFSET)&ADH_CR_WADDR_FIX_EN)); } else { RegVal |= (((Conf->Wsize<<ADH_CR_RSIZE_OFFSET)&ADH_CR_RSIZE) | \ ((Conf->Burst<<ADH_CR_BURST_LEN_OFFSET)&ADH_CR_BURST_LEN) | \ ((Conf->Fix_en<<ADH_CR_RADDR_FIX_EN_OFFSET)&ADH_CR_RADDR_FIX_EN)); } HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_CON, RegVal); GDMA_DBG(("GDMA> AP_P_DMA_G_DMA_2_CON = 0x%08x\n", RegVal)); /* AP_P_DMA_G_DMA_2_CONNECT */ RegVal = HIF_DMAR_READL(HifInfo, AP_P_DMA_G_DMA_2_CONNECT); RegVal &= ~(ADH_CR_RATIO | ADH_CR_DIR | ADH_CR_CONNECT); RegVal |= (((Conf->Ratio<<ADH_CR_RATIO_OFFSET)&ADH_CR_RATIO) | \ ((Conf->Dir<<ADH_CR_DIR_OFFSET)&ADH_CR_DIR) | \ (Conf->Connect&ADH_CR_CONNECT)); HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_CONNECT, RegVal); GDMA_DBG(("GDMA> AP_P_DMA_G_DMA_2_CONNECT = 0x%08x\n", RegVal)); /* AP_DMA_HIF_0_SRC_ADDR */ HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_SRC_ADDR, Conf->Src); GDMA_DBG(("GDMA> AP_P_DMA_G_DMA_2_SRC_ADDR = 0x%08x\n", Conf->Src)); /* AP_DMA_HIF_0_DST_ADDR */ HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_DST_ADDR, Conf->Dst); GDMA_DBG(("GDMA> AP_P_DMA_G_DMA_2_DST_ADDR = 0x%08x\n", Conf->Dst)); /* AP_P_DMA_G_DMA_2_LEN1 */ HIF_DMAR_WRITEL(HifInfo, AP_P_DMA_G_DMA_2_LEN1, (Conf->Count & ADH_CR_LEN)); GDMA_DBG(("GDMA> AP_P_DMA_G_DMA_2_LEN1 = %ld\n", (Conf->Count & ADH_CR_LEN))); }/* End of HifGdmaConfig */