Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys The UART in the allwiner SoCs is not full-compatible wit...
details: https://anonhg.NetBSD.org/src/rev/2d8b91e4b03b
branches: trunk
changeset: 345438:2d8b91e4b03b
user: bouyer <bouyer%NetBSD.org@localhost>
date: Fri May 27 20:01:49 2016 +0000
description:
The UART in the allwiner SoCs is not full-compatible with the 16550, and
it's not a 16750 either. Like the 16750 it has the IIR_BUSY interrupt,
which is triggered when writing to LCR while the chip
can't accept it. But unlike the 16750, it has a specific register,
HALT, to allow writing to the LCR and divisor registers, and then
commit the changes.
Tested on an A20 SoC, changing the baud rate while keeping the
tty device open and incoming data.
diffstat:
sys/arch/arm/allwinner/files.awin | 4 +-
sys/conf/files | 4 +-
sys/dev/ic/com.c | 45 ++++++++++++++++++++++++++++++++++----
sys/dev/ic/comreg.h | 10 ++++++-
sys/dev/ic/comvar.h | 14 +++++++++++-
sys/dev/ic/ns16550reg.h | 9 ++++++-
6 files changed, 72 insertions(+), 14 deletions(-)
diffs (209 lines):
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/arch/arm/allwinner/files.awin
--- a/sys/arch/arm/allwinner/files.awin Fri May 27 16:44:15 2016 +0000
+++ b/sys/arch/arm/allwinner/files.awin Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.awin,v 1.35 2016/04/25 20:15:46 bouyer Exp $
+# $NetBSD: files.awin,v 1.36 2016/05/27 20:01:49 bouyer Exp $
#
# Configuration info for Allwinner ARM Peripherals
#
@@ -65,7 +65,7 @@
file arch/arm/allwinner/awin_cnt.c awin_cnt
# A10/A20 UART
-options COM_16750 # for IIR_BUSY
+options COM_AWIN # for IIR_BUSY
attach com at awinio with awin_com
file arch/arm/allwinner/awin_com.c awin_com
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/conf/files
--- a/sys/conf/files Fri May 27 16:44:15 2016 +0000
+++ b/sys/conf/files Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1158 2016/05/01 10:21:02 nonaka Exp $
+# $NetBSD: files,v 1.1159 2016/05/27 20:01:49 bouyer Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20150846
@@ -870,7 +870,7 @@
# XXX In a perfect world, this would be done with attributes
defflag opt_com.h COM_16650 COM_16750
COM_HAYESP COM_PXA2X0 COM_AU1X00
- COM_REGMAP COM_FUNCMAP
+ COM_REGMAP COM_FUNCMAP COM_AWIN
defparam opt_com.h COM_TOLERANCE
device com { } : tty
file dev/ic/com.c com needs-flag
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/dev/ic/com.c
--- a/sys/dev/ic/com.c Fri May 27 16:44:15 2016 +0000
+++ b/sys/dev/ic/com.c Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: com.c,v 1.338 2015/12/14 23:57:30 jmcneill Exp $ */
+/* $NetBSD: com.c,v 1.339 2016/05/27 20:01:49 bouyer Exp $ */
/*-
* Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.338 2015/12/14 23:57:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.339 2016/05/27 20:01:49 bouyer Exp $");
#include "opt_com.h"
#include "opt_ddb.h"
@@ -424,7 +424,7 @@
(u_long)comcons_info.regs.cr_iobase);
}
-#ifdef COM_16750
+#if defined(COM_16750) || defined(COM_AWIN)
/* Use in comintr(). */
sc->sc_lcr = cflag2lcr(comcons_info.cflag);
#endif
@@ -1580,7 +1580,7 @@
aprint_error_dev(sc->sc_dev, "com_iflush timeout %02x\n", reg);
#endif
-#ifdef COM_16750
+#if defined(COM_16750) || defined(COM_AWIN)
uint8_t fifo;
/*
* Reset all Rx/Tx FIFO, preserve current FIFO length.
@@ -2027,6 +2027,9 @@
/* Handle ns16750-specific busy interrupt. */
#ifdef COM_16750
+#ifdef COM_AWIN
+#error "COM_16750 and COM_AWIN are exclusive"
+#endif
int timeout;
if ((iir & IIR_BUSY) == IIR_BUSY) {
for (timeout = 10000;
@@ -2043,7 +2046,39 @@
iir = CSR_READ_1(regsp, COM_REG_IIR);
}
#endif /* COM_16750 */
-
+#ifdef COM_AWIN
+ /* Allwinner BUSY interrupt */
+ if ((iir & IIR_BUSY) == IIR_BUSY) {
+ if ((CSR_READ_1(regsp, COM_REG_USR) & 0x1) != 0) {
+ CSR_WRITE_1(regsp, COM_REG_HALT, HALT_CHCFG_EN);
+ CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr | LCR_DLAB);
+ CSR_WRITE_1(regsp, COM_REG_DLBL, sc->sc_dlbl);
+ CSR_WRITE_1(regsp, COM_REG_DLBH, sc->sc_dlbh);
+ CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr);
+ CSR_WRITE_1(regsp, COM_REG_HALT,
+ HALT_CHCFG_EN | HALT_CHCFG_UD);
+ for (int timeout = 10000000;
+ (CSR_READ_1(regsp, COM_REG_HALT) & HALT_CHCFG_UD) != 0;
+ timeout--) {
+ if (timeout <= 0) {
+ aprint_error_dev(sc->sc_dev,
+ "timeout while waiting for HALT "
+ "update acknowledge 0x%x 0x%x\n",
+ CSR_READ_1(regsp, COM_REG_HALT),
+ CSR_READ_1(regsp, COM_REG_USR));
+ break;
+ }
+ }
+ CSR_WRITE_1(regsp, COM_REG_HALT, 0);
+ (void)CSR_READ_1(regsp, COM_REG_USR);
+ } else {
+ CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr | LCR_DLAB);
+ CSR_WRITE_1(regsp, COM_REG_DLBL, sc->sc_dlbl);
+ CSR_WRITE_1(regsp, COM_REG_DLBH, sc->sc_dlbh);
+ CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr);
+ }
+ }
+#endif /* COM_AWIN */
if (ISSET(iir, IIR_NOPEND)) {
mutex_spin_exit(&sc->sc_lock);
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/dev/ic/comreg.h
--- a/sys/dev/ic/comreg.h Fri May 27 16:44:15 2016 +0000
+++ b/sys/dev/ic/comreg.h Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: comreg.h,v 1.24 2015/03/07 15:49:20 macallan Exp $ */
+/* $NetBSD: comreg.h,v 1.25 2016/05/27 20:01:49 bouyer Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -64,7 +64,7 @@
#define IIR_NOPEND 0x1 /* No pending interrupts */
#define IIR_64B_FIFO 0x20 /* 64byte FIFO Enabled (16750) */
#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */
-#ifdef COM_16750
+#if defined(COM_16750) || defined(COM_AWIN)
#define IIR_BUSY 0x7 /* Busy indicator */
#endif
@@ -160,6 +160,12 @@
#define MDR1_MODE_UART_16X 0x00
#define MDR1_MODE_MASK 0x07
+#ifdef COM_AWIN
+/* AWIN-specific registers */
+#define HALT_CHCFG_UD 0x04 /* apply updates to LCR/dividors */
+#define HALT_CHCFG_EN 0x02 /* enable change while busy */
+#endif
+
/* XXX ISA-specific. */
#define COM_NPORTS 8
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/dev/ic/comvar.h
--- a/sys/dev/ic/comvar.h Fri May 27 16:44:15 2016 +0000
+++ b/sys/dev/ic/comvar.h Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: comvar.h,v 1.81 2015/05/03 17:22:54 jmcneill Exp $ */
+/* $NetBSD: comvar.h,v 1.82 2016/05/27 20:01:49 bouyer Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -94,6 +94,12 @@
#ifdef COM_16750
#define COM_REG_USR 31
#endif
+#ifdef COM_AWIN
+#define COM_REG_USR 31
+#define COM_REG_TFL 32
+#define COM_REG_RFL 33
+#define COM_REG_HALT 41
+#endif
struct com_regs {
bus_space_tag_t cr_iot;
@@ -141,6 +147,12 @@
#ifdef COM_16750
#define COM_REG_USR com_usr
#endif
+#ifdef COM_AWIN
+#define COM_REG_USR com_usr
+#define COM_REG_TFL com_tfl
+#define COM_REG_RFL com_rfl
+#define COM_REG_HALT com_halt
+#endif
struct com_regs {
bus_space_tag_t cr_iot;
diff -r fb3445c7c086 -r 2d8b91e4b03b sys/dev/ic/ns16550reg.h
--- a/sys/dev/ic/ns16550reg.h Fri May 27 16:44:15 2016 +0000
+++ b/sys/dev/ic/ns16550reg.h Fri May 27 20:01:49 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ns16550reg.h,v 1.10 2013/10/03 13:23:03 kiyohara Exp $ */
+/* $NetBSD: ns16550reg.h,v 1.11 2016/05/27 20:01:49 bouyer Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -54,4 +54,9 @@
#ifdef COM_16750
#define com_usr 31 /* status register (R) */
#endif
-
+#ifdef COM_AWIN
+#define com_usr 31 /* status register (R) */
+#define com_tfl 32 /* transmit fifo level (R) */
+#define com_rfl 33 /* receive fifo level (R) */
+#define com_halt 41 /* halt tx (R/W) */
+#endif
Home |
Main Index |
Thread Index |
Old Index