OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [drivers/] [uart/] [omap/] [uart.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * UART driver used by OMAP devices
3
 *
4
 * Copyright (C) 2007 Bahadir Balban
5
 */
6
 
7
#include <l4/drivers/uart/omap/uart.h>
8
#include INC_ARCH(io.h)
9
 
10
#define OMAP_UART_FIFO_ENABLE   (1 << 0)
11
#define OMAP_UART_RX_FIFO_CLR   (1 << 1)
12
#define OMAP_UART_TX_FIFO_CLR   (1 << 2)
13
static inline void uart_enable_fifo(unsigned long uart_base)
14
{
15
        volatile u32 reg = read(uart_base + OMAP_UART_FCR);
16
        reg |= (OMAP_UART_FIFO_ENABLE | OMAP_UART_RX_FIFO_CLR |
17
                OMAP_UART_TX_FIFO_CLR);
18
        write(reg, uart_base + OMAP_UART_FCR);
19
}
20
 
21
static inline void uart_disable_fifo(unsigned long uart_base)
22
{
23
        volatile u32 reg = read(uart_base + OMAP_UART_FCR);
24
        reg &= (~OMAP_UART_FIFO_ENABLE | OMAP_UART_RX_FIFO_CLR |
25
                OMAP_UART_TX_FIFO_CLR);
26
        write(reg, uart_base + OMAP_UART_FCR);
27
}
28
 
29
#define OMAP_UART_TX_ENABLE     (1 << 0)
30
static inline void uart_enable_tx(unsigned long uart_base)
31
{
32
        volatile u32 reg = read(uart_base + OMAP_UART_MCR);
33
        reg |= OMAP_UART_TX_ENABLE;
34
        write(reg, uart_base + OMAP_UART_MCR);
35
}
36
 
37
static inline void uart_disable_tx(unsigned long uart_base)
38
{
39
        volatile u32 reg = read(uart_base + OMAP_UART_MCR);
40
        reg &= ~OMAP_UART_TX_ENABLE;
41
        write(reg, uart_base + OMAP_UART_MCR);
42
 
43
}
44
 
45
#define OMAP_UART_RX_ENABLE     (1 << 1)
46
static inline void uart_enable_rx(unsigned long uart_base)
47
{
48
        volatile u32 reg = read(uart_base + OMAP_UART_MCR);
49
        reg |= OMAP_UART_RX_ENABLE;
50
        write(reg, uart_base + OMAP_UART_MCR);
51
}
52
 
53
static inline void uart_disable_rx(unsigned long uart_base)
54
{
55
        volatile u32 reg = read(uart_base + OMAP_UART_MCR);
56
        reg &= ~OMAP_UART_RX_ENABLE;
57
        write(reg, uart_base + OMAP_UART_MCR);
58
}
59
 
60
#define OMAP_UART_STOP_BITS_MASK        (1 << 2)
61
static inline void uart_set_stop_bits(unsigned long uart_base, int bits)
62
{
63
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
64
        reg &= ~OMAP_UART_STOP_BITS_MASK;
65
        reg |= (bits << 2);
66
        write(reg, uart_base + OMAP_UART_LCR);
67
}
68
 
69
#define OMAP_UART_DATA_BITS_MASK        (0x3)
70
static inline void uart_set_data_bits(unsigned long uart_base, int bits)
71
{
72
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
73
        reg &= ~OMAP_UART_DATA_BITS_MASK;
74
        reg |= bits;
75
        write(reg, uart_base + OMAP_UART_LCR);
76
}
77
 
78
#define OMAP_UART_PARITY_ENABLE         (1 << 3)
79
static inline void uart_enable_parity(unsigned long uart_base)
80
{
81
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
82
        reg |= OMAP_UART_PARITY_ENABLE;
83
        write(reg, uart_base + OMAP_UART_LCR);
84
}
85
 
86
static inline void uart_disable_parity(unsigned long uart_base)
87
{
88
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
89
        reg &= ~OMAP_UART_PARITY_ENABLE;
90
        write(reg, uart_base + OMAP_UART_LCR);
91
}
92
 
93
#define OMAP_UART_PARITY_EVEN           (1 << 4)
94
static inline void uart_set_even_parity(unsigned long uart_base)
95
{
96
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
97
        reg |= OMAP_UART_PARITY_EVEN;
98
        write(reg, uart_base + OMAP_UART_LCR);
99
}
100
 
101
static inline void uart_set_odd_parity(unsigned long uart_base)
102
{
103
        volatile u32 reg = read(uart_base + OMAP_UART_LCR);
104
        reg &= ~OMAP_UART_PARITY_EVEN;
105
        write(reg, uart_base + OMAP_UART_LCR);
106
}
107
 
108
static inline void uart_select_mode(unsigned long uart_base, int mode)
109
{
110
        write(mode, uart_base + OMAP_UART_MDR1);
111
}
112
 
113
#define OMAP_UART_INTR_EN       1
114
static inline void uart_enable_interrupt(unsigned long uart_base)
115
{
116
        write(OMAP_UART_INTR_EN, uart_base + OMAP_UART_IER);
117
}
118
 
119
static inline void uart_disable_interrupt(unsigned long uart_base)
120
{
121
        write((~OMAP_UART_INTR_EN), uart_base + OMAP_UART_IER);
122
}
123
 
124
static inline void uart_set_link_control(unsigned long uart_base, int mode)
125
{
126
        write(mode, uart_base + OMAP_UART_LCR);
127
}
128
 
129
#define OMAP_UART_TXFE          0x20
130
void uart_tx_char(unsigned long uart_base, char c)
131
{
132
        volatile u32 reg;
133
 
134
        /* Check if there is space for tx */
135
        do {
136
                reg = read(uart_base + OMAP_UART_LSR);
137
        } while(!(reg & OMAP_UART_TXFE));
138
 
139
        write(c, uart_base + OMAP_UART_THR);
140
}
141
 
142
#define OMAP_UART_RXFNE                 0x1
143
#define OMAP_UART_RX_FIFO_STATUS        0x8
144
char uart_rx_char(unsigned long uart_base)
145
{
146
        volatile u32 reg;
147
 
148
        /* Check if pending data is there */
149
        do {
150
                reg = read(uart_base + OMAP_UART_LSR);
151
        } while(!(reg & OMAP_UART_RXFNE));
152
 
153
#if 0
154
        /* Check if there is some error in recieve */
155
        if(reg & OMAP_UART_RX_FIFO_STATUS)
156
                return -1;
157
#endif
158
 
159
        return (char)read(uart_base + OMAP_UART_RHR);
160
}
161
 
162
void uart_set_baudrate(unsigned long uart_base, u32 baudrate, u32 clkrate)
163
{
164
        u32 clk_div = 0;
165
 
166
        /* 48Mhz clock fixed on beagleboard */
167
        const u32 uartclk = 48000000;
168
 
169
        if(clkrate == 0)
170
                clkrate = uartclk;
171
 
172
        /* If baud out of range, set default rate */
173
        if(baudrate > 3686400 || baudrate < 300)
174
                baudrate = 115200;
175
 
176
        clk_div = clkrate/(16 * baudrate);
177
 
178
        /* Set clockrate in DLH and DLL */
179
        write((clk_div & 0xff), uart_base + OMAP_UART_DLL);
180
        write(((clk_div >> 8) & 0xff ), uart_base + OMAP_UART_DLH);
181
}
182
 
183
void uart_init(unsigned long uart_base)
184
{
185
        /* Disable UART */
186
        uart_select_mode(uart_base, OMAP_UART_MODE_DEFAULT);
187
 
188
        /* Disable interrupts */
189
        uart_disable_interrupt(uart_base);
190
 
191
        /* Change to config mode, to set baud divisor */
192
        uart_set_link_control(uart_base, OMAP_UART_BANKED_MODE_CONFIG_A);
193
 
194
        /* Set the baud rate */
195
        uart_set_baudrate(uart_base, 115200, 48000000);
196
 
197
        /* Switch to operational mode */
198
        uart_set_link_control(uart_base, OMAP_UART_BANKED_MODE_OPERATIONAL);
199
 
200
        /* Set up the link- parity, data bits stop bits to 8N1 */
201
        uart_disable_parity(uart_base);
202
        uart_set_data_bits(uart_base, OMAP_UART_DATA_BITS_8);
203
        uart_set_stop_bits(uart_base, OMAP_UART_STOP_BITS_1);
204
 
205
        /* Disable Fifos */
206
        uart_disable_fifo(uart_base);
207
 
208
        /* Enable modem Rx/Tx */
209
        uart_enable_tx(uart_base);
210
        uart_enable_rx(uart_base);
211
 
212
        /* Enable UART in 16x mode */
213
        uart_select_mode(uart_base, OMAP_UART_MODE_UART16X);
214
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.