From 8a5a677801bbe955af3dd26f684214dcc7e14b88 Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 17 Aug 2016 13:05:02 +0000 Subject: [PATCH] Replace sxiuart(4) with the mostly compatible com(4). The Synopsys DesignWare 8250 throws an interrupt if it detects a write to LCR while it was busy. Read the USR register to clear the interrupt so we don't get flooded. The sunxi machines also use a different frequency on the consoles. As we have no clock framework, especially not for early consoles, match on known Allwinner compatibles to set a known frequency. ok kettenis@ mglocker@ --- sys/arch/armv7/armv7/platform.c | 4 +-- sys/arch/armv7/conf/GENERIC | 4 +-- sys/arch/armv7/conf/RAMDISK | 4 +-- sys/arch/armv7/dev/com_fdt.c | 48 ++++++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/sys/arch/armv7/armv7/platform.c b/sys/arch/armv7/armv7/platform.c index 80ce5f1ad87..d37f283954b 100644 --- a/sys/arch/armv7/armv7/platform.c +++ b/sys/arch/armv7/armv7/platform.c @@ -1,4 +1,4 @@ -/* $OpenBSD: platform.c,v 1.11 2016/08/15 13:42:49 patrick Exp $ */ +/* $OpenBSD: platform.c,v 1.12 2016/08/17 13:05:02 patrick Exp $ */ /* * Copyright (c) 2014 Patrick Wildt * @@ -39,7 +39,6 @@ void agtimer_init(void); void exuart_init_cons(void); void imxuart_init_cons(void); void com_fdt_init_cons(void); -void sxiuart_init_cons(void); void pl011_init_cons(void); void bcmmuart_init_cons(void); @@ -107,7 +106,6 @@ platform_init_cons(void) exuart_init_cons(); imxuart_init_cons(); com_fdt_init_cons(); - sxiuart_init_cons(); pl011_init_cons(); bcmmuart_init_cons(); } diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC index 982bb53b3af..75be1291011 100644 --- a/sys/arch/armv7/conf/GENERIC +++ b/sys/arch/armv7/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.47 2016/08/14 19:08:44 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.48 2016/08/17 13:05:02 patrick Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -93,7 +93,7 @@ sxiccmu* at sunxi? # Clock Control Module/Unit sxitimer* at sunxi? sxidog* at fdt? # watchdog timer sxirtc* at fdt? # Real Time Clock -sxiuart* at fdt? # onboard UARTs +#sxiuart* at fdt? # onboard UARTs sxie* at fdt? dwge* at fdt? sxiahci* at fdt? # AHCI/SATA diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK index 4936f7e3ff1..2508c8ec9a1 100644 --- a/sys/arch/armv7/conf/RAMDISK +++ b/sys/arch/armv7/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.43 2016/08/13 22:07:01 kettenis Exp $ +# $OpenBSD: RAMDISK,v 1.44 2016/08/17 13:05:02 patrick Exp $ machine armv7 arm @@ -91,7 +91,7 @@ sxiccmu* at sunxi? # Clock Control Module/Unit sxitimer* at sunxi? sxidog* at fdt? # watchdog timer sxirtc* at fdt? # Real Time Clock -sxiuart* at fdt? # onboard UARTs +#sxiuart* at fdt? # onboard UARTs sxie* at fdt? dwge* at fdt? sxiahci* at fdt? # AHCI/SATA diff --git a/sys/arch/armv7/dev/com_fdt.c b/sys/arch/armv7/dev/com_fdt.c index 5ca649b8cfd..54ad0467338 100644 --- a/sys/arch/armv7/dev/com_fdt.c +++ b/sys/arch/armv7/dev/com_fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_fdt.c,v 1.3 2016/08/15 21:04:32 patrick Exp $ */ +/* $OpenBSD: com_fdt.c,v 1.4 2016/08/17 13:05:02 patrick Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. * All rights reserved. @@ -58,10 +58,12 @@ #define com_isr 8 #define ISR_RECV (ISR_RXPL | ISR_XMODE | ISR_RCVEIR) +#define com_usr 31 /* Synopsys DesignWare UART */ int com_fdt_match(struct device *, void *, void *); void com_fdt_attach(struct device *, struct device *, void *); int com_fdt_activate(struct device *, int); +int com_fdt_intr_designware(void *); extern int comcnspeed; extern int comcnmode; @@ -81,14 +83,23 @@ com_fdt_init_cons(void) { struct fdt_reg reg; void *node; + int freq = 48000000; - if ((node = fdt_find_cons("ti,omap3-uart")) == NULL) - if ((node = fdt_find_cons("ti,omap4-uart")) == NULL) + if ((node = fdt_find_cons("ti,omap3-uart")) == NULL && + (node = fdt_find_cons("ti,omap4-uart")) == NULL && + (node = fdt_find_cons("snps,dw-apb-uart")) == NULL) return; if (fdt_get_reg(node, 0, ®)) return; - comcnattach(&armv7_a4x_bs_tag, reg.addr, comcnspeed, 48000000, + if ((node = fdt_find_node("/")) != NULL && + (fdt_is_compatible(node, "allwinner,sun4i-a10") || + fdt_is_compatible(node, "allwinner,sun5i-a10s") || + fdt_is_compatible(node, "allwinner,sun5i-r8") || + fdt_is_compatible(node, "allwinner,sun7i-a20"))) + freq = 24000000; + + comcnattach(&armv7_a4x_bs_tag, reg.addr, comcnspeed, freq, comcnmode); comdefaultrate = comcnspeed; } @@ -99,7 +110,8 @@ com_fdt_match(struct device *parent, void *match, void *aux) struct fdt_attach_args *faa = aux; return (OF_is_compatible(faa->fa_node, "ti,omap3-uart") || - OF_is_compatible(faa->fa_node, "ti,omap4-uart")); + OF_is_compatible(faa->fa_node, "ti,omap4-uart") || + OF_is_compatible(faa->fa_node, "snps,dw-apb-uart")); } void @@ -107,6 +119,8 @@ com_fdt_attach(struct device *parent, struct device *self, void *aux) { struct com_fdt_softc *sc = (struct com_fdt_softc *)self; struct fdt_attach_args *faa = aux; + int (*intr)(void *) = comintr; + int node; if (faa->fa_nreg < 1) return; @@ -124,6 +138,18 @@ com_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_frequency = 48000000; sc->sc.sc_uarttype = COM_UART_TI16750; + if (OF_is_compatible(faa->fa_node, "snps,dw-apb-uart")) { + sc->sc.sc_uarttype = COM_UART_16550; + intr = com_fdt_intr_designware; + } + + if ((node = OF_finddevice("/")) != 0 && + (OF_is_compatible(node, "allwinner,sun4i-a10") || + OF_is_compatible(node, "allwinner,sun5i-a10s") || + OF_is_compatible(node, "allwinner,sun5i-r8") || + OF_is_compatible(node, "allwinner,sun7i-a20"))) + sc->sc.sc_frequency = 24000000; + if (stdout_node == faa->fa_node) { SET(sc->sc.sc_hwflags, COM_HW_CONSOLE); SET(sc->sc.sc_swflags, COM_SW_SOFTCAR); @@ -139,7 +165,7 @@ com_fdt_attach(struct device *parent, struct device *self, void *aux) com_attach_subr(&sc->sc); - (void)arm_intr_establish_fdt(faa->fa_node, IPL_TTY, comintr, + arm_intr_establish_fdt(faa->fa_node, IPL_TTY, intr, sc, sc->sc.sc_dev.dv_xname); } @@ -169,3 +195,13 @@ com_fdt_activate(struct device *self, int act) } return 0; } + +int +com_fdt_intr_designware(void *cookie) +{ + struct com_softc *sc = cookie; + + bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_usr); + + return comintr(sc); +} -- 2.20.1