]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/arm_drivers/drv/src/integrator/uart.c
a160118620bd523a7962440531b2aa702a506f2e
[l4.git] / l4 / pkg / arm_drivers / drv / src / integrator / uart.c
1 /*
2  * UART Driver AMBA -- based on the Linux driver in 2.6.14
3  */
4
5 #include <l4/arm_drivers_c/uart.h>
6
7
8 /* ------------------------------------------------------------- */
9
10 enum {
11   UART011_TXIM = (1 << 5),
12
13   UART01x_CR_UARTEN = 1, // UART enable
14   UART011_CR_LBE    = 0x080, // loopback enable
15   UART011_CR_TXE    = 0x100, // transmit enable
16   UART011_CR_RXE    = 0x200, // receive enable
17
18   UART01x_FR_BUSY   = 0x008,
19   UART01x_FR_TXFF   = 0x020,
20
21   UART01x_LCRH_PEN    = 0x02, // parity enable
22   UART01x_LCRH_WLEN_8 = 0x60,
23 };
24
25 l4_addr_t address;
26 unsigned _irq;
27
28
29 inline static l4_addr_t _UART01x_DR(l4_addr_t a)
30 { return a + 0x00; }
31
32 inline static l4_addr_t _UART01x_FR(l4_addr_t a)
33 { return a + 0x18; }
34
35 inline static l4_addr_t _UART011_IBRD(l4_addr_t a)
36 { return a + 0x24; }
37
38 inline static l4_addr_t _UART011_FBRD(l4_addr_t a)
39 { return a + 0x28; }
40
41 inline static l4_addr_t _UART011_LCRH(l4_addr_t a)
42 { return a + 0x2c; }
43
44 inline static l4_addr_t _UART011_CR(l4_addr_t a)
45 { return a + 0x30; }
46
47 inline static l4_addr_t _UART011_IMSC(l4_addr_t a)
48 { return a + 0x38; }
49
50 inline static l4_addr_t _UART011_ICR(l4_addr_t a)
51 { return a + 0x44; }
52
53
54 // getters
55 static inline
56 unsigned UART01x_FR_get(void)
57 { return *((volatile unsigned *)(_UART01x_FR(address))); }
58
59 static inline
60 unsigned UART011_CR_get(void)
61 { return *((volatile unsigned *)(_UART011_CR(address))); }
62
63 static inline
64 unsigned UART011_IMSC_get(void)
65 { return *((volatile unsigned *)(_UART011_IMSC(address))); }
66
67
68 // setters
69 static inline
70 void UART01x_DR_set(unsigned v)
71 { *((volatile unsigned*)(_UART01x_DR(address))) = v; }
72
73 static inline
74 void UART011_IBRD_set(unsigned v)
75 { *((volatile unsigned *)(_UART011_IBRD(address))) = v;}
76
77 static inline
78 void UART011_FBRD_set(unsigned v)
79 { *((volatile unsigned *)(_UART011_FBRD(address))) = v;}
80
81 static inline
82 void UART011_LCRH_set(unsigned v)
83 { *((volatile unsigned *)(_UART011_LCRH(address))) = v;}
84
85 static inline
86 void UART011_CR_set(unsigned v)
87 { *((volatile unsigned *)(_UART011_CR(address))) = v;}
88
89 static inline
90 void UART011_IMSC_set(unsigned v)
91 { *((volatile unsigned *)(_UART011_IMSC(address))) = v; }
92
93 static inline
94 void UART011_ICR_set(unsigned v)
95 { *((volatile unsigned *)(_UART011_ICR(address))) = v; }
96
97 void uart_init(void)
98 {
99   address = (unsigned)-1;
100   _irq = (unsigned)-1;
101 }
102
103 int uart_startup(l4_addr_t _address, unsigned irq)
104 {
105   unsigned cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
106
107   address =_address;
108   _irq = irq;
109
110   UART011_CR_set(cr);
111   UART011_FBRD_set(0);
112   UART011_IBRD_set(1);
113   UART011_LCRH_set(0);
114   UART01x_DR_set(1);
115
116   while (UART01x_FR_get() & UART01x_FR_BUSY)
117     asm volatile("" : : : "memory");
118
119   return true;
120 }
121
122 void uart_shutdown(void)
123 {
124   UART011_IMSC_set(0); // all interrupts off
125   UART011_ICR_set(0xffff);
126
127   UART011_CR_set(UART01x_CR_UARTEN | UART011_CR_TXE);
128 }
129
130 int uart_change_mode(TransferMode m, BaudRate baud)
131 {
132   /* Be lazy, only support one mode */
133   if (baud != 115200)
134     return false;
135
136   unsigned old_cr = UART011_CR_get();
137   UART011_CR_set(0);
138
139   UART011_FBRD_set(0x0);
140   UART011_IBRD_set(0x4);
141
142   UART011_LCRH_set(UART01x_LCRH_WLEN_8 | UART01x_LCRH_PEN);
143   UART011_CR_set(old_cr);
144
145   return true;
146 }
147
148 int uart_write( const char *s, unsigned count )
149 {
150   unsigned old_im;
151   proc_status st;
152   unsigned i;
153
154   st = proc_cli_save();
155   old_im = UART011_IMSC_get();
156   UART011_IMSC_set(old_im | UART011_TXIM);
157
158   /* transmission */
159   for(i =0; i<count; i++)
160     {
161       while (UART01x_FR_get() & UART01x_FR_TXFF)
162         ;
163       UART01x_DR_set(s[i]);
164       if( s[i]=='\n' )
165         {
166           while (UART01x_FR_get() & UART01x_FR_TXFF)
167             ;
168           UART01x_DR_set('\r');
169         }
170     }
171
172   /* wait till everything is transmitted */
173   while (UART01x_FR_get() & UART01x_FR_BUSY)
174     ;
175
176   UART011_IMSC_set(old_im & ~UART011_TXIM);
177
178   proc_sti_restore(st);
179   return 1;
180 }
181
182 int uart_getchar(int blocking)
183 {
184   return 0;
185 }
186
187 int uart_char_avail(void)
188 {
189   return 0;
190 }
191
192 l4_addr_t uart_base(void)
193 {
194   return 0x16000000; // ttyAMA0 at MMIO 0x16000000 (irq = 1) is a AMBA/PL011
195   //return 0x17000000; // ttyAMA1 at MMIO 0x17000000 (irq = 2) is a AMBA/PL011
196 }
197
198 int uart_get_mode(enum uart_mode_type type)
199 {
200   return 0;
201 }