Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4d640c9 authored by Roy Huang's avatar Roy Huang Committed by Bryan Wu
Browse files

Blackfin serial driver: supporting BF548-EZKIT serial port

parent db83b991
Loading
Loading
Loading
Loading
+43 −3
Original line number Diff line number Diff line
@@ -599,7 +599,7 @@ config UART0_RTS_PIN

config SERIAL_BFIN_UART1
	bool "Enable UART1"
	depends on SERIAL_BFIN && (BF534 || BF536 || BF537)
	depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x)
	help
	  Enable UART1

@@ -612,18 +612,58 @@ config BFIN_UART1_CTSRTS

config UART1_CTS_PIN
	int "UART1 CTS pin"
	depends on BFIN_UART1_CTSRTS
	depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
	default -1
	help
	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config UART1_RTS_PIN
	int "UART1 RTS pin"
	depends on BFIN_UART1_CTSRTS
	depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
	default -1
	help
	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config SERIAL_BFIN_UART2
	bool "Enable UART2"
	depends on SERIAL_BFIN && (BF54x)
	help
	  Enable UART2

config BFIN_UART2_CTSRTS
	bool "Enable UART2 hardware flow control"
	depends on SERIAL_BFIN_UART2
	help
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
	  signal.

config UART2_CTS_PIN
	int "UART2 CTS pin"
	depends on BFIN_UART2_CTSRTS
	default -1
	help
	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config UART2_RTS_PIN
	int "UART2 RTS pin"
	depends on BFIN_UART2_CTSRTS
	default -1
	help
	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config SERIAL_BFIN_UART3
	bool "Enable UART3"
	depends on SERIAL_BFIN && (BF54x)
	help
	  Enable UART3

config BFIN_UART3_CTSRTS
	bool "Enable UART3 hardware flow control"
	depends on SERIAL_BFIN_UART3
	help
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
	  signal.

config SERIAL_IMX
	bool "IMX serial port support"
	depends on ARM && ARCH_IMX
+74 −3
Original line number Diff line number Diff line
@@ -86,8 +86,21 @@ static void bfin_serial_stop_tx(struct uart_port *port)
{
	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;

#ifdef CONFIG_BF54x
	while (!(UART_GET_LSR(uart) & TEMT))
		continue;
#endif

#ifdef CONFIG_SERIAL_BFIN_DMA
	disable_dma(uart->tx_dma_channel);
#else
#ifdef CONFIG_BF54x
	/* Waiting for Transmission Finished */
	while (!(UART_GET_LSR(uart) & TFI))
		continue;
	/* Clear TFI bit */
	UART_PUT_LSR(uart, TFI);
	UART_CLEAR_IER(uart, ETBEI);
#else
	unsigned short ier;

@@ -95,6 +108,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
	ier &= ~ETBEI;
	UART_PUT_IER(uart, ier);
#endif
#endif
}

/*
@@ -106,6 +120,9 @@ static void bfin_serial_start_tx(struct uart_port *port)

#ifdef CONFIG_SERIAL_BFIN_DMA
	bfin_serial_dma_tx_chars(uart);
#else
#ifdef CONFIG_BF54x
	UART_SET_IER(uart, ETBEI);
#else
	unsigned short ier;
	ier = UART_GET_IER(uart);
@@ -113,6 +130,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
	UART_PUT_IER(uart, ier);
	bfin_serial_tx_chars(uart);
#endif
#endif
}

/*
@@ -121,6 +139,9 @@ static void bfin_serial_start_tx(struct uart_port *port)
static void bfin_serial_stop_rx(struct uart_port *port)
{
	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
#ifdef CONFIG_BF54x
	UART_CLEAR_IER(uart, ERBFI);
#else
	unsigned short ier;

	ier = UART_GET_IER(uart);
@@ -129,6 +150,7 @@ static void bfin_serial_stop_rx(struct uart_port *port)
#endif
	ier &= ~ERBFI;
	UART_PUT_IER(uart, ier);
#endif
}

/*
@@ -325,10 +347,21 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
{
	struct bfin_serial_port *uart = dev_id;

#ifdef CONFIG_BF54x
	unsigned short status;
	spin_lock(&uart->port.lock);
	status = UART_GET_LSR(uart);
	while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) {
		bfin_serial_rx_chars(uart);
		status = UART_GET_LSR(uart);
	}
	spin_unlock(&uart->port.lock);
#else
	spin_lock(&uart->port.lock);
	while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY)
		bfin_serial_rx_chars(uart);
	spin_unlock(&uart->port.lock);
#endif
	return IRQ_HANDLED;
}

@@ -336,10 +369,21 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{
	struct bfin_serial_port *uart = dev_id;

#ifdef CONFIG_BF54x
	unsigned short status;
	spin_lock(&uart->port.lock);
	status = UART_GET_LSR(uart);
	while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) {
		bfin_serial_tx_chars(uart);
		status = UART_GET_LSR(uart);
	}
	spin_unlock(&uart->port.lock);
#else
	spin_lock(&uart->port.lock);
	while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY)
		bfin_serial_tx_chars(uart);
	spin_unlock(&uart->port.lock);
#endif
	return IRQ_HANDLED;
}

@@ -350,7 +394,6 @@ static void bfin_serial_do_work(struct work_struct *work)

	bfin_serial_mctrl_check(uart);
}

#endif

#ifdef CONFIG_SERIAL_BFIN_DMA
@@ -399,9 +442,13 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
	set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
	set_dma_x_modify(uart->tx_dma_channel, 1);
	enable_dma(uart->tx_dma_channel);
#ifdef CONFIG_BF54x
	UART_SET_IER(uart, ETBEI);
#else
	ier = UART_GET_IER(uart);
	ier |= ETBEI;
	UART_PUT_IER(uart, ier);
#endif
	spin_unlock_irqrestore(&uart->port.lock, flags);
}

@@ -481,9 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
	if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
		clear_dma_irqstat(uart->tx_dma_channel);
		disable_dma(uart->tx_dma_channel);
#ifdef CONFIG_BF54x
		UART_CLEAR_IER(uart, ETBEI);
#else
		ier = UART_GET_IER(uart);
		ier &= ~ETBEI;
		UART_PUT_IER(uart, ier);
#endif
		xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
		uart->port.icount.tx+=uart->tx_count;

@@ -665,7 +716,11 @@ static int bfin_serial_startup(struct uart_port *port)
		return -EBUSY;
	}
#endif
#ifdef CONFIG_BF54x
	UART_SET_IER(uart, ERBFI);
#else
	UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
#endif
	return 0;
}

@@ -756,29 +811,41 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,

	/* Disable UART */
	ier = UART_GET_IER(uart);
#ifdef CONFIG_BF54x
	UART_CLEAR_IER(uart, 0xF);
#else
	UART_PUT_IER(uart, 0);
#endif

#ifndef CONFIG_BF54x
	/* Set DLAB in LCR to Access DLL and DLH */
	val = UART_GET_LCR(uart);
	val |= DLAB;
	UART_PUT_LCR(uart, val);
	SSYNC();
#endif

	UART_PUT_DLL(uart, quot & 0xFF);
	SSYNC();
	UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
	SSYNC();

#ifndef CONFIG_BF54x
	/* Clear DLAB in LCR to Access THR RBR IER */
	val = UART_GET_LCR(uart);
	val &= ~DLAB;
	UART_PUT_LCR(uart, val);
	SSYNC();
#endif

	UART_PUT_LCR(uart, lcr);

	/* Enable UART */
#ifdef CONFIG_BF54x
	UART_SET_IER(uart, ier);
#else
	UART_PUT_IER(uart, ier);
#endif

	val = UART_GET_GCTL(uart);
	val |= UCEN;
@@ -890,15 +957,15 @@ static void __init bfin_serial_init_ports(void)
			bfin_serial_resource[i].uart_rts_pin;
#endif
		bfin_serial_hw_init(&bfin_serial_ports[i]);

	}

}

#ifdef CONFIG_SERIAL_BFIN_CONSOLE
static void bfin_serial_console_putchar(struct uart_port *port, int ch)
{
	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
	while (!(UART_GET_LSR(uart)))
	while (!(UART_GET_LSR(uart) & THRE))
		barrier();
	UART_PUT_CHAR(uart, ch);
	SSYNC();
@@ -950,18 +1017,22 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
			case 2:	*bits = 7; break;
			case 3:	*bits = 8; break;
		}
#ifndef CONFIG_BF54x
		/* Set DLAB in LCR to Access DLL and DLH */
		val = UART_GET_LCR(uart);
		val |= DLAB;
		UART_PUT_LCR(uart, val);
#endif

		dll = UART_GET_DLL(uart);
		dlh = UART_GET_DLH(uart);

#ifndef CONFIG_BF54x
		/* Clear DLAB in LCR to Access THR RBR IER */
		val = UART_GET_LCR(uart);
		val &= ~DLAB;
		UART_PUT_LCR(uart, val);
#endif

		*baud = get_sclk() / (16*(dll | dlh << 8));
	}