2 * UART Driver AMBA -- based on the Linux driver in 2.6.14
5 #include <l4/arm_drivers_c/uart.h>
8 /* ------------------------------------------------------------- */
11 UART011_TXIM = (1 << 5),
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
18 UART01x_FR_BUSY = 0x008,
19 UART01x_FR_TXFF = 0x020,
21 UART01x_LCRH_PEN = 0x02, // parity enable
22 UART01x_LCRH_WLEN_8 = 0x60,
29 inline static l4_addr_t _UART01x_DR(l4_addr_t a)
32 inline static l4_addr_t _UART01x_FR(l4_addr_t a)
35 inline static l4_addr_t _UART011_IBRD(l4_addr_t a)
38 inline static l4_addr_t _UART011_FBRD(l4_addr_t a)
41 inline static l4_addr_t _UART011_LCRH(l4_addr_t a)
44 inline static l4_addr_t _UART011_CR(l4_addr_t a)
47 inline static l4_addr_t _UART011_IMSC(l4_addr_t a)
50 inline static l4_addr_t _UART011_ICR(l4_addr_t a)
56 unsigned UART01x_FR_get(void)
57 { return *((volatile unsigned *)(_UART01x_FR(address))); }
60 unsigned UART011_CR_get(void)
61 { return *((volatile unsigned *)(_UART011_CR(address))); }
64 unsigned UART011_IMSC_get(void)
65 { return *((volatile unsigned *)(_UART011_IMSC(address))); }
70 void UART01x_DR_set(unsigned v)
71 { *((volatile unsigned*)(_UART01x_DR(address))) = v; }
74 void UART011_IBRD_set(unsigned v)
75 { *((volatile unsigned *)(_UART011_IBRD(address))) = v;}
78 void UART011_FBRD_set(unsigned v)
79 { *((volatile unsigned *)(_UART011_FBRD(address))) = v;}
82 void UART011_LCRH_set(unsigned v)
83 { *((volatile unsigned *)(_UART011_LCRH(address))) = v;}
86 void UART011_CR_set(unsigned v)
87 { *((volatile unsigned *)(_UART011_CR(address))) = v;}
90 void UART011_IMSC_set(unsigned v)
91 { *((volatile unsigned *)(_UART011_IMSC(address))) = v; }
94 void UART011_ICR_set(unsigned v)
95 { *((volatile unsigned *)(_UART011_ICR(address))) = v; }
99 address = (unsigned)-1;
103 int uart_startup(l4_addr_t _address, unsigned irq)
105 unsigned cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
116 while (UART01x_FR_get() & UART01x_FR_BUSY)
117 asm volatile("" : : : "memory");
122 void uart_shutdown(void)
124 UART011_IMSC_set(0); // all interrupts off
125 UART011_ICR_set(0xffff);
127 UART011_CR_set(UART01x_CR_UARTEN | UART011_CR_TXE);
130 int uart_change_mode(TransferMode m, BaudRate baud)
132 /* Be lazy, only support one mode */
136 unsigned old_cr = UART011_CR_get();
139 UART011_FBRD_set(0x0);
140 UART011_IBRD_set(0x4);
142 UART011_LCRH_set(UART01x_LCRH_WLEN_8 | UART01x_LCRH_PEN);
143 UART011_CR_set(old_cr);
148 int uart_write( const char *s, unsigned count )
154 st = proc_cli_save();
155 old_im = UART011_IMSC_get();
156 UART011_IMSC_set(old_im | UART011_TXIM);
159 for(i =0; i<count; i++)
161 while (UART01x_FR_get() & UART01x_FR_TXFF)
163 UART01x_DR_set(s[i]);
166 while (UART01x_FR_get() & UART01x_FR_TXFF)
168 UART01x_DR_set('\r');
172 /* wait till everything is transmitted */
173 while (UART01x_FR_get() & UART01x_FR_BUSY)
176 UART011_IMSC_set(old_im & ~UART011_TXIM);
178 proc_sti_restore(st);
182 int uart_getchar(int blocking)
187 int uart_char_avail(void)
192 l4_addr_t uart_base(void)
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
198 int uart_get_mode(enum uart_mode_type type)