1 #include "uart_s3c2410.h"
2 #include "poll_timeout_counter.h"
8 Type_24xx, Type_64xx, Type_s5pv210,
13 ULCON = 0x0, // line control register
14 UCON = 0x4, // control register
15 UFCON = 0x8, // FIFO control register
16 UMCON = 0xc, // modem control register
17 UTRSTAT = 0x10, // Tx/Rx status register
18 UERSTAT = 0x14, // Rx error status register
19 UFSTAT = 0x18, // FIFO status register
20 UMSTAT = 0x1c, // modem status register
21 UTXH = 0x20, // transmit buffer register (little endian, 0x23 for BE)
22 URXH = 0x24, // receive buffer register (little endian, 0x27 for BE)
23 UBRDIV = 0x28, // baud rate divisor register
26 UINTP = 0x30, // interrupt pending register
27 UINTSP = 0x34, // interrupt source pending register
28 UINTM = 0x38, // interrupt mask register
33 UCON_MODE_RECEIVE_IRQ_POLL = 1 << 0,
34 UCON_MODE_TRANSMIT_IRQ_POLL = 1 << 2,
35 UCON_SEND_BREAK_SIGNAL = 1 << 4,
36 UCON_LOOPBACK_MODE = 1 << 5,
37 UCON_RX_ERROR_STATUS_IRQ_EN = 1 << 6,
38 UCON_RX_TIME_OUT_EN = 1 << 7,
39 UCON_MODE = UCON_MODE_RECEIVE_IRQ_POLL
40 | UCON_MODE_TRANSMIT_IRQ_POLL
41 | UCON_RX_TIME_OUT_EN,
43 UFCON_ENABLE = 1 << 0, // enable fifo
44 UFCON_RX_FIFO_RESET = 1 << 1, // Rx Fifo reset
45 UFCON_TX_FIFO_RESET = 1 << 2, // Tx Fifo reset
49 UTRSTAT_Rx_RDY = 1 << 0,
50 UTRSTAT_Tx_RDY = 1 << 1,
58 UFSTAT_2410_Rx_COUNT_MASK = 0x00f,
59 UFSTAT_2410_Tx_COUNT_MASK = 0x0f0,
60 UFSTAT_2410_RxFULL = 0x100,
61 UFSTAT_2410_TxFULL = 0x200,
64 UFSTAT_64XX_Rx_COUNT_MASK = 0x003f,
65 UFSTAT_64XX_Tx_COUNT_MASK = 0x3f00,
66 UFSTAT_64XX_RxFULL = 0x0040,
67 UFSTAT_64XX_TxFULL = 0x4000,
70 UFSTAT_S5PV210_Rx_COUNT_MASK = 0x000000ff,
71 UFSTAT_S5PV210_Tx_COUNT_MASK = 0x00ff0000,
72 UFSTAT_S5PV210_RxFULL = 0x00000100,
73 UFSTAT_S5PV210_TxFULL = 0x01000000,
77 void Uart_s3c::fifo_reset()
79 _regs->write<unsigned int>(UFCON, UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET);
80 Poll_timeout_counter i(3000000);
81 while (i.test(_regs->read<unsigned int>(UFCON) & (UFCON_RX_FIFO_RESET | UFCON_TX_FIFO_RESET)))
86 bool Uart_s3c::startup(Io_register_block const *regs)
92 _regs->write<unsigned int>(UMCON, 0);
95 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
96 _regs->write<unsigned int>(UCON, UCON_MODE);
97 _regs->write<unsigned int>(UFCON, UFCON_ENABLE);
105 _regs->write<unsigned int>(UINTM, ~UINT_RXD); // mask all but receive irq
106 _regs->write<unsigned int>(UINTP, ~0); // clear all pending irqs
110 _regs->write<unsigned int>(UBRDIV, 0x23);
116 void Uart_s3c::shutdown()
121 bool Uart_s3c::change_mode(Transfer_mode, Baud_rate r)
127 _regs->write<unsigned int>(ULCON, ULCON_8N1_MODE);
128 _regs->write<unsigned int>(UCON, UCON_MODE);
129 _regs->write<unsigned int>(UFCON, 1);
131 _regs->write<unsigned int>(UBRDIV, 0x23);
137 int Uart_s3c::get_char(bool blocking) const
139 while (!char_avail())
143 _regs->read<unsigned int>(UFCON);
144 int c = _regs->read<unsigned int>(URXH) & 0xff;
149 int Uart_s3c::char_avail() const
151 return is_rx_fifo_non_empty();
154 void Uart_s3c::out_char(char c) const
156 wait_for_non_full_tx_fifo();
157 _regs->write<unsigned int>(UTXH, c);
160 int Uart_s3c::write(char const *s, unsigned long count) const
162 unsigned long c = count;
165 wait_for_empty_tx_fifo();
170 // -----------------------
172 void Uart_s3c2410::wait_for_empty_tx_fifo() const
174 Poll_timeout_counter i(3000000);
175 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Tx_COUNT_MASK | UFSTAT_2410_TxFULL)))
179 void Uart_s3c2410::wait_for_non_full_tx_fifo() const
181 Poll_timeout_counter i(3000000);
182 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_2410_TxFULL))
186 unsigned Uart_s3c2410::is_rx_fifo_non_empty() const
188 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_2410_Rx_COUNT_MASK | UFSTAT_2410_RxFULL);
191 void Uart_s3c2410::auto_flow_control(bool on)
193 _regs->write<unsigned int>(UMCON, (_regs->read<unsigned int>(UMCON) & ~UMCON_AFC) | (on ? UMCON_AFC : 0));
196 // -----------------------
198 void Uart_s3c64xx::wait_for_empty_tx_fifo() const
200 Poll_timeout_counter i(3000000);
201 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Tx_COUNT_MASK | UFSTAT_64XX_TxFULL)))
205 void Uart_s3c64xx::wait_for_non_full_tx_fifo() const
207 Poll_timeout_counter i(3000000);
208 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_64XX_TxFULL))
212 unsigned Uart_s3c64xx::is_rx_fifo_non_empty() const
214 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_64XX_Rx_COUNT_MASK | UFSTAT_64XX_RxFULL);
217 void Uart_s3c64xx::ack_rx_irq() const
219 _regs->write<unsigned int>(UINTP, UINT_RXD);
222 // -----------------------
224 void Uart_s5pv210::wait_for_empty_tx_fifo() const
226 Poll_timeout_counter i(3000000);
227 while (i.test(_regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Tx_COUNT_MASK | UFSTAT_S5PV210_TxFULL)))
231 void Uart_s5pv210::wait_for_non_full_tx_fifo() const
233 Poll_timeout_counter i(3000000);
234 while (i.test(_regs->read<unsigned int>(UFSTAT) & UFSTAT_S5PV210_TxFULL))
238 unsigned Uart_s5pv210::is_rx_fifo_non_empty() const
240 return _regs->read<unsigned int>(UFSTAT) & (UFSTAT_S5PV210_Rx_COUNT_MASK | UFSTAT_S5PV210_RxFULL);
243 void Uart_s5pv210::ack_rx_irq() const
245 _regs->write<unsigned int>(UINTP, UINT_RXD);
248 void Uart_s5pv210::save(Save_block *b) const
250 b->ubrdiv = _regs->read<unsigned>(UBRDIV);
251 b->uintm = _regs->read<unsigned>(UINTM);
252 b->ufracval = _regs->read<unsigned>(UFRACVAL);
253 b->umcon = _regs->read<unsigned>(UMCON);
254 b->ufcon = _regs->read<unsigned>(UFCON);
255 b->ucon = _regs->read<unsigned>(UCON);
256 b->ulcon = _regs->read<unsigned>(ULCON);
259 void Uart_s5pv210::restore(Save_block const *b) const
261 _regs->write<unsigned>(UINTM, b->uintm);
262 _regs->write<unsigned>(ULCON, b->ulcon);
263 _regs->write<unsigned>(UCON, b->ucon);
264 _regs->write<unsigned>(UFCON, b->ufcon);
265 _regs->write<unsigned>(UMCON, b->umcon);
266 _regs->write<unsigned>(UBRDIV, b->ubrdiv);
267 _regs->write<unsigned>(UFRACVAL, b->ufracval);