- Add initial support for TI OMAP3530 (last commit said OMAP3450, this was incorrect...
[reactos.git] / reactos / boot / freeldr / freeldr / arch / arm / omapuart.c
1 /*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/freeldr/arch/arm/omapuart.c
5 * PURPOSE: Implements code for TI OMAP3 boards using the 16550 UART
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <freeldr.h>
12
13 /* GLOBALS ********************************************************************/
14
15 //
16 // UART Registers
17 //
18 #define UART0_RHR (ArmBoardBlock->UartRegisterBase + 0x00)
19 #define UART0_THR UART0_RHR
20 #define UART0_IER (ArmBoardBlock->UartRegisterBase + 0x04)
21 #define UART0_FCR (ArmBoardBlock->UartRegisterBase + 0x08)
22 #define UART0_LCR (ArmBoardBlock->UartRegisterBase + 0x0C)
23 #define UART0_MCR (ArmBoardBlock->UartRegisterBase + 0x10)
24 #define UART0_LSR (ArmBoardBlock->UartRegisterBase + 0x14)
25 #define UART0_MDR1 (ArmBoardBlock->UartRegisterBase + 0x20)
26
27 //
28 // When we enable the divisor latch
29 //
30 #define UART0_DLL UART0_RHR
31 #define UART0_DLH UART0_IER
32
33 //
34 // FCR Values
35 //
36 #define FCR_FIFO_EN 0x01
37 #define FCR_RXSR 0x02
38 #define FCR_TXSR 0x04
39
40 //
41 // LCR Values
42 //
43 #define LCR_WLS_8 0x03
44 #define LCR_1_STB 0x00
45 #define LCR_DIVL_EN 0x80
46 #define LCR_NO_PAR 0x00
47
48 //
49 // LSR Values
50 //
51 #define LSR_DR 0x01
52 #define LSR_THRE 0x20
53
54 //
55 // MCR Values
56 //
57 #define MCR_DTR 0x01
58 #define MCR_RTS 0x02
59
60 //
61 // MDR1 Modes
62 //
63 #define MDR1_UART16X 1
64 #define MDR1_SIR 2
65 #define MDR1_UART16X_AUTO_BAUD 3
66 #define MDR1_UART13X 4
67 #define MDR1_MIR 5
68 #define MDR1_FIR 6
69 #define MDR1_CIR 7
70 #define MDR1_DISABLE 8
71
72 /* FUNCTIONS ******************************************************************/
73
74 VOID
75 ArmOmap3SerialInit(IN ULONG Baudrate)
76 {
77 ULONG BaudClock;
78
79 //
80 // Calculate baudrate clock divider to set the baud rate
81 //
82 BaudClock = (ArmBoardBlock->ClockRate / 16) / Baudrate;
83
84 //
85 // Disable serial port
86 //
87 WRITE_REGISTER_UCHAR(UART0_MDR1, MDR1_DISABLE);
88
89 //
90 // Disable interrupts
91 //
92 WRITE_REGISTER_UCHAR(UART0_IER, 0);
93
94 //
95 // Set the baud rate to 115200 bps
96 //
97 WRITE_REGISTER_UCHAR(UART0_LCR, LCR_DIVL_EN);
98 WRITE_REGISTER_UCHAR(UART0_DLL, BaudClock);
99 WRITE_REGISTER_UCHAR(UART0_DLH, (BaudClock >> 8) & 0xFF);
100
101 //
102 // Setup loopback
103 //
104 WRITE_REGISTER_UCHAR(UART0_MCR, MCR_DTR | MCR_RTS);
105
106 //
107 // Set 8 bits for data, 1 stop bit, no parity
108 //
109 WRITE_REGISTER_UCHAR(UART0_LCR, LCR_WLS_8 | LCR_1_STB | LCR_NO_PAR);
110
111 //
112 // Clear and enable FIFO
113 //
114 WRITE_REGISTER_UCHAR(UART0_FCR, FCR_FIFO_EN | FCR_RXSR | FCR_TXSR);
115
116 //
117 // Enable serial port
118 //
119 WRITE_REGISTER_UCHAR(UART0_MDR1, MDR1_UART16X);
120 }
121
122 VOID
123 ArmOmap3PutChar(IN INT Char)
124 {
125 //
126 // Properly support new-lines
127 //
128 if (Char == '\n') ArmOmap3PutChar('\r');
129
130 //
131 // Wait for ready
132 //
133 while ((READ_REGISTER_UCHAR(UART0_LSR) & LSR_THRE) == 0);
134
135 //
136 // Send the character
137 //
138 WRITE_REGISTER_UCHAR(UART0_THR, Char);
139 }
140
141 INT
142 ArmOmap3GetCh(VOID)
143 {
144 //
145 // Wait for ready
146 //
147 while ((READ_REGISTER_UCHAR(UART0_LSR) & LSR_DR) == 0);
148
149 //
150 // Read the character
151 //
152 return READ_REGISTER_UCHAR(UART0_RHR);
153 }
154
155 BOOLEAN
156 ArmOmap3KbHit(VOID)
157 {
158 //
159 // Return if something is ready
160 //
161 return ((READ_REGISTER_UCHAR(UART0_LSR) & LSR_DR) != 0);
162 }