Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Add support for Apple M1 debug UART.
details: https://anonhg.NetBSD.org/src/rev/cbb8387a3feb
branches: trunk
changeset: 985913:cbb8387a3feb
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Sep 13 23:31:23 2021 +0000
description:
Add support for Apple M1 debug UART.
diffstat:
sys/arch/arm/samsung/exynos_uart.c | 122 +++++++++++++++++++++++++++-------
sys/arch/arm/samsung/sscom_reg.h | 11 ++-
sys/arch/evbarm/conf/GENERIC64 | 3 +-
sys/arch/evbarm/conf/files.generic64 | 3 +-
4 files changed, 109 insertions(+), 30 deletions(-)
diffs (truncated from 386 to 300 lines):
diff -r a43b1196b101 -r cbb8387a3feb sys/arch/arm/samsung/exynos_uart.c
--- a/sys/arch/arm/samsung/exynos_uart.c Mon Sep 13 23:30:52 2021 +0000
+++ b/sys/arch/arm/samsung/exynos_uart.c Mon Sep 13 23:31:23 2021 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: exynos_uart.c,v 1.5 2021/03/14 08:16:57 skrll Exp $ */
+/* $NetBSD: exynos_uart.c,v 1.6 2021/09/13 23:31:23 jmcneill Exp $ */
/*-
- * Copyright (c) 2013-2018 The NetBSD Foundation, Inc.
+ * Copyright (c) 2013-2021 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -33,7 +33,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_uart.c,v 1.5 2021/03/14 08:16:57 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_uart.c,v 1.6 2021/09/13 23:31:23 jmcneill Exp $");
#define cn_trap() \
do { \
@@ -73,6 +73,18 @@
extern struct cfdriver exuart_cd;
+enum exynos_uart_type {
+ EXYNOS_UART_SAMSUNG,
+ EXYNOS_UART_APPLE,
+};
+
+struct exynos_uart_config {
+ enum exynos_uart_type type;
+ uint32_t rxfull;
+ uint32_t txfull;
+ uint32_t rxcount;
+};
+
struct exynos_uart_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
@@ -87,6 +99,8 @@
int sc_ospeed;
tcflag_t sc_cflag;
+ const struct exynos_uart_config *sc_conf;
+
u_char sc_buf[1024];
};
@@ -135,8 +149,23 @@
static int exynos_uart_cmajor = -1;
+static const struct exynos_uart_config exynos_uart_samsung = {
+ .type = EXYNOS_UART_SAMSUNG,
+ .rxfull = UFSTAT_RXFULL,
+ .txfull = UFSTAT_TXFULL,
+ .rxcount = UFSTAT_RXCOUNT,
+};
+
+static const struct exynos_uart_config exynos_uart_apple = {
+ .type = EXYNOS_UART_APPLE,
+ .rxfull = UFSTAT_S5L_RXFULL,
+ .txfull = UFSTAT_S5L_TXFULL,
+ .rxcount = UFSTAT_S5L_RXCOUNT,
+};
+
static const struct device_compatible_entry compat_data[] = {
- { .compat = "samsung,exynos4210-uart" },
+ { .compat = "samsung,exynos4210-uart", .data = &exynos_uart_samsung },
+ { .compat = "apple,s5l-uart", .data = &exynos_uart_apple },
DEVICE_COMPAT_EOL
};
@@ -163,6 +192,7 @@
int major, minor;
bus_addr_t addr;
bus_size_t size;
+ uint32_t ucon;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
@@ -187,6 +217,7 @@
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
+ sc->sc_conf = of_compatible_lookup(phandle, compat_data)->data;
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
sc->sc_console = is_console;
if (is_console) {
@@ -245,14 +276,21 @@
__SHIFTIN(1, UFCON_RXTRIGGER) |
UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
UFCON_FIFO_ENABLE);
+
/* Configure PIO mode with RX timeout interrupts */
- WR4(sc, SSCOM_UCON,
- __SHIFTIN(3, UCON_RXTO) |
- UCON_TOINT | UCON_ERRINT |
- UCON_TXMODE_INT | UCON_RXMODE_INT);
+ ucon = UCON_TOINT | UCON_ERRINT |
+ UCON_TXMODE_INT | UCON_RXMODE_INT;
+ WR4(sc, SSCOM_UCON, ucon);
- /* Disable interrupts */
- WR4(sc, SSCOM_UINTM, ~0u);
+ switch (sc->sc_conf->type) {
+ case EXYNOS_UART_SAMSUNG:
+ WR4(sc, SSCOM_UCON, ucon | __SHIFTIN(3, UCON_RXTO));
+ /* Disable interrupts */
+ WR4(sc, SSCOM_UINTM, ~0u);
+ break;
+ case EXYNOS_UART_APPLE:
+ break;
+ }
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
}
@@ -267,19 +305,19 @@
s = splserial();
ufstat = RD4(sc, SSCOM_UFSTAT);
- if (__SHIFTOUT(ufstat, UFSTAT_RXCOUNT) == 0) {
+ if (__SHIFTOUT(ufstat, sc->sc_conf->rxcount) == 0) {
splx(s);
return -1;
}
- c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, SSCOM_URXH);
+ c = RD4(sc, SSCOM_URXH);
#if defined(DDB)
extern int db_active;
if (!db_active)
#endif
{
int cn_trapped __unused = 0;
- cn_check_magic(dev, c, exynos_uart_cnm_state);
+ cn_check_magic(dev, c & 0xff, exynos_uart_cnm_state);
}
splx(s);
@@ -294,10 +332,10 @@
int s;
s = splserial();
- while ((RD4(sc, SSCOM_UFSTAT) & UFSTAT_TXFULL) != 0)
+ while ((RD4(sc, SSCOM_UFSTAT) & sc->sc_conf->txfull) != 0)
;
- bus_space_write_1(sc->sc_bst, sc->sc_bsh, SSCOM_UTXH, c);
+ WR4(sc, SSCOM_UTXH, c & 0xff);
splx(s);
}
@@ -310,7 +348,7 @@
static void
exynos_uart_cnattach(bus_space_tag_t bst, bus_space_handle_t bsh,
- int ospeed, tcflag_t cflag)
+ int ospeed, tcflag_t cflag, const struct exynos_uart_config *conf)
{
struct exynos_uart_softc *sc = &exynos_uart_cnsc;
@@ -322,6 +360,7 @@
sc->sc_bsh = bsh;
sc->sc_ospeed = ospeed;
sc->sc_cflag = cflag;
+ sc->sc_conf = conf;
}
static int
@@ -330,6 +369,7 @@
struct exynos_uart_softc *sc =
device_lookup_private(&exuart_cd, minor(dev));
struct tty *tp = sc->sc_tty;
+ uint32_t ucon;
if (kauth_authorize_device_tty(l->l_cred,
KAUTH_DEVICE_TTY_OPEN, tp) != 0) {
@@ -356,7 +396,16 @@
tp->t_state |= TS_CARR_ON;
/* Enable RX and error interrupts */
- WR4(sc, SSCOM_UINTM, ~0u & ~(UINT_RXD|UINT_ERROR));
+ switch (sc->sc_conf->type) {
+ case EXYNOS_UART_SAMSUNG:
+ WR4(sc, SSCOM_UINTM, ~0u & ~(UINT_RXD|UINT_ERROR));
+ break;
+ case EXYNOS_UART_APPLE:
+ ucon = RD4(sc, SSCOM_UCON);
+ ucon |= UCON_S5L_RXTHRESH | UCON_S5L_RX_TIMEOUT;
+ WR4(sc, SSCOM_UCON, ucon);
+ break;
+ }
mutex_exit(&sc->sc_lock);
@@ -369,6 +418,7 @@
struct exynos_uart_softc *sc =
device_lookup_private(&exuart_cd, minor(dev));
struct tty *tp = sc->sc_tty;
+ uint32_t ucon;
mutex_enter(&sc->sc_lock);
@@ -376,7 +426,16 @@
ttyclose(tp);
/* Disable interrupts */
- WR4(sc, SSCOM_UINTM, ~0u);
+ switch (sc->sc_conf->type) {
+ case EXYNOS_UART_SAMSUNG:
+ WR4(sc, SSCOM_UINTM, ~0u);
+ break;
+ case EXYNOS_UART_APPLE:
+ ucon = RD4(sc, SSCOM_UCON);
+ ucon &= ~(UCON_S5L_RXTHRESH | UCON_S5L_RX_TIMEOUT);
+ WR4(sc, SSCOM_UCON, ucon);
+ break;
+ }
mutex_exit(&sc->sc_lock);
@@ -460,11 +519,10 @@
for (brem = q_to_b(&tp->t_outq, sc->sc_buf, sizeof(sc->sc_buf));
brem > 0;
brem--, p++) {
- while ((RD4(sc, SSCOM_UFSTAT) & UFSTAT_TXFULL) != 0)
+ while ((RD4(sc, SSCOM_UFSTAT) & sc->sc_conf->txfull) != 0)
;
- bus_space_write_1(sc->sc_bst, sc->sc_bsh,
- SSCOM_UTXH, *p);
+ WR4(sc, SSCOM_UTXH, *p);
}
tp->t_state &= ~TS_BUSY;
@@ -533,11 +591,15 @@
{
struct exynos_uart_softc *sc = priv;
struct tty *tp = sc->sc_tty;
- uint32_t uintp, uerstat, ufstat, c;
+ uint32_t ack, uerstat, ufstat, c;
mutex_enter(&sc->sc_lock);
- uintp = RD4(sc, SSCOM_UINTP);
+ if (sc->sc_conf->type == EXYNOS_UART_APPLE) {
+ ack = RD4(sc, SSCOM_UTRSTAT);
+ } else {
+ ack = RD4(sc, SSCOM_UINTP);
+ }
for (;;) {
int cn_trapped = 0;
@@ -551,18 +613,22 @@
}
ufstat = RD4(sc, SSCOM_UFSTAT);
- if (__SHIFTOUT(ufstat, UFSTAT_RXCOUNT) == 0) {
+ if (__SHIFTOUT(ufstat, sc->sc_conf->rxcount) == 0) {
break;
}
- c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, SSCOM_URXH);
+ c = RD4(sc, SSCOM_URXH);
cn_check_magic(tp->t_dev, c & 0xff, exynos_uart_cnm_state);
if (cn_trapped)
continue;
tp->t_linesw->l_rint(c & 0xff, tp);
}
- WR4(sc, SSCOM_UINTP, uintp);
+ if (sc->sc_conf->type == EXYNOS_UART_APPLE) {
+ WR4(sc, SSCOM_UTRSTAT, ack);
+ } else {
+ WR4(sc, SSCOM_UINTP, ack);
+ }
mutex_exit(&sc->sc_lock);
@@ -589,11 +655,13 @@
bus_size_t size;
tcflag_t flags;
int speed;
+ const struct exynos_uart_config *conf;
speed = fdtbus_get_stdout_speed();
if (speed < 0)
speed = 115200; /* default */
flags = fdtbus_get_stdout_flags();
+ conf = of_compatible_lookup(phandle, compat_data)->data;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0)
panic("exynos_uart: couldn't get registers");
@@ -602,7 +670,7 @@
exynos_uart_consaddr = addr;
Home |
Main Index |
Thread Index |
Old Index