static void serial_omap_start_rxdma(struct uart_omap_port *up)
{
#ifdef CONFIG_OMAP3_PM
	/* Disallow OCP bus idle. UART TX irqs are not seen during
	 * bus idle. Alternative is to set kernel timer at fifo
	 * drain rate.
	 */
	unsigned int tmp;
	tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3);
	serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */
#endif
	if (up->uart_dma.rx_dma_channel == 0xFF) {
		omap_request_dma(uart_dma_rx[up->pdev->id-1],"UART Rx DMA",
				(void *)uart_rx_dma_callback,up,
				&(up->uart_dma.rx_dma_channel));
		omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0,
					OMAP_DMA_AMODE_CONSTANT,
					UART_BASE(up->pdev->id - 1), 0, 0);
		omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0,
					OMAP_DMA_AMODE_POST_INC,
					up->uart_dma.rx_buf_dma_phys, 0, 0);
		omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel,
					OMAP_DMA_DATA_TYPE_S8,
					up->uart_dma.rx_buf_size, 1,
					OMAP_DMA_SYNC_ELEMENT,
					uart_dma_rx[up->pdev->id-1], 0);
	}
	up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys;
	omap_writel(0, OMAP34XX_DMA4_BASE +
		OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel));
	omap_start_dma(up->uart_dma.rx_dma_channel);
	mod_timer(&up->uart_dma.rx_timer, jiffies +
			usecs_to_jiffies(up->uart_dma.rx_timeout));
	up->uart_dma.rx_dma_state = 1;
}
static void serial_omap_continue_tx(struct uart_omap_port *up)
{
	struct circ_buf *xmit = &up->port.info->xmit;
	int start = up->uart_dma.tx_buf_dma_phys + (xmit->tail & (UART_XMIT_SIZE - 1));
	if (uart_circ_empty(xmit))  {
			return;
	}

	up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
	/* It is a circular buffer. See if the buffer has wounded back.
	* If yes it will have to be transferred in two separate dma
	* transfers
	*/
	if (start + up->uart_dma.tx_buf_size >=
			up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
		up->uart_dma.tx_buf_size =
			(up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start;
	omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
				 OMAP_DMA_AMODE_CONSTANT, UART_BASE(up->pdev->id - 1), 0,0);
	omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
		OMAP_DMA_AMODE_POST_INC, start, 0,0);

	omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
				     OMAP_DMA_DATA_TYPE_S8, up->uart_dma.tx_buf_size, 1,
				     OMAP_DMA_SYNC_ELEMENT,
				     uart_dma_tx[(up->pdev->id)-1], 0);

	omap_start_dma(up->uart_dma.tx_dma_channel);
}
Esempio n. 3
0
static void serial_omap_start_tx(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
#ifdef CONFIG_OMAP3_PM
		/* Disallow OCP bus idle. UART TX irqs are not seen during
		 * bus idle. Alternative is to set kernel timer at fifo
		 * drain rate.
		 */
		unsigned int tmp;
		tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3);
		serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */
#endif

	if (up->use_dma && !(up->port.x_char)) {

		struct circ_buf *xmit = &up->port.info->xmit;
		unsigned int start = up->uart_dma.tx_buf_dma_phys +
				     (xmit->tail & (UART_XMIT_SIZE - 1));
		if (uart_circ_empty(xmit) || up->uart_dma.tx_dma_state)
			return;
		spin_lock(&(up->uart_dma.tx_lock));
		up->uart_dma.tx_dma_state = 1;
		spin_unlock(&(up->uart_dma.tx_lock));

		up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit);
		/* It is a circular buffer. See if the buffer has wounded back.
		 * If yes it will have to be transferred in two separate dma
		 * transfers */
		if (start + up->uart_dma.tx_buf_size >=
				up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE)
			up->uart_dma.tx_buf_size =
				(up->uart_dma.tx_buf_dma_phys +
				UART_XMIT_SIZE) - start;

		if (up->uart_dma.tx_dma_channel == 0xFF)
			omap_request_dma(uart_dma_tx[up->pdev->id-1],
					"UART Tx DMA",
					(void *)uart_tx_dma_callback, up,
					&(up->uart_dma.tx_dma_channel));
		omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0,
					 OMAP_DMA_AMODE_CONSTANT,
					 UART_BASE(up->pdev->id - 1), 0, 0);
		omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0,
					OMAP_DMA_AMODE_POST_INC, start, 0, 0);

		omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel,
					     OMAP_DMA_DATA_TYPE_S8,
					     up->uart_dma.tx_buf_size, 1,
					     OMAP_DMA_SYNC_ELEMENT,
					     uart_dma_tx[(up->pdev->id)-1], 0);

		omap_start_dma(up->uart_dma.tx_dma_channel);

	} else if (!(up->ier & UART_IER_THRI)) {
		up->ier |= UART_IER_THRI;
		serial_out(up, UART_IER, up->ier);
	}
}
Esempio n. 4
0
static int s3c24x0_uart_init(void)
{
	int num;

	writel(VA(GPIO_BASE + GPH_CON), 0x16faaa);
	writel(VA(GPIO_BASE + GPH_UP), 0x7ff);

	for (num = 0; num < UART_NUM; num++) {
		writel(UART_BASE(num) + ULCON, 0x3);
		writel(UART_BASE(num) + UCON, 0x245);

#ifdef CONFIG_UART_ENABLE_FIFO
		writel(UART_BASE(num) + UFCON, 1);
#else
		writel(UART_BASE(num) + UFCON, 0);
#endif

		writel(UART_BASE(num) + UBRDIV, (PCLK_RATE / (BR115200 * 16)) - 1);
	}

	return 0;
}