Exemplo n.º 1
0
/**
 * mu3d_hal_resume_qmu - resume qmu function
 * @args - arg1: ep number, arg2: dir
 */
void mu3d_hal_resume_qmu(DEV_INT32 q_num, USB_DIR dir)
{
	if (dir == USB_TX) {
		/* qmu_printk(K_DEBUG, "%s EP%d CSR=%x, CPR=%x\n", __func__, q_num, os_readl(USB_QMU_TQCSR(q_num)), os_readl(USB_QMU_TQCPR(q_num))); */
		os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME);
		if (!os_readl(USB_QMU_TQCSR(q_num))) {
			qmu_printk(K_WARNIN, "[ERROR]" "%s TQCSR[%d]=%x\n", __func__, q_num,
				   os_readl(USB_QMU_TQCSR(q_num)));
			os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME);
			qmu_printk(K_WARNIN, "[ERROR]" "%s TQCSR[%d]=%x\n", __func__, q_num,
				   os_readl(USB_QMU_TQCSR(q_num)));
		}
	} else if (dir == USB_RX) {
		os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME);
		if (!os_readl(USB_QMU_RQCSR(q_num))) {
			qmu_printk(K_WARNIN, "[ERROR]" "%s RQCSR[%d]=%x\n", __func__, q_num,
				   os_readl(USB_QMU_RQCSR(q_num)));
			os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME);
			qmu_printk(K_WARNIN, "[ERROR]" "%s RQCSR[%d]=%x\n", __func__, q_num,
				   os_readl(USB_QMU_RQCSR(q_num)));
		}
	} else {
		qmu_printk(K_ERR, "%s wrong direction!!!\n", __func__);
		BUG_ON(1);
	}
}
Exemplo n.º 2
0
/**
 * mu3d_hal_resume_qmu - resume qmu function
 * @args - arg1: ep number, arg2: dir
 */
void mu3d_hal_resume_qmu(DEV_INT32 q_num, USB_DIR dir)
{

#if defined(USB_RISC_CACHE_ENABLED)
	os_flushinvalidateDcache();
#endif

	if (dir == USB_TX) {
		os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME);
		if (!os_readl(USB_QMU_TQCSR(q_num))) {
			os_printk(K_DEBUG, "%s QMU_TQCSR[%d]=%x\n", __func__, q_num,
				  os_readl(USB_QMU_TQCSR(q_num)));
			os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME);
		}
	} else if (dir == USB_RX) {
		os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME);
		if (!os_readl(USB_QMU_RQCSR(q_num))) {
			os_printk(K_DEBUG, "%s QMU_RQCSR[%d]=%x\n", __func__, q_num,
				  os_readl(USB_QMU_RQCSR(q_num)));
			os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME);
		}
	} else {
		os_printk(K_INFO, "%s wrong direction!!!\n", __func__);
		BUG_ON(1);
	}
}
/**
 * mu3d_hal_stop_qmu - stop qmu function (after qmu stop, fifo should be flushed)
 * @args - arg1: ep number, arg2: dir
 */
void mu3d_hal_stop_qmu(DEV_INT32 q_num,  USB_DIR dir)
{
	if (dir == USB_TX) {
		if(!(os_readl(USB_QMU_TQCSR(q_num)) & (QMU_Q_ACTIVE))){
			qmu_printk(K_CRIT, "Tx%d inActive Now!\n", q_num);
			return;
		}
		os_writel(USB_QMU_TQCSR(q_num), QMU_Q_STOP);
		mb();
		if(wait_for_value(USB_QMU_TQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS)
			qmu_printk(K_CRIT, "Tx%d stop Now! CSR=0x%x\n", q_num, os_readl(USB_QMU_TQCSR(q_num)));
		else {
			qmu_printk(K_CRIT, "Tx%d UNSTOPABLE!! CSR=0x%x\n", q_num, os_readl(USB_QMU_TQCSR(q_num)));
			WARN_ON(1);
		}
	} else if(dir == USB_RX) {
		if(!(os_readl(USB_QMU_RQCSR(q_num)) & QMU_Q_ACTIVE)){
			qmu_printk(K_CRIT, "Rx%d inActive Now!\n", q_num);
			return;
		}
 		os_writel(USB_QMU_RQCSR(q_num), QMU_Q_STOP);
		mb();
		if(wait_for_value(USB_QMU_RQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS)
			qmu_printk(K_CRIT, "Rx%d stop Now! CSR=0x%x\n", q_num, os_readl(USB_QMU_RQCSR(q_num)));
		else {
			qmu_printk(K_CRIT, "Rx%d UNSTOPABLE!! CSR=0x%x\n", q_num, os_readl(USB_QMU_RQCSR(q_num)));
			WARN_ON(1);
		}
	}
}
Exemplo n.º 4
0
/*
   When receiving RXQ done interrupt, qmu_interrupt calls this function.

   1. Traverse GPD/BD data structures to count actual transferred length.
   2. Set the done flag to notify rxstate_qmu() to report status to upper gadget driver.

    ported from proc_qmu_rx() from test driver.

    caller:qmu_interrupt after getting QMU done interrupt and TX is raised

*/
void qmu_done_rx(struct musb *musb, u8 ep_num, unsigned long flags)
{
	TGPD *gpd = Rx_gpd_last[ep_num];
	TGPD *gpd_current = (TGPD *) (os_readl(USB_QMU_RQCPR(ep_num)));
	struct musb_ep *musb_ep = &musb->endpoints[ep_num].ep_out;
	struct usb_request *request = NULL;
	struct musb_request *req;

	/* trying to give_back the request to gadget driver. */
	req = next_request(musb_ep);
	if (!req) {
		qmu_printk(K_ERR, "[RXD]" "%s Cannot get next request of %d, "
			   "but QMU has done.\n", __func__, ep_num);
		return;
	} else {
		request = &req->request;
	}

	/*Transfer PHY addr got from QMU register to VIR addr */
	gpd_current = phys_to_virt((unsigned long)gpd_current);

	qmu_printk(K_DEBUG, "[RXD]" "%s EP%d, Last=%p, Current=%p, End=%p\n",
		   __func__, ep_num, gpd, gpd_current, Rx_gpd_end[ep_num]);

	/*gpd_current should at least point to the next GPD to the previous last one. */
	if (gpd == gpd_current) {
		qmu_printk(K_ERR, "[RXD][ERROR]" "%s gpd(%p) == gpd_current(%p)\n", __func__, gpd,
			   gpd_current);

		qmu_printk(K_ERR, "[RXD][ERROR]" "EP%d RQCSR=%x, RQSAR=%x, RQCPR=%x, RQLDPR=%x\n",
			   ep_num, os_readl(USB_QMU_RQCSR(ep_num)), os_readl(USB_QMU_RQSAR(ep_num)),
			   os_readl(USB_QMU_RQCPR(ep_num)), os_readl(USB_QMU_RQLDPR(ep_num)));

		qmu_printk(K_ERR, "[RXD][ERROR]" "QCR0=%x, QCR1=%x, QCR2=%x, QCR3=%x, "
			   "QGCSR=%x\n", os_readl(U3D_QCR0), os_readl(U3D_QCR1), os_readl(U3D_QCR2),
			   os_readl(U3D_QCR3), os_readl(U3D_QGCSR));

		qmu_printk(K_INFO, "[RXD][ERROR]" "HWO=%d, Next_GPD=%x ,DataBufLen=%d, "
			   "DataBuf=%x, RecvLen=%d, Endpoint=%d\n",
			   (DEV_UINT32) TGPD_GET_FLAG(gpd), (DEV_UINT32) TGPD_GET_NEXT(gpd),
			   (DEV_UINT32) TGPD_GET_DataBUF_LEN(gpd), (DEV_UINT32) TGPD_GET_DATA(gpd),
			   (DEV_UINT32) TGPD_GET_BUF_LEN(gpd), (DEV_UINT32) TGPD_GET_EPaddr(gpd));

		return;
	}

	spin_unlock_irqrestore(&musb->lock, flags);

	/* invalidate GPD data in CPU */
	dma_sync_single_for_cpu(musb->controller, virt_to_phys(gpd), sizeof(TGPD), DMA_FROM_DEVICE);

	spin_lock_irqsave(&musb->lock, flags);

	if (!gpd || !gpd_current) {
		qmu_printk(K_ERR, "[RXD][ERROR]" "%s EP%d, gpd=%p, gpd_current=%p, ishwo=%d, \
			rx_gpd_last=%p, RQCPR=0x%x\n", __func__, ep_num, gpd, gpd_current, ((gpd == NULL) ? 999 : TGPD_IS_FLAGS_HWO(gpd)), Rx_gpd_last[ep_num], os_readl(USB_QMU_RQCPR(ep_num)));
		return;
	}
Exemplo n.º 5
0
/**
 * mu3d_hal_stop_qmu - stop qmu function (after qmu stop, fifo should be flushed)
 * @args - arg1: ep number, arg2: dir
 */
void mu3d_hal_stop_qmu(DEV_INT32 q_num, USB_DIR dir)
{
	if (dir == USB_TX) {
		if (!(os_readl(USB_QMU_TQCSR(q_num)) & (QMU_Q_ACTIVE))) {
			qmu_printk(K_DEBUG, "Tx%d inActive Now!\n", q_num);
			return;
		}
		os_writel(USB_QMU_TQCSR(q_num), QMU_Q_STOP);
		while ((os_readl(USB_QMU_TQCSR(q_num)) & (QMU_Q_ACTIVE)));
		qmu_printk(K_CRIT, "Tx%d stop Now!\n", q_num);
	} else if (dir == USB_RX) {
		if (!(os_readl(USB_QMU_RQCSR(q_num)) & QMU_Q_ACTIVE)) {
			qmu_printk(K_DEBUG, "Rx%d inActive Now!\n", q_num);
			return;
		}
		os_writel(USB_QMU_RQCSR(q_num), QMU_Q_STOP);
		while ((os_readl(USB_QMU_RQCSR(q_num)) & (QMU_Q_ACTIVE)));
		qmu_printk(K_CRIT, "Rx%d stop now!\n", q_num);
	}
}
Exemplo n.º 6
0
/*
   When receiving RXQ done interrupt, qmu_interrupt calls this function.

   1. Traverse GPD/BD data structures to count actual transferred length.
   2. Set the done flag to notify rxstate_qmu() to report status to upper gadget driver.

    ported from proc_qmu_rx() from test driver.

    caller:qmu_interrupt after getting QMU done interrupt and TX is raised

*/
void qmu_done_rx(struct musb *musb, u8 ep_num, unsigned long flags)
{
	TGPD* gpd = Rx_gpd_last[ep_num];
	TGPD* gpd_current = (TGPD*)(uintptr_t)(os_readl(USB_QMU_RQCPR(ep_num))); //QMU GPD address --> CPU DMA address
	struct musb_ep		*musb_ep = &musb->endpoints[ep_num].ep_out;
	struct usb_request	*request = NULL;
	struct musb_request	*req;

	//trying to give_back the request to gadget driver.
	req = next_request(musb_ep);
	if (!req) {
		qmu_printk(K_ERR, "[RXD]""%s Cannot get next request of %d, "
			"but QMU has done.\n", __func__, ep_num);
		return;
	} else {
		request = &req->request;
	}

	/*Transfer PHY addr got from QMU register to VIR addr*/
	gpd_current = gpd_phys_to_virt(gpd_current, USB_RX, ep_num);

	qmu_printk(K_DEBUG, "[RXD]""%s EP%d, Last=%p, Current=%p, End=%p\n",
		__func__, ep_num, gpd, gpd_current, Rx_gpd_end[ep_num]);

	/*gpd_current should at least point to the next GPD to the previous last one.*/
	if (gpd == gpd_current) {
		qmu_printk(K_ERR, "[RXD][ERROR]""%s gpd(%p) == gpd_current(%p)\n", __func__, gpd, \
			gpd_current);

		qmu_printk(K_ERR, "[RXD][ERROR]""EP%d RQCSR=%x, RQSAR=%x, RQCPR=%x, RQLDPR=%x\n",
				ep_num, os_readl(USB_QMU_RQCSR(ep_num)), os_readl(USB_QMU_RQSAR(ep_num)),
				os_readl(USB_QMU_RQCPR(ep_num)), os_readl(USB_QMU_RQLDPR(ep_num)));

		qmu_printk(K_ERR, "[RXD][ERROR]""QCR0=%x, QCR1=%x, QCR2=%x, QCR3=%x, "
			"QGCSR=%x\n", os_readl(U3D_QCR0), os_readl(U3D_QCR1), os_readl(U3D_QCR2), \
			os_readl(U3D_QCR3), os_readl(U3D_QGCSR));

		qmu_printk(K_INFO,"[RXD][ERROR]""HWO=%d, Next_GPD=%lx ,DataBufLen=%d, "
			"DataBuf=%lx, RecvLen=%d, Endpoint=%d\n",
			(u32)TGPD_GET_FLAG(gpd), (uintptr_t)TGPD_GET_NEXT(gpd),
			(u32)TGPD_GET_DataBUF_LEN(gpd), (uintptr_t)TGPD_GET_DATA(gpd),
			(u32)TGPD_GET_BUF_LEN(gpd), (u32)TGPD_GET_EPaddr(gpd));

		return;
	}

	if(!gpd || !gpd_current) {
		qmu_printk(K_ERR, "[RXD][ERROR]""%s EP%d, gpd=%p, gpd_current=%p, ishwo=%d, \
			rx_gpd_last=%p, RQCPR=0x%x\n", __func__,
			ep_num, gpd, gpd_current, ((gpd==NULL) ? 999 : TGPD_IS_FLAGS_HWO(gpd)),
			Rx_gpd_last[ep_num], os_readl(USB_QMU_RQCPR(ep_num)));
		return;
	}
Exemplo n.º 7
0
/**
 * mu3d_hal_start_qmu - start qmu function (QMU flow : mu3d_hal_init_qmu ->mu3d_hal_start_qmu -> mu3d_hal_insert_transfer_gpd -> mu3d_hal_resume_qmu)
 * @args - arg1: ep number, arg2: dir
 */
void mu3d_hal_start_qmu(DEV_INT32 Q_num, USB_DIR dir)
{
	DEV_UINT32 QCR;
	DEV_UINT32 txcsr;

	if (dir == USB_TX) {
		txcsr = USB_ReadCsr32(U3D_TX1CSR0, Q_num) & 0xFFFEFFFF;
		USB_WriteCsr32(U3D_TX1CSR0, Q_num, txcsr | TX_DMAREQEN);
		QCR = os_readl(U3D_QCR0);
		os_writel(U3D_QCR0, QCR | QMU_TX_CS_EN(Q_num));
#if (TXZLP == HW_MODE)
		QCR = os_readl(U3D_QCR1);
		os_writel(U3D_QCR1, QCR & ~QMU_TX_ZLP(Q_num));
		QCR = os_readl(U3D_QCR2);
		os_writel(U3D_QCR2, QCR | QMU_TX_ZLP(Q_num));
#elif (TXZLP == GPD_MODE)
		QCR = os_readl(U3D_QCR1);
		os_writel(U3D_QCR1, QCR | QMU_TX_ZLP(Q_num));
#endif
		os_writel(U3D_QEMIESR, os_readl(U3D_QEMIESR) | QMU_TX_EMPTY(Q_num));
		os_writel(U3D_TQERRIESR0, QMU_TX_LEN_ERR(Q_num) | QMU_TX_CS_ERR(Q_num));

		qmu_printk(K_INFO, "USB_QMU_TQCSR:0x%08X\n", os_readl(USB_QMU_TQCSR(Q_num)));

		if (os_readl(USB_QMU_TQCSR(Q_num)) & QMU_Q_ACTIVE) {
			qmu_printk(K_INFO, "Tx %d Active Now!\n", Q_num);
			return;
		}

		os_writel(USB_QMU_TQCSR(Q_num), QMU_Q_START);

		qmu_printk(K_INFO, "USB_QMU_TQCSR:0x%08X\n", os_readl(USB_QMU_TQCSR(Q_num)));
	} else if (dir == USB_RX) {
		USB_WriteCsr32(U3D_RX1CSR0, Q_num,
			       USB_ReadCsr32(U3D_RX1CSR0, Q_num) | (RX_DMAREQEN));
		QCR = os_readl(U3D_QCR0);
		os_writel(U3D_QCR0, QCR | QMU_RX_CS_EN(Q_num));

#ifdef CFG_RX_ZLP_EN
		QCR = os_readl(U3D_QCR3);
		os_writel(U3D_QCR3, QCR | QMU_RX_ZLP(Q_num));
#else
		QCR = os_readl(U3D_QCR3);
		os_writel(U3D_QCR3, QCR & ~(QMU_RX_ZLP(Q_num)));
#endif

#ifdef CFG_RX_COZ_EN
		QCR = os_readl(U3D_QCR3);
		os_writel(U3D_QCR3, QCR | QMU_RX_COZ(Q_num));
#else
		QCR = os_readl(U3D_QCR3);
		os_writel(U3D_QCR3, QCR & ~(QMU_RX_COZ(Q_num)));
#endif

		os_writel(U3D_QEMIESR, os_readl(U3D_QEMIESR) | QMU_RX_EMPTY(Q_num));
		os_writel(U3D_RQERRIESR0, QMU_RX_LEN_ERR(Q_num) | QMU_RX_CS_ERR(Q_num));
		os_writel(U3D_RQERRIESR1, QMU_RX_EP_ERR(Q_num) | QMU_RX_ZLP_ERR(Q_num));

		qmu_printk(K_INFO, "USB_QMU_RQCSR:0x%08X\n", os_readl(USB_QMU_RQCSR(Q_num)));

		if (os_readl(USB_QMU_RQCSR(Q_num)) & QMU_Q_ACTIVE) {
			qmu_printk(K_INFO, "Rx %d Active Now!\n", Q_num);
			return;
		}

		os_writel(USB_QMU_RQCSR(Q_num), QMU_Q_START);

		qmu_printk(K_INFO, "USB_QMU_RQCSR:0x%08X\n", os_readl(USB_QMU_RQCSR(Q_num)));
	}
#if (CHECKSUM_TYPE == CS_16B)
	os_writel(U3D_QCR0, os_readl(U3D_QCR0) | CS16B_EN);
#else
	os_writel(U3D_QCR0, os_readl(U3D_QCR0) & ~CS16B_EN);
#endif
}