1c5dff60aSchristos /* Blackfin Universal Asynchronous Receiver/Transmitter (UART) model.
2c5dff60aSchristos For "old style" UARTs on BF53x/etc... parts.
3c5dff60aSchristos
4*1424dfb3Schristos Copyright (C) 2010-2020 Free Software Foundation, Inc.
5c5dff60aSchristos Contributed by Analog Devices, Inc.
6c5dff60aSchristos
7c5dff60aSchristos This file is part of simulators.
8c5dff60aSchristos
9c5dff60aSchristos This program is free software; you can redistribute it and/or modify
10c5dff60aSchristos it under the terms of the GNU General Public License as published by
11c5dff60aSchristos the Free Software Foundation; either version 3 of the License, or
12c5dff60aSchristos (at your option) any later version.
13c5dff60aSchristos
14c5dff60aSchristos This program is distributed in the hope that it will be useful,
15c5dff60aSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
16c5dff60aSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17c5dff60aSchristos GNU General Public License for more details.
18c5dff60aSchristos
19c5dff60aSchristos You should have received a copy of the GNU General Public License
20c5dff60aSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */
21c5dff60aSchristos
22c5dff60aSchristos #include "config.h"
23c5dff60aSchristos
24c5dff60aSchristos #include "sim-main.h"
25c5dff60aSchristos #include "dv-sockser.h"
26c5dff60aSchristos #include "devices.h"
27c5dff60aSchristos #include "dv-bfin_uart.h"
28c5dff60aSchristos
29c5dff60aSchristos /* XXX: Should we bother emulating the TX/RX FIFOs ? */
30c5dff60aSchristos
31c5dff60aSchristos /* Internal state needs to be the same as bfin_uart2. */
32c5dff60aSchristos struct bfin_uart
33c5dff60aSchristos {
34c5dff60aSchristos /* This top portion matches common dv_bfin struct. */
35c5dff60aSchristos bu32 base;
36c5dff60aSchristos struct hw *dma_master;
37c5dff60aSchristos bool acked;
38c5dff60aSchristos
39c5dff60aSchristos struct hw_event *handler;
40c5dff60aSchristos char saved_byte;
41c5dff60aSchristos int saved_count;
42c5dff60aSchristos
43c5dff60aSchristos /* This is aliased to DLH. */
44c5dff60aSchristos bu16 ier;
45c5dff60aSchristos /* These are aliased to DLL. */
46c5dff60aSchristos bu16 thr, rbr;
47c5dff60aSchristos
48c5dff60aSchristos /* Order after here is important -- matches hardware MMR layout. */
49c5dff60aSchristos bu16 BFIN_MMR_16(dll);
50c5dff60aSchristos bu16 BFIN_MMR_16(dlh);
51c5dff60aSchristos bu16 BFIN_MMR_16(iir);
52c5dff60aSchristos bu16 BFIN_MMR_16(lcr);
53c5dff60aSchristos bu16 BFIN_MMR_16(mcr);
54c5dff60aSchristos bu16 BFIN_MMR_16(lsr);
55c5dff60aSchristos bu16 BFIN_MMR_16(msr);
56c5dff60aSchristos bu16 BFIN_MMR_16(scr);
57c5dff60aSchristos bu16 _pad0[2];
58c5dff60aSchristos bu16 BFIN_MMR_16(gctl);
59c5dff60aSchristos };
60c5dff60aSchristos #define mmr_base() offsetof(struct bfin_uart, dll)
61c5dff60aSchristos #define mmr_offset(mmr) (offsetof(struct bfin_uart, mmr) - mmr_base())
62c5dff60aSchristos
63c5dff60aSchristos static const char * const mmr_names[] =
64c5dff60aSchristos {
65c5dff60aSchristos "UART_RBR/UART_THR", "UART_IER", "UART_IIR", "UART_LCR", "UART_MCR",
66c5dff60aSchristos "UART_LSR", "UART_MSR", "UART_SCR", "<INV>", "UART_GCTL",
67c5dff60aSchristos };
mmr_name(struct bfin_uart * uart,bu32 idx)68c5dff60aSchristos static const char *mmr_name (struct bfin_uart *uart, bu32 idx)
69c5dff60aSchristos {
70c5dff60aSchristos if (uart->lcr & DLAB)
71c5dff60aSchristos if (idx < 2)
72c5dff60aSchristos return idx == 0 ? "UART_DLL" : "UART_DLH";
73c5dff60aSchristos return mmr_names[idx];
74c5dff60aSchristos }
75c5dff60aSchristos #define mmr_name(off) mmr_name (uart, (off) / 4)
76c5dff60aSchristos
77c5dff60aSchristos static void
bfin_uart_poll(struct hw * me,void * data)78c5dff60aSchristos bfin_uart_poll (struct hw *me, void *data)
79c5dff60aSchristos {
80c5dff60aSchristos struct bfin_uart *uart = data;
81c5dff60aSchristos bu16 lsr;
82c5dff60aSchristos
83c5dff60aSchristos uart->handler = NULL;
84c5dff60aSchristos
85c5dff60aSchristos lsr = bfin_uart_get_status (me);
86c5dff60aSchristos if (lsr & DR)
87c5dff60aSchristos hw_port_event (me, DV_PORT_RX, 1);
88c5dff60aSchristos
89c5dff60aSchristos bfin_uart_reschedule (me);
90c5dff60aSchristos }
91c5dff60aSchristos
92c5dff60aSchristos void
bfin_uart_reschedule(struct hw * me)93c5dff60aSchristos bfin_uart_reschedule (struct hw *me)
94c5dff60aSchristos {
95c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
96c5dff60aSchristos
97c5dff60aSchristos if (uart->ier & ERBFI)
98c5dff60aSchristos {
99c5dff60aSchristos if (!uart->handler)
100c5dff60aSchristos uart->handler = hw_event_queue_schedule (me, 10000,
101c5dff60aSchristos bfin_uart_poll, uart);
102c5dff60aSchristos }
103c5dff60aSchristos else
104c5dff60aSchristos {
105c5dff60aSchristos if (uart->handler)
106c5dff60aSchristos {
107c5dff60aSchristos hw_event_queue_deschedule (me, uart->handler);
108c5dff60aSchristos uart->handler = NULL;
109c5dff60aSchristos }
110c5dff60aSchristos }
111c5dff60aSchristos }
112c5dff60aSchristos
113c5dff60aSchristos bu16
bfin_uart_write_byte(struct hw * me,bu16 thr,bu16 mcr)11448596154Schristos bfin_uart_write_byte (struct hw *me, bu16 thr, bu16 mcr)
115c5dff60aSchristos {
11648596154Schristos struct bfin_uart *uart = hw_data (me);
117c5dff60aSchristos unsigned char ch = thr;
11848596154Schristos
11948596154Schristos if (mcr & LOOP_ENA)
12048596154Schristos {
12148596154Schristos /* XXX: This probably doesn't work exactly right with
12248596154Schristos external FIFOs ... */
12348596154Schristos uart->saved_byte = thr;
12448596154Schristos uart->saved_count = 1;
12548596154Schristos }
12648596154Schristos
127c5dff60aSchristos bfin_uart_write_buffer (me, &ch, 1);
12848596154Schristos
129c5dff60aSchristos return thr;
130c5dff60aSchristos }
131c5dff60aSchristos
132c5dff60aSchristos static unsigned
bfin_uart_io_write_buffer(struct hw * me,const void * source,int space,address_word addr,unsigned nr_bytes)133c5dff60aSchristos bfin_uart_io_write_buffer (struct hw *me, const void *source,
134c5dff60aSchristos int space, address_word addr, unsigned nr_bytes)
135c5dff60aSchristos {
136c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
137c5dff60aSchristos bu32 mmr_off;
138c5dff60aSchristos bu32 value;
139c5dff60aSchristos bu16 *valuep;
140c5dff60aSchristos
141c03b94e9Schristos /* Invalid access mode is higher priority than missing register. */
142c03b94e9Schristos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, true))
143c03b94e9Schristos return 0;
144c03b94e9Schristos
145c5dff60aSchristos value = dv_load_2 (source);
146c5dff60aSchristos mmr_off = addr - uart->base;
147c5dff60aSchristos valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
148c5dff60aSchristos
149c5dff60aSchristos HW_TRACE_WRITE ();
150c5dff60aSchristos
151c5dff60aSchristos /* XXX: All MMRs are "8bit" ... what happens to high 8bits ? */
152c5dff60aSchristos switch (mmr_off)
153c5dff60aSchristos {
154c5dff60aSchristos case mmr_offset(dll):
155c5dff60aSchristos if (uart->lcr & DLAB)
156c5dff60aSchristos uart->dll = value;
157c5dff60aSchristos else
158c5dff60aSchristos {
15948596154Schristos uart->thr = bfin_uart_write_byte (me, value, uart->mcr);
160c5dff60aSchristos
161c5dff60aSchristos if (uart->ier & ETBEI)
162c5dff60aSchristos hw_port_event (me, DV_PORT_TX, 1);
163c5dff60aSchristos }
164c5dff60aSchristos break;
165c5dff60aSchristos case mmr_offset(dlh):
166c5dff60aSchristos if (uart->lcr & DLAB)
167c5dff60aSchristos uart->dlh = value;
168c5dff60aSchristos else
169c5dff60aSchristos {
170c5dff60aSchristos uart->ier = value;
171c5dff60aSchristos bfin_uart_reschedule (me);
172c5dff60aSchristos }
173c5dff60aSchristos break;
174c5dff60aSchristos case mmr_offset(iir):
175c5dff60aSchristos case mmr_offset(lsr):
176c5dff60aSchristos /* XXX: Writes are ignored ? */
177c5dff60aSchristos break;
178c5dff60aSchristos case mmr_offset(lcr):
179c5dff60aSchristos case mmr_offset(mcr):
180c5dff60aSchristos case mmr_offset(scr):
181c5dff60aSchristos case mmr_offset(gctl):
182c5dff60aSchristos *valuep = value;
183c5dff60aSchristos break;
184c5dff60aSchristos default:
185c5dff60aSchristos dv_bfin_mmr_invalid (me, addr, nr_bytes, true);
186c03b94e9Schristos return 0;
187c5dff60aSchristos }
188c5dff60aSchristos
189c5dff60aSchristos return nr_bytes;
190c5dff60aSchristos }
191c5dff60aSchristos
192c5dff60aSchristos /* Switch between socket and stdin on the fly. */
193c5dff60aSchristos bu16
bfin_uart_get_next_byte(struct hw * me,bu16 rbr,bu16 mcr,bool * fresh)19448596154Schristos bfin_uart_get_next_byte (struct hw *me, bu16 rbr, bu16 mcr, bool *fresh)
195c5dff60aSchristos {
196c5dff60aSchristos SIM_DESC sd = hw_system (me);
197c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
198c5dff60aSchristos int status = dv_sockser_status (sd);
199c5dff60aSchristos bool _fresh;
200c5dff60aSchristos
201c5dff60aSchristos /* NB: The "uart" here may only use interal state. */
202c5dff60aSchristos
203c5dff60aSchristos if (!fresh)
204c5dff60aSchristos fresh = &_fresh;
205c5dff60aSchristos
206c5dff60aSchristos *fresh = false;
20748596154Schristos
208c5dff60aSchristos if (uart->saved_count > 0)
209c5dff60aSchristos {
210c5dff60aSchristos *fresh = true;
211c5dff60aSchristos rbr = uart->saved_byte;
212c5dff60aSchristos --uart->saved_count;
213c5dff60aSchristos }
21448596154Schristos else if (mcr & LOOP_ENA)
21548596154Schristos {
21648596154Schristos /* RX is disconnected, so only return local data. */
21748596154Schristos }
21848596154Schristos else if (status & DV_SOCKSER_DISCONNECTED)
219c5dff60aSchristos {
220c5dff60aSchristos char byte;
221c5dff60aSchristos int ret = sim_io_poll_read (sd, 0/*STDIN*/, &byte, 1);
22248596154Schristos
223c5dff60aSchristos if (ret > 0)
224c5dff60aSchristos {
225c5dff60aSchristos *fresh = true;
226c5dff60aSchristos rbr = byte;
227c5dff60aSchristos }
228c5dff60aSchristos }
229c5dff60aSchristos else
230c5dff60aSchristos rbr = dv_sockser_read (sd);
231c5dff60aSchristos
232c5dff60aSchristos return rbr;
233c5dff60aSchristos }
234c5dff60aSchristos
235c5dff60aSchristos bu16
bfin_uart_get_status(struct hw * me)236c5dff60aSchristos bfin_uart_get_status (struct hw *me)
237c5dff60aSchristos {
238c5dff60aSchristos SIM_DESC sd = hw_system (me);
239c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
240c5dff60aSchristos int status = dv_sockser_status (sd);
241c5dff60aSchristos bu16 lsr = 0;
242c5dff60aSchristos
243c5dff60aSchristos if (status & DV_SOCKSER_DISCONNECTED)
244c5dff60aSchristos {
245c5dff60aSchristos if (uart->saved_count <= 0)
246c5dff60aSchristos uart->saved_count = sim_io_poll_read (sd, 0/*STDIN*/,
247c5dff60aSchristos &uart->saved_byte, 1);
248c5dff60aSchristos lsr |= TEMT | THRE | (uart->saved_count > 0 ? DR : 0);
249c5dff60aSchristos }
250c5dff60aSchristos else
251c5dff60aSchristos lsr |= (status & DV_SOCKSER_INPUT_EMPTY ? 0 : DR) |
252c5dff60aSchristos (status & DV_SOCKSER_OUTPUT_EMPTY ? TEMT | THRE : 0);
253c5dff60aSchristos
254c5dff60aSchristos return lsr;
255c5dff60aSchristos }
256c5dff60aSchristos
257c5dff60aSchristos static unsigned
bfin_uart_io_read_buffer(struct hw * me,void * dest,int space,address_word addr,unsigned nr_bytes)258c5dff60aSchristos bfin_uart_io_read_buffer (struct hw *me, void *dest,
259c5dff60aSchristos int space, address_word addr, unsigned nr_bytes)
260c5dff60aSchristos {
261c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
262c5dff60aSchristos bu32 mmr_off;
263c5dff60aSchristos bu16 *valuep;
264c5dff60aSchristos
265c03b94e9Schristos /* Invalid access mode is higher priority than missing register. */
266c03b94e9Schristos if (!dv_bfin_mmr_require_16 (me, addr, nr_bytes, false))
267c03b94e9Schristos return 0;
268c03b94e9Schristos
269c5dff60aSchristos mmr_off = addr - uart->base;
270c5dff60aSchristos valuep = (void *)((unsigned long)uart + mmr_base() + mmr_off);
271c5dff60aSchristos
272c5dff60aSchristos HW_TRACE_READ ();
273c5dff60aSchristos
274c5dff60aSchristos switch (mmr_off)
275c5dff60aSchristos {
276c5dff60aSchristos case mmr_offset(dll):
277c5dff60aSchristos if (uart->lcr & DLAB)
278c5dff60aSchristos dv_store_2 (dest, uart->dll);
279c5dff60aSchristos else
280c5dff60aSchristos {
28148596154Schristos uart->rbr = bfin_uart_get_next_byte (me, uart->rbr, uart->mcr, NULL);
282c5dff60aSchristos dv_store_2 (dest, uart->rbr);
283c5dff60aSchristos }
284c5dff60aSchristos break;
285c5dff60aSchristos case mmr_offset(dlh):
286c5dff60aSchristos if (uart->lcr & DLAB)
287c5dff60aSchristos dv_store_2 (dest, uart->dlh);
288c5dff60aSchristos else
289c5dff60aSchristos dv_store_2 (dest, uart->ier);
290c5dff60aSchristos break;
291c5dff60aSchristos case mmr_offset(lsr):
292c5dff60aSchristos /* XXX: Reads are destructive on most parts, but not all ... */
293c5dff60aSchristos uart->lsr |= bfin_uart_get_status (me);
294c5dff60aSchristos dv_store_2 (dest, *valuep);
295c5dff60aSchristos uart->lsr = 0;
296c5dff60aSchristos break;
297c5dff60aSchristos case mmr_offset(iir):
298c5dff60aSchristos /* XXX: Reads are destructive ... */
299c5dff60aSchristos case mmr_offset(lcr):
300c5dff60aSchristos case mmr_offset(mcr):
301c5dff60aSchristos case mmr_offset(scr):
302c5dff60aSchristos case mmr_offset(gctl):
303c5dff60aSchristos dv_store_2 (dest, *valuep);
304c5dff60aSchristos break;
305c5dff60aSchristos default:
306c5dff60aSchristos dv_bfin_mmr_invalid (me, addr, nr_bytes, false);
307c03b94e9Schristos return 0;
308c5dff60aSchristos }
309c5dff60aSchristos
310c5dff60aSchristos return nr_bytes;
311c5dff60aSchristos }
312c5dff60aSchristos
313c5dff60aSchristos unsigned
bfin_uart_read_buffer(struct hw * me,unsigned char * buffer,unsigned nr_bytes)314c5dff60aSchristos bfin_uart_read_buffer (struct hw *me, unsigned char *buffer, unsigned nr_bytes)
315c5dff60aSchristos {
316c5dff60aSchristos SIM_DESC sd = hw_system (me);
317c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
318c5dff60aSchristos int status = dv_sockser_status (sd);
319c5dff60aSchristos unsigned i = 0;
320c5dff60aSchristos
321c5dff60aSchristos if (status & DV_SOCKSER_DISCONNECTED)
322c5dff60aSchristos {
323c5dff60aSchristos int ret;
324c5dff60aSchristos
325c5dff60aSchristos while (uart->saved_count > 0 && i < nr_bytes)
326c5dff60aSchristos {
327c5dff60aSchristos buffer[i++] = uart->saved_byte;
328c5dff60aSchristos --uart->saved_count;
329c5dff60aSchristos }
330c5dff60aSchristos
331c5dff60aSchristos ret = sim_io_poll_read (sd, 0/*STDIN*/, (char *) buffer, nr_bytes - i);
332c5dff60aSchristos if (ret > 0)
333c5dff60aSchristos i += ret;
334c5dff60aSchristos }
335c5dff60aSchristos else
336c5dff60aSchristos buffer[i++] = dv_sockser_read (sd);
337c5dff60aSchristos
338c5dff60aSchristos return i;
339c5dff60aSchristos }
340c5dff60aSchristos
341c5dff60aSchristos static unsigned
bfin_uart_dma_read_buffer(struct hw * me,void * dest,int space,unsigned_word addr,unsigned nr_bytes)342c5dff60aSchristos bfin_uart_dma_read_buffer (struct hw *me, void *dest, int space,
343c5dff60aSchristos unsigned_word addr, unsigned nr_bytes)
344c5dff60aSchristos {
345c5dff60aSchristos HW_TRACE_DMA_READ ();
346c5dff60aSchristos return bfin_uart_read_buffer (me, dest, nr_bytes);
347c5dff60aSchristos }
348c5dff60aSchristos
349c5dff60aSchristos unsigned
bfin_uart_write_buffer(struct hw * me,const unsigned char * buffer,unsigned nr_bytes)350c5dff60aSchristos bfin_uart_write_buffer (struct hw *me, const unsigned char *buffer,
351c5dff60aSchristos unsigned nr_bytes)
352c5dff60aSchristos {
353c5dff60aSchristos SIM_DESC sd = hw_system (me);
354c5dff60aSchristos int status = dv_sockser_status (sd);
355c5dff60aSchristos
356c5dff60aSchristos if (status & DV_SOCKSER_DISCONNECTED)
357c5dff60aSchristos {
358c5dff60aSchristos sim_io_write_stdout (sd, (const char *) buffer, nr_bytes);
359c5dff60aSchristos sim_io_flush_stdout (sd);
360c5dff60aSchristos }
361c5dff60aSchristos else
362c5dff60aSchristos {
363c5dff60aSchristos /* Normalize errors to a value of 0. */
364c5dff60aSchristos int ret = dv_sockser_write_buffer (sd, buffer, nr_bytes);
365c5dff60aSchristos nr_bytes = CLAMP (ret, 0, nr_bytes);
366c5dff60aSchristos }
367c5dff60aSchristos
368c5dff60aSchristos return nr_bytes;
369c5dff60aSchristos }
370c5dff60aSchristos
371c5dff60aSchristos static unsigned
bfin_uart_dma_write_buffer(struct hw * me,const void * source,int space,unsigned_word addr,unsigned nr_bytes,int violate_read_only_section)372c5dff60aSchristos bfin_uart_dma_write_buffer (struct hw *me, const void *source,
373c5dff60aSchristos int space, unsigned_word addr,
374c5dff60aSchristos unsigned nr_bytes,
375c5dff60aSchristos int violate_read_only_section)
376c5dff60aSchristos {
377c5dff60aSchristos struct bfin_uart *uart = hw_data (me);
378c5dff60aSchristos unsigned ret;
379c5dff60aSchristos
380c5dff60aSchristos HW_TRACE_DMA_WRITE ();
381c5dff60aSchristos
382c5dff60aSchristos ret = bfin_uart_write_buffer (me, source, nr_bytes);
383c5dff60aSchristos
384c5dff60aSchristos if (ret == nr_bytes && (uart->ier & ETBEI))
385c5dff60aSchristos hw_port_event (me, DV_PORT_TX, 1);
386c5dff60aSchristos
387c5dff60aSchristos return ret;
388c5dff60aSchristos }
389c5dff60aSchristos
390c5dff60aSchristos static const struct hw_port_descriptor bfin_uart_ports[] =
391c5dff60aSchristos {
392c5dff60aSchristos { "tx", DV_PORT_TX, 0, output_port, },
393c5dff60aSchristos { "rx", DV_PORT_RX, 0, output_port, },
394c5dff60aSchristos { "stat", DV_PORT_STAT, 0, output_port, },
395c5dff60aSchristos { NULL, 0, 0, 0, },
396c5dff60aSchristos };
397c5dff60aSchristos
398c5dff60aSchristos static void
attach_bfin_uart_regs(struct hw * me,struct bfin_uart * uart)399c5dff60aSchristos attach_bfin_uart_regs (struct hw *me, struct bfin_uart *uart)
400c5dff60aSchristos {
401c5dff60aSchristos address_word attach_address;
402c5dff60aSchristos int attach_space;
403c5dff60aSchristos unsigned attach_size;
404c5dff60aSchristos reg_property_spec reg;
405c5dff60aSchristos
406c5dff60aSchristos if (hw_find_property (me, "reg") == NULL)
407c5dff60aSchristos hw_abort (me, "Missing \"reg\" property");
408c5dff60aSchristos
409c5dff60aSchristos if (!hw_find_reg_array_property (me, "reg", 0, ®))
410c5dff60aSchristos hw_abort (me, "\"reg\" property must contain three addr/size entries");
411c5dff60aSchristos
412c5dff60aSchristos hw_unit_address_to_attach_address (hw_parent (me),
413c5dff60aSchristos ®.address,
414c5dff60aSchristos &attach_space, &attach_address, me);
415c5dff60aSchristos hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me);
416c5dff60aSchristos
417c5dff60aSchristos if (attach_size != BFIN_MMR_UART_SIZE)
418c5dff60aSchristos hw_abort (me, "\"reg\" size must be %#x", BFIN_MMR_UART_SIZE);
419c5dff60aSchristos
420c5dff60aSchristos hw_attach_address (hw_parent (me),
421c5dff60aSchristos 0, attach_space, attach_address, attach_size, me);
422c5dff60aSchristos
423c5dff60aSchristos uart->base = attach_address;
424c5dff60aSchristos }
425c5dff60aSchristos
426c5dff60aSchristos static void
bfin_uart_finish(struct hw * me)427c5dff60aSchristos bfin_uart_finish (struct hw *me)
428c5dff60aSchristos {
429c5dff60aSchristos struct bfin_uart *uart;
430c5dff60aSchristos
431c5dff60aSchristos uart = HW_ZALLOC (me, struct bfin_uart);
432c5dff60aSchristos
433c5dff60aSchristos set_hw_data (me, uart);
434c5dff60aSchristos set_hw_io_read_buffer (me, bfin_uart_io_read_buffer);
435c5dff60aSchristos set_hw_io_write_buffer (me, bfin_uart_io_write_buffer);
436c5dff60aSchristos set_hw_dma_read_buffer (me, bfin_uart_dma_read_buffer);
437c5dff60aSchristos set_hw_dma_write_buffer (me, bfin_uart_dma_write_buffer);
438c5dff60aSchristos set_hw_ports (me, bfin_uart_ports);
439c5dff60aSchristos
440c5dff60aSchristos attach_bfin_uart_regs (me, uart);
441c5dff60aSchristos
442c5dff60aSchristos /* Initialize the UART. */
443c5dff60aSchristos uart->dll = 0x0001;
444c5dff60aSchristos uart->iir = 0x0001;
445c5dff60aSchristos uart->lsr = 0x0060;
446c5dff60aSchristos }
447c5dff60aSchristos
448c5dff60aSchristos const struct hw_descriptor dv_bfin_uart_descriptor[] =
449c5dff60aSchristos {
450c5dff60aSchristos {"bfin_uart", bfin_uart_finish,},
451c5dff60aSchristos {NULL, NULL},
452c5dff60aSchristos };
453