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"