blob: f08b5b0cba4a57afbce2a7d3647d79d43971e419 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#ifndef __CADENCE_UART_H__
#define __CADENCE_UART_H__
#define CADENCE_UART_CONTROL 0x00
#define CADENCE_UART_MODE 0x04
#define CADENCE_UART_BAUD_GEN 0x18
#define CADENCE_UART_CHANNEL_STS 0x2C
#define CADENCE_UART_RXTXFIFO 0x30
#define CADENCE_UART_BAUD_DIV 0x34
#define CADENCE_CTRL_RXRES (1 << 0)
#define CADENCE_CTRL_TXRES (1 << 1)
#define CADENCE_CTRL_RXEN (1 << 2)
#define CADENCE_CTRL_RXDIS (1 << 3)
#define CADENCE_CTRL_TXEN (1 << 4)
#define CADENCE_CTRL_TXDIS (1 << 5)
#define CADENCE_CTRL_RSTTO (1 << 6)
#define CADENCE_CTRL_STTBRK (1 << 7)
#define CADENCE_CTRL_STPBRK (1 << 8)
#define CADENCE_MODE_CLK_REF (0 << 0)
#define CADENCE_MODE_CLK_REF_DIV (1 << 0)
#define CADENCE_MODE_CHRL_6 (3 << 1)
#define CADENCE_MODE_CHRL_7 (2 << 1)
#define CADENCE_MODE_CHRL_8 (0 << 1)
#define CADENCE_MODE_PAR_EVEN (0 << 3)
#define CADENCE_MODE_PAR_ODD (1 << 3)
#define CADENCE_MODE_PAR_SPACE (2 << 3)
#define CADENCE_MODE_PAR_MARK (3 << 3)
#define CADENCE_MODE_PAR_NONE (4 << 3)
#define CADENCE_STS_REMPTY (1 << 1)
#define CADENCE_STS_RFUL (1 << 2)
#define CADENCE_STS_TEMPTY (1 << 3)
#define CADENCE_STS_TFUL (1 << 4)
static inline void cadence_uart_init(void __iomem *uartbase)
{
int baudrate = CONFIG_BAUDRATE;
unsigned int clk = 49999995;
unsigned int gen, div;
/* disable transmitter and receiver */
writel(0, uartbase + CADENCE_UART_CONTROL);
/* calculate and set baud clock generator parameters */
for (div = 4; div < 256; div++) {
int calc_rate, error;
gen = clk / (baudrate * (div + 1));
if (gen < 1 || gen > 65535)
continue;
calc_rate = clk / (gen * (div + 1));
error = baudrate - calc_rate;
if (error < 0)
error *= -1;
if (((error * 100) / baudrate) < 3)
break;
}
writel(gen, uartbase + CADENCE_UART_BAUD_GEN);
writel(div, uartbase + CADENCE_UART_BAUD_DIV);
/* soft-reset tx/rx paths */
writel(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES,
uartbase + CADENCE_UART_CONTROL);
while (readl(uartbase + CADENCE_UART_CONTROL) &
(CADENCE_CTRL_RXRES | CADENCE_CTRL_TXRES))
;
/* enable UART */
writel(CADENCE_MODE_CLK_REF | CADENCE_MODE_CHRL_8 |
CADENCE_MODE_PAR_NONE, uartbase + CADENCE_UART_MODE);
writel(CADENCE_CTRL_RXEN | CADENCE_CTRL_TXEN,
uartbase + CADENCE_UART_CONTROL);
}
static inline void cadence_uart_putc(void *base, int c)
{
if (!(readl(base + CADENCE_UART_CONTROL) & CADENCE_CTRL_TXEN))
return;
while ((readl(base + CADENCE_UART_CHANNEL_STS) & CADENCE_STS_TFUL))
;
writel(c, base + CADENCE_UART_RXTXFIFO);
}
#endif /* __CADENCE_UART_H__ */
|