Commit cb4595a2 authored by Qipan Li's avatar Qipan Li Committed by Greg Kroah-Hartman

serial: sirf: use uart_port's fifosize for fifo related operation

In SiRF platform, there are different fifo size of uart and usp,
with the fifosize configuration changes in different chips, we
can not use port line to decide how to check FIFO full,empty and
level.

There is a direct mapping between FIFO HW register layout with
fifo size, so move to use fifosize as the input to check fifo
status.
Signed-off-by: default avatarQipan Li <Qipan.Li@csr.com>
Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a6ffe896
...@@ -73,8 +73,7 @@ static inline unsigned int sirfsoc_uart_tx_empty(struct uart_port *port) ...@@ -73,8 +73,7 @@ static inline unsigned int sirfsoc_uart_tx_empty(struct uart_port *port)
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status;
reg = rd_regl(port, ureg->sirfsoc_tx_fifo_status); reg = rd_regl(port, ureg->sirfsoc_tx_fifo_status);
return (reg & ufifo_st->ff_empty(port)) ? TIOCSER_TEMT : 0;
return (reg & ufifo_st->ff_empty(port->line)) ? TIOCSER_TEMT : 0;
} }
static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port) static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port)
...@@ -247,8 +246,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port) ...@@ -247,8 +246,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port)
if (sirfport->tx_dma_chan) if (sirfport->tx_dma_chan)
sirfsoc_uart_tx_with_dma(sirfport); sirfsoc_uart_tx_with_dma(sirfport);
else { else {
sirfsoc_uart_pio_tx_chars(sirfport, sirfsoc_uart_pio_tx_chars(sirfport, port->fifosize);
SIRFSOC_UART_IO_TX_REASONABLE_CNT);
wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START);
if (!sirfport->is_atlas7) if (!sirfport->is_atlas7)
wr_regl(port, ureg->sirfsoc_int_en_reg, wr_regl(port, ureg->sirfsoc_int_en_reg,
...@@ -374,7 +372,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) ...@@ -374,7 +372,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count)
if (!tty) if (!tty)
return -ENODEV; return -ENODEV;
while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) & while (!(rd_regl(port, ureg->sirfsoc_rx_fifo_status) &
ufifo_st->ff_empty(port->line))) { ufifo_st->ff_empty(port))) {
ch = rd_regl(port, ureg->sirfsoc_rx_fifo_data) | ch = rd_regl(port, ureg->sirfsoc_rx_fifo_data) |
SIRFUART_DUMMY_READ; SIRFUART_DUMMY_READ;
if (unlikely(uart_handle_sysrq_char(port, ch))) if (unlikely(uart_handle_sysrq_char(port, ch)))
...@@ -401,7 +399,7 @@ sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count) ...@@ -401,7 +399,7 @@ sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count)
unsigned int num_tx = 0; unsigned int num_tx = 0;
while (!uart_circ_empty(xmit) && while (!uart_circ_empty(xmit) &&
!(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & !(rd_regl(port, ureg->sirfsoc_tx_fifo_status) &
ufifo_st->ff_full(port->line)) && ufifo_st->ff_full(port)) &&
count--) { count--) {
wr_regl(port, ureg->sirfsoc_tx_fifo_data, wr_regl(port, ureg->sirfsoc_tx_fifo_data,
xmit->buf[xmit->tail]); xmit->buf[xmit->tail]);
...@@ -626,8 +624,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) ...@@ -626,8 +624,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id)
sirfsoc_uart_handle_rx_done(sirfport); sirfsoc_uart_handle_rx_done(sirfport);
} else { } else {
if (intr_status & SIRFUART_RX_IO_INT_ST(uint_st)) if (intr_status & SIRFUART_RX_IO_INT_ST(uint_st))
sirfsoc_uart_pio_rx_chars(port, sirfsoc_uart_pio_rx_chars(port, port->fifosize);
SIRFSOC_UART_IO_RX_MAX_CNT);
} }
spin_unlock(&port->lock); spin_unlock(&port->lock);
tty_flip_buffer_push(&state->port); tty_flip_buffer_push(&state->port);
...@@ -641,10 +638,10 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) ...@@ -641,10 +638,10 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} else { } else {
sirfsoc_uart_pio_tx_chars(sirfport, sirfsoc_uart_pio_tx_chars(sirfport,
SIRFSOC_UART_IO_TX_REASONABLE_CNT); port->fifosize);
if ((uart_circ_empty(xmit)) && if ((uart_circ_empty(xmit)) &&
(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & (rd_regl(port, ureg->sirfsoc_tx_fifo_status) &
ufifo_st->ff_empty(port->line))) ufifo_st->ff_empty(port)))
sirfsoc_uart_stop_tx(port); sirfsoc_uart_stop_tx(port);
} }
} }
...@@ -746,7 +743,7 @@ sirfsoc_usp_calc_sample_div(unsigned long set_rate, ...@@ -746,7 +743,7 @@ sirfsoc_usp_calc_sample_div(unsigned long set_rate,
unsigned long ioclk_div = 0; unsigned long ioclk_div = 0;
unsigned long temp_delta; unsigned long temp_delta;
for (sample_div = SIRF_MIN_SAMPLE_DIV; for (sample_div = SIRF_USP_MIN_SAMPLE_DIV;
sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) {
temp_delta = ioclk_rate - temp_delta = ioclk_rate -
(ioclk_rate + (set_rate * sample_div) / 2) (ioclk_rate + (set_rate * sample_div) / 2)
...@@ -1012,7 +1009,6 @@ static int sirfsoc_uart_startup(struct uart_port *port) ...@@ -1012,7 +1009,6 @@ static int sirfsoc_uart_startup(struct uart_port *port)
index, port->irq); index, port->irq);
goto irq_err; goto irq_err;
} }
/* initial hardware settings */ /* initial hardware settings */
wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl,
rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl) | rd_regl(port, ureg->sirfsoc_tx_dma_io_ctrl) |
...@@ -1174,8 +1170,8 @@ static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) ...@@ -1174,8 +1170,8 @@ static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch)
struct sirfsoc_uart_port *sirfport = to_sirfport(port); struct sirfsoc_uart_port *sirfport = to_sirfport(port);
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status;
while (rd_regl(port, while (rd_regl(port, ureg->sirfsoc_tx_fifo_status) &
ureg->sirfsoc_tx_fifo_status) & ufifo_st->ff_full(port->line)) ufifo_st->ff_full(port))
cpu_relax(); cpu_relax();
wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch); wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Licensed under GPLv2 or later. * Licensed under GPLv2 or later.
*/ */
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/log2.h>
struct sirfsoc_uart_param { struct sirfsoc_uart_param {
const char *uart_name; const char *uart_name;
const char *port_name; const char *port_name;
...@@ -43,8 +44,8 @@ struct sirfsoc_register { ...@@ -43,8 +44,8 @@ struct sirfsoc_register {
u32 sirfsoc_async_param_reg; u32 sirfsoc_async_param_reg;
}; };
typedef u32 (*fifo_full_mask)(int line); typedef u32 (*fifo_full_mask)(struct uart_port *port);
typedef u32 (*fifo_empty_mask)(int line); typedef u32 (*fifo_empty_mask)(struct uart_port *port);
struct sirfsoc_fifo_status { struct sirfsoc_fifo_status {
fifo_full_mask ff_full; fifo_full_mask ff_full;
...@@ -103,21 +104,20 @@ struct sirfsoc_uart_register { ...@@ -103,21 +104,20 @@ struct sirfsoc_uart_register {
enum sirfsoc_uart_type uart_type; enum sirfsoc_uart_type uart_type;
}; };
u32 usp_ff_full(int line) u32 uart_usp_ff_full_mask(struct uart_port *port)
{ {
return 0x80; u32 full_bit;
}
u32 usp_ff_empty(int line) full_bit = ilog2(port->fifosize);
{ return (1 << full_bit);
return 0x100;
}
u32 uart_ff_full(int line)
{
return (line == 1) ? (0x20) : (0x80);
} }
u32 uart_ff_empty(int line)
u32 uart_usp_ff_empty_mask(struct uart_port *port)
{ {
return (line == 1) ? (0x40) : (0x100); u32 empty_bit;
empty_bit = ilog2(port->fifosize);
return (1 << empty_bit);
} }
struct sirfsoc_uart_register sirfsoc_usp = { struct sirfsoc_uart_register sirfsoc_usp = {
.uart_reg = { .uart_reg = {
...@@ -175,8 +175,8 @@ struct sirfsoc_uart_register sirfsoc_usp = { ...@@ -175,8 +175,8 @@ struct sirfsoc_uart_register sirfsoc_usp = {
.sirfsoc_rxd_brk = BIT(15), .sirfsoc_rxd_brk = BIT(15),
}, },
.fifo_status = { .fifo_status = {
.ff_full = usp_ff_full, .ff_full = uart_usp_ff_full_mask,
.ff_empty = usp_ff_empty, .ff_empty = uart_usp_ff_empty_mask,
}, },
.uart_param = { .uart_param = {
.uart_name = "ttySiRF", .uart_name = "ttySiRF",
...@@ -245,8 +245,8 @@ struct sirfsoc_uart_register sirfsoc_uart = { ...@@ -245,8 +245,8 @@ struct sirfsoc_uart_register sirfsoc_uart = {
.sirfsoc_rts = BIT(15), .sirfsoc_rts = BIT(15),
}, },
.fifo_status = { .fifo_status = {
.ff_full = uart_ff_full, .ff_full = uart_usp_ff_full_mask,
.ff_empty = uart_ff_empty, .ff_empty = uart_usp_ff_empty_mask,
}, },
.uart_param = { .uart_param = {
.uart_name = "ttySiRF", .uart_name = "ttySiRF",
...@@ -294,6 +294,7 @@ struct sirfsoc_uart_register sirfsoc_uart = { ...@@ -294,6 +294,7 @@ struct sirfsoc_uart_register sirfsoc_uart = {
/* Macro Specific*/ /* Macro Specific*/
#define SIRFUART_INT_EN_CLR 0x0060 #define SIRFUART_INT_EN_CLR 0x0060
/* Baud Rate Calculation */ /* Baud Rate Calculation */
#define SIRF_USP_MIN_SAMPLE_DIV 0x1
#define SIRF_MIN_SAMPLE_DIV 0xf #define SIRF_MIN_SAMPLE_DIV 0xf
#define SIRF_MAX_SAMPLE_DIV 0x3f #define SIRF_MAX_SAMPLE_DIV 0x3f
#define SIRF_IOCLK_DIV_MAX 0xffff #define SIRF_IOCLK_DIV_MAX 0xffff
...@@ -328,7 +329,7 @@ struct sirfsoc_uart_register sirfsoc_uart = { ...@@ -328,7 +329,7 @@ struct sirfsoc_uart_register sirfsoc_uart = {
#define SIRFUART_RECV_TIMEOUT(port, x) \ #define SIRFUART_RECV_TIMEOUT(port, x) \
(((port)->line > 2) ? (x & 0xFFFF) : ((x) & 0xFFFF) << 16) (((port)->line > 2) ? (x & 0xFFFF) : ((x) & 0xFFFF) << 16)
#define SIRFUART_FIFO_THD(port) ((port->line) == 1 ? 16 : 64) #define SIRFUART_FIFO_THD(port) (port->fifosize >> 1)
#define SIRFUART_ERR_INT_STAT(port, unit_st) \ #define SIRFUART_ERR_INT_STAT(port, unit_st) \
(uint_st->sirfsoc_rx_oflow | \ (uint_st->sirfsoc_rx_oflow | \
uint_st->sirfsoc_frm_err | \ uint_st->sirfsoc_frm_err | \
...@@ -365,10 +366,6 @@ struct sirfsoc_uart_register sirfsoc_uart = { ...@@ -365,10 +366,6 @@ struct sirfsoc_uart_register sirfsoc_uart = {
/* Uart Common Use Macro*/ /* Uart Common Use Macro*/
#define SIRFSOC_RX_DMA_BUF_SIZE 256 #define SIRFSOC_RX_DMA_BUF_SIZE 256
#define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) #define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3)
#define LOOP_DMA_BUFA_FILL 1
#define LOOP_DMA_BUFB_FILL 2
#define TX_TRAN_PIO 1
#define TX_TRAN_DMA 2
/* Uart Fifo Level Chk */ /* Uart Fifo Level Chk */
#define SIRFUART_TX_FIFO_SC_OFFSET 0 #define SIRFUART_TX_FIFO_SC_OFFSET 0
#define SIRFUART_TX_FIFO_LC_OFFSET 10 #define SIRFUART_TX_FIFO_LC_OFFSET 10
...@@ -437,10 +434,6 @@ struct sirfsoc_uart_port { ...@@ -437,10 +434,6 @@ struct sirfsoc_uart_port {
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
/* UART Port Mask */ /* UART Port Mask */
#define SIRFUART_FIFOLEVEL_MASK(port) ((port->line == 1) ? (0x1f) : (0x7f)) #define SIRFUART_FIFOLEVEL_MASK(port) ((port->fifosize - 1) & 0xFFF)
#define SIRFUART_FIFOFULL_MASK(port) ((port->line == 1) ? (0x20) : (0x80)) #define SIRFUART_FIFOFULL_MASK(port) (port->fifosize & 0xFFF)
#define SIRFUART_FIFOEMPTY_MASK(port) ((port->line == 1) ? (0x40) : (0x100)) #define SIRFUART_FIFOEMPTY_MASK(port) ((port->fifosize & 0xFFF) << 1)
/* I/O Mode */
#define SIRFSOC_UART_IO_RX_MAX_CNT 256
#define SIRFSOC_UART_IO_TX_REASONABLE_CNT 256
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment