Module Name: src
Committed By: jmcneill
Date: Mon Sep 13 23:31:23 UTC 2021
Modified Files:
src/sys/arch/arm/samsung: exynos_uart.c sscom_reg.h
src/sys/arch/evbarm/conf: GENERIC64 files.generic64
Log Message:
Add support for Apple M1 debug UART.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/samsung/exynos_uart.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/samsung/sscom_reg.h
cvs rdiff -u -r1.184 -r1.185 src/sys/arch/evbarm/conf/GENERIC64
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/evbarm/conf/files.generic64
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/samsung/exynos_uart.c
diff -u src/sys/arch/arm/samsung/exynos_uart.c:1.5 src/sys/arch/arm/samsung/exynos_uart.c:1.6
--- src/sys/arch/arm/samsung/exynos_uart.c:1.5 Sun Mar 14 08:16:57 2021
+++ src/sys/arch/arm/samsung/exynos_uart.c Mon Sep 13 23:31:23 2021
@@ -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 @@ static int exynos_uart_param(struct tty
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 @@ struct exynos_uart_softc {
int sc_ospeed;
tcflag_t sc_cflag;
+ const struct exynos_uart_config *sc_conf;
+
u_char sc_buf[1024];
};
@@ -135,8 +149,23 @@ const struct cdevsw exuart_cdevsw = {
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 @@ exynos_uart_attach(device_t parent, devi
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 @@ exynos_uart_attach(device_t parent, devi
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 @@ exynos_uart_attach(device_t parent, devi
__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);
- /* Disable interrupts */
- WR4(sc, SSCOM_UINTM, ~0u);
+ /* Configure PIO mode with RX timeout interrupts */
+ ucon = UCON_TOINT | UCON_ERRINT |
+ UCON_TXMODE_INT | UCON_RXMODE_INT;
+ WR4(sc, SSCOM_UCON, ucon);
+
+ 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 @@ exynos_uart_cngetc(dev_t dev)
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 @@ exynos_uart_cnputc(dev_t dev, int c)
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 @@ exynos_uart_cnpollc(dev_t dev, int on)
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 @@ exynos_uart_cnattach(bus_space_tag_t bst
sc->sc_bsh = bsh;
sc->sc_ospeed = ospeed;
sc->sc_cflag = cflag;
+ sc->sc_conf = conf;
}
static int
@@ -330,6 +369,7 @@ exynos_uart_open(dev_t dev, int flag, in
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 @@ exynos_uart_open(dev_t dev, int flag, in
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 @@ exynos_uart_close(dev_t dev, int flag, i
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 @@ exynos_uart_close(dev_t dev, int flag, i
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 @@ exynos_uart_start(struct tty *tp)
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 @@ exynos_uart_intr(void *priv)
{
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 @@ exynos_uart_intr(void *priv)
}
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 @@ exynos_uart_console_consinit(struct fdt_
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_console_consinit(struct fdt_
exynos_uart_consaddr = addr;
- exynos_uart_cnattach(bst, bsh, speed, flags);
+ exynos_uart_cnattach(bst, bsh, speed, flags, conf);
}
static const struct fdt_console exynos_uart_console = {
Index: src/sys/arch/arm/samsung/sscom_reg.h
diff -u src/sys/arch/arm/samsung/sscom_reg.h:1.3 src/sys/arch/arm/samsung/sscom_reg.h:1.4
--- src/sys/arch/arm/samsung/sscom_reg.h:1.3 Thu Jul 5 13:11:58 2018
+++ src/sys/arch/arm/samsung/sscom_reg.h Mon Sep 13 23:31:23 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sscom_reg.h,v 1.3 2018/07/05 13:11:58 jmcneill Exp $ */
+/* $NetBSD: sscom_reg.h,v 1.4 2021/09/13 23:31:23 jmcneill Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@@ -66,11 +66,14 @@
#define UCON_RXDMA_BRST_8 __SHIFTIN(2, UCON_RXDMA)
#define UCON_RXDMA_BRST_16 __SHIFTIN(3, UCON_RXDMA)
#define UCON_RXTO __BITS(15,12)
+#define UCON_S5L_TXTHRESH __BIT(13) /* Apple specific */
+#define UCON_S5L_RXTHRESH __BIT(12) /* Apple specific */
#define UCON_RXTO_FIFO_EMPTY __BIT(11)
#define UCON_RXTO_DMA_FSM_STOP __BIT(10)
#define UCON_TXINT_TYPE __BIT(9) /* Tx interrupt. 0=pulse,1=level */
#define UCON_TXINT_TYPE_LEVEL UCON_TXINT_TYPE /* 4412 mandatory */
#define UCON_TXINT_TYPE_PULSE 0
+#define UCON_S5L_RX_TIMEOUT __BIT(9) /* Apple specific */
#define UCON_RXINT_TYPE __BIT(8) /* Rx interrupt */
#define UCON_RXINT_TYPE_LEVEL UCON_RXINT_TYPE /* 4412 mandatory */
#define UCON_RXINT_TYPE_PULSE __SHIFTIN(0,UCON_RXINT_TYPE)
@@ -103,6 +106,9 @@
#define UTRSTAT_RXFIFOCNT __BITS(23,16)
#define UTRSTAT_TXDMA_FSM __BITS(15,12)
#define UTRSTAT_RXDMA_FSM __BITS(11,8)
+#define UTRSTAT_S5L_RX_TIMEOUT __BIT(9) /* Apple specific */
+#define UTRSTAT_S5L_TXTHRESH __BIT(5) /* Apple specific */
+#define UTRSTAT_S5L_RXTHRESH __BIT(4) /* Apple specific */
#define UTRSTAT_RXTIMEOUT __BIT(3)
#define UTRSTAT_TXSHIFTER_EMPTY __BIT(2)
#define UTRSTAT_TXEMPTY __BIT(1) /* TX fifo or buffer empty */
@@ -117,8 +123,11 @@
#define UFSTAT_TXFULL __BIT(24) /* Tx fifo full */
#define UFSTAT_TXCOUNT __BITS(23,16) /* TX FIFO count */
#define UFSTAT_RXERROR __BIT(9)
+#define UFSTAT_S5L_TXFULL __BIT(9) /* Tx fifo full (Apple) */
#define UFSTAT_RXFULL __BIT(8) /* Rx fifo full */
+#define UFSTAT_S5L_RXFULL __BIT(8) /* Rx fifo full (Apple) */
#define UFSTAT_RXCOUNT __BITS(7,0) /* RX FIFO count */
+#define UFSTAT_S5L_RXCOUNT __BITS(3,0) /* RX FIFO count (Apple) */
#define SSCOM_UMSTAT 0x1c /* Modem status register */
#define UMSTAT_DCTS __BIT(4)
#define UMSTAT_CTS __BIT(0) /* Clear to send */
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.184 src/sys/arch/evbarm/conf/GENERIC64:1.185
--- src/sys/arch/evbarm/conf/GENERIC64:1.184 Tue Sep 7 10:09:34 2021
+++ src/sys/arch/evbarm/conf/GENERIC64 Mon Sep 13 23:31:23 2021
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.184 2021/09/07 10:09:34 msaitoh Exp $
+# $NetBSD: GENERIC64,v 1.185 2021/09/13 23:31:23 jmcneill Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -307,6 +307,7 @@ ukphy* at mii? phy ? # generic unknown
# UART
com* at fdt? pass 4 # UART
com* at acpi?
+exuart* at fdt? pass 4 # SSCOM UART
imxuart* at fdt? pass 4 # IMX UART
options IMXUARTCONSOLE
mesonuart* at fdt? pass 4 # Amlogic Meson UART
Index: src/sys/arch/evbarm/conf/files.generic64
diff -u src/sys/arch/evbarm/conf/files.generic64:1.18 src/sys/arch/evbarm/conf/files.generic64:1.19
--- src/sys/arch/evbarm/conf/files.generic64:1.18 Mon Aug 30 23:26:26 2021
+++ src/sys/arch/evbarm/conf/files.generic64 Mon Sep 13 23:31:23 2021
@@ -1,4 +1,4 @@
-# $NetBSD: files.generic64,v 1.18 2021/08/30 23:26:26 jmcneill Exp $
+# $NetBSD: files.generic64,v 1.19 2021/09/13 23:31:23 jmcneill Exp $
#
# A generic (aarch64) kernel configuration info
#
@@ -17,6 +17,7 @@ include "arch/arm/broadcom/files.bcm2835
include "arch/arm/nvidia/files.tegra"
include "arch/arm/nxp/files.imx"
include "arch/arm/rockchip/files.rockchip"
+include "arch/arm/samsung/files.exynos"
include "arch/arm/sunxi/files.sunxi"
include "arch/arm/virt/files.virt"
include "arch/arm/sociox/files.sociox"