4 * Copyright (c) 2008 OKL
5 * Originally Written by Hans Jiang
6 * Copyright (c) 2011 NICTA Pty Ltd.
7 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
12 * This is a `bare-bones' implementation of the IMX series serial ports.
14 * -- implement FIFOs. The real hardware has 32 word transmit
15 * and receive FIFOs; we currently use a 1-char buffer
17 * -- implement BAUD-rate and modem lines, for when the backend
18 * is a real serial device.
21 #include "hw/char/imx_serial.h"
22 #include "sysemu/sysemu.h"
23 #include "sysemu/char.h"
24 #include "hw/arm/imx.h"
26 //#define DEBUG_SERIAL 1
28 #define DPRINTF(fmt, args...) \
29 do { printf("%s: " fmt , TYPE_IMX_SERIAL, ##args); } while (0)
31 #define DPRINTF(fmt, args...) do {} while (0)
35 * Define to 1 for messages about attempts to
36 * access unimplemented registers or similar.
38 //#define DEBUG_IMPLEMENTATION 1
39 #ifdef DEBUG_IMPLEMENTATION
40 # define IPRINTF(fmt, args...) \
41 do { fprintf(stderr, "%s: " fmt, TYPE_IMX_SERIAL, ##args); } while (0)
43 # define IPRINTF(fmt, args...) do {} while (0)
46 static const VMStateDescription vmstate_imx_serial
= {
47 .name
= TYPE_IMX_SERIAL
,
49 .minimum_version_id
= 1,
50 .fields
= (VMStateField
[]) {
51 VMSTATE_INT32(readbuff
, IMXSerialState
),
52 VMSTATE_UINT32(usr1
, IMXSerialState
),
53 VMSTATE_UINT32(usr2
, IMXSerialState
),
54 VMSTATE_UINT32(ucr1
, IMXSerialState
),
55 VMSTATE_UINT32(uts1
, IMXSerialState
),
56 VMSTATE_UINT32(onems
, IMXSerialState
),
57 VMSTATE_UINT32(ufcr
, IMXSerialState
),
58 VMSTATE_UINT32(ubmr
, IMXSerialState
),
59 VMSTATE_UINT32(ubrc
, IMXSerialState
),
60 VMSTATE_UINT32(ucr3
, IMXSerialState
),
65 static void imx_update(IMXSerialState
*s
)
69 flags
= (s
->usr1
& s
->ucr1
) & (USR1_TRDY
|USR1_RRDY
);
70 if (!(s
->ucr1
& UCR1_TXMPTYEN
)) {
74 qemu_set_irq(s
->irq
, !!flags
);
77 static void imx_serial_reset(IMXSerialState
*s
)
80 s
->usr1
= USR1_TRDY
| USR1_RXDS
;
82 * Fake attachment of a terminal: assert RTS.
85 s
->usr2
= USR2_TXFE
| USR2_TXDC
| USR2_DCDIN
;
86 s
->uts1
= UTS1_RXEMPTY
| UTS1_TXEMPTY
;
92 s
->readbuff
= URXD_ERR
;
95 static void imx_serial_reset_at_boot(DeviceState
*dev
)
97 IMXSerialState
*s
= IMX_SERIAL(dev
);
102 * enable the uart on boot, so messages from the linux decompresser
103 * are visible. On real hardware this is done by the boot rom
104 * before anything else is loaded.
106 s
->ucr1
= UCR1_UARTEN
;
111 static uint64_t imx_serial_read(void *opaque
, hwaddr offset
,
114 IMXSerialState
*s
= (IMXSerialState
*)opaque
;
117 DPRINTF("read(offset=%x)\n", offset
>> 2);
118 switch (offset
>> 2) {
121 if (!(s
->uts1
& UTS1_RXEMPTY
)) {
122 /* Character is valid */
124 s
->usr1
&= ~USR1_RRDY
;
125 s
->usr2
&= ~USR2_RDR
;
126 s
->uts1
|= UTS1_RXEMPTY
;
128 qemu_chr_accept_input(s
->chr
);
132 case 0x20: /* UCR1 */
135 case 0x21: /* UCR2 */
138 case 0x25: /* USR1 */
141 case 0x26: /* USR2 */
144 case 0x2A: /* BRM Modulator */
147 case 0x2B: /* Baud Rate Count */
150 case 0x2d: /* Test register */
153 case 0x24: /* UFCR */
159 case 0x22: /* UCR3 */
162 case 0x23: /* UCR4 */
163 case 0x29: /* BRM Incremental */
164 return 0x0; /* TODO */
167 IPRINTF("%s: bad offset: 0x%x\n", __func__
, (int)offset
);
172 static void imx_serial_write(void *opaque
, hwaddr offset
,
173 uint64_t value
, unsigned size
)
175 IMXSerialState
*s
= (IMXSerialState
*)opaque
;
178 DPRINTF("write(offset=%x, value = %x) to %s\n",
180 (unsigned int)value
, s
->chr
? s
->chr
->label
: "NODEV");
182 switch (offset
>> 2) {
183 case 0x10: /* UTXD */
185 if (s
->ucr2
& UCR2_TXEN
) {
187 qemu_chr_fe_write(s
->chr
, &ch
, 1);
189 s
->usr1
&= ~USR1_TRDY
;
191 s
->usr1
|= USR1_TRDY
;
196 case 0x20: /* UCR1 */
197 s
->ucr1
= value
& 0xffff;
198 DPRINTF("write(ucr1=%x)\n", (unsigned int)value
);
202 case 0x21: /* UCR2 */
204 * Only a few bits in control register 2 are implemented as yet.
205 * If it's intended to use a real serial device as a back-end, this
206 * register will have to be implemented more fully.
208 if (!(value
& UCR2_SRST
)) {
213 if (value
& UCR2_RXEN
) {
214 if (!(s
->ucr2
& UCR2_RXEN
)) {
215 qemu_chr_accept_input(s
->chr
);
218 s
->ucr2
= value
& 0xffff;
221 case 0x25: /* USR1 */
222 value
&= USR1_AWAKE
| USR1_AIRINT
| USR1_DTRD
| USR1_AGTIM
|
223 USR1_FRAMERR
| USR1_ESCF
| USR1_RTSD
| USR1_PARTYER
;
227 case 0x26: /* USR2 */
229 * Writing 1 to some bits clears them; all other
232 value
&= USR2_ADET
| USR2_DTRF
| USR2_IDLE
| USR2_ACST
|
233 USR2_RIDELT
| USR2_IRINT
| USR2_WAKE
|
234 USR2_DCDDELT
| USR2_RTSF
| USR2_BRCD
| USR2_ORE
;
239 * Linux expects to see what it writes to these registers
240 * We don't currently alter the baud rate
242 case 0x29: /* UBIR */
243 s
->ubrc
= value
& 0xffff;
246 case 0x2a: /* UBMR */
247 s
->ubmr
= value
& 0xffff;
250 case 0x2c: /* One ms reg */
251 s
->onems
= value
& 0xffff;
254 case 0x24: /* FIFO control register */
255 s
->ufcr
= value
& 0xffff;
258 case 0x22: /* UCR3 */
259 s
->ucr3
= value
& 0xffff;
262 case 0x2d: /* UTS1 */
263 case 0x23: /* UCR4 */
264 IPRINTF("Unimplemented Register %x written to\n", offset
>> 2);
269 IPRINTF("%s: Bad offset 0x%x\n", __func__
, (int)offset
);
273 static int imx_can_receive(void *opaque
)
275 IMXSerialState
*s
= (IMXSerialState
*)opaque
;
276 return !(s
->usr1
& USR1_RRDY
);
279 static void imx_put_data(void *opaque
, uint32_t value
)
281 IMXSerialState
*s
= (IMXSerialState
*)opaque
;
282 DPRINTF("received char\n");
283 s
->usr1
|= USR1_RRDY
;
285 s
->uts1
&= ~UTS1_RXEMPTY
;
290 static void imx_receive(void *opaque
, const uint8_t *buf
, int size
)
292 imx_put_data(opaque
, *buf
);
295 static void imx_event(void *opaque
, int event
)
297 if (event
== CHR_EVENT_BREAK
) {
298 imx_put_data(opaque
, URXD_BRK
);
303 static const struct MemoryRegionOps imx_serial_ops
= {
304 .read
= imx_serial_read
,
305 .write
= imx_serial_write
,
306 .endianness
= DEVICE_NATIVE_ENDIAN
,
309 static void imx_serial_realize(DeviceState
*dev
, Error
**errp
)
311 IMXSerialState
*s
= IMX_SERIAL(dev
);
314 qemu_chr_add_handlers(s
->chr
, imx_can_receive
, imx_receive
,
317 DPRINTF("No char dev for uart at 0x%lx\n",
318 (unsigned long)s
->iomem
.ram_addr
);
322 static void imx_serial_init(Object
*obj
)
324 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
325 IMXSerialState
*s
= IMX_SERIAL(obj
);
327 memory_region_init_io(&s
->iomem
, obj
, &imx_serial_ops
, s
,
328 TYPE_IMX_SERIAL
, 0x1000);
329 sysbus_init_mmio(sbd
, &s
->iomem
);
330 sysbus_init_irq(sbd
, &s
->irq
);
333 void imx_serial_create(int uart
, const hwaddr addr
, qemu_irq irq
)
337 CharDriverState
*chr
;
338 const char chr_name
[] = "serial";
339 char label
[ARRAY_SIZE(chr_name
) + 1];
341 dev
= qdev_create(NULL
, TYPE_IMX_SERIAL
);
343 if (uart
>= MAX_SERIAL_PORTS
) {
344 hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",
345 uart
, MAX_SERIAL_PORTS
);
347 chr
= serial_hds
[uart
];
349 snprintf(label
, ARRAY_SIZE(label
), "%s%d", chr_name
, uart
);
350 chr
= qemu_chr_new(label
, "null", NULL
);
352 hw_error("Can't assign serial port to imx-uart%d.\n", uart
);
356 qdev_prop_set_chr(dev
, "chardev", chr
);
357 bus
= SYS_BUS_DEVICE(dev
);
358 qdev_init_nofail(dev
);
359 if (addr
!= (hwaddr
)-1) {
360 sysbus_mmio_map(bus
, 0, addr
);
362 sysbus_connect_irq(bus
, 0, irq
);
367 static Property imx_serial_properties
[] = {
368 DEFINE_PROP_CHR("chardev", IMXSerialState
, chr
),
369 DEFINE_PROP_END_OF_LIST(),
372 static void imx_serial_class_init(ObjectClass
*klass
, void *data
)
374 DeviceClass
*dc
= DEVICE_CLASS(klass
);
376 dc
->realize
= imx_serial_realize
;
377 dc
->vmsd
= &vmstate_imx_serial
;
378 dc
->reset
= imx_serial_reset_at_boot
;
379 set_bit(DEVICE_CATEGORY_INPUT
, dc
->categories
);
380 dc
->desc
= "i.MX series UART";
381 dc
->props
= imx_serial_properties
;
384 static const TypeInfo imx_serial_info
= {
385 .name
= TYPE_IMX_SERIAL
,
386 .parent
= TYPE_SYS_BUS_DEVICE
,
387 .instance_size
= sizeof(IMXSerialState
),
388 .instance_init
= imx_serial_init
,
389 .class_init
= imx_serial_class_init
,
392 static void imx_serial_register_types(void)
394 type_register_static(&imx_serial_info
);
397 type_init(imx_serial_register_types
)