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 FIFOs and hardware flow-control to ...



details:   https://anonhg.NetBSD.org/src/rev/bb13ed154281
branches:  trunk
changeset: 373210:bb13ed154281
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue Jan 24 06:56:40 2023 +0000

description:
Add support for FIFOs and hardware flow-control to plcom driver.
Add a PLCOM_TYPE_GENERIC_UART variant to match SBSA requirements.

diffstat:

 sys/arch/arm/acpi/acpi_platform.c |    9 +-
 sys/arch/arm/acpi/plcom_acpi.c    |   32 ++++-
 sys/arch/arm/fdt/plcom_fdt.c      |   16 ++-
 sys/arch/evbarm/dev/plcom.c       |  200 +++++++++++++++++++++++++++++++------
 sys/arch/evbarm/dev/plcomreg.h    |   11 +-
 sys/arch/evbarm/dev/plcomvar.h    |   12 +-
 6 files changed, 225 insertions(+), 55 deletions(-)

diffs (truncated from 794 to 300 lines):

diff -r 84aec533394f -r bb13ed154281 sys/arch/arm/acpi/acpi_platform.c
--- a/sys/arch/arm/acpi/acpi_platform.c Tue Jan 24 00:24:02 2023 +0000
+++ b/sys/arch/arm/acpi/acpi_platform.c Tue Jan 24 06:56:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_platform.c,v 1.34 2022/11/16 11:54:26 skrll Exp $ */
+/* $NetBSD: acpi_platform.c,v 1.35 2023/01/24 06:56:40 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.34 2022/11/16 11:54:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.35 2023/01/24 06:56:40 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -188,7 +188,10 @@
        case ACPI_DBG2_ARM_PL011:
        case ACPI_DBG2_ARM_SBSA_32BIT:
        case ACPI_DBG2_ARM_SBSA_GENERIC:
-               plcom_console.pi_type = PLCOM_TYPE_PL011;
+               if (spcr->InterfaceType == ACPI_DBG2_ARM_PL011)
+                       plcom_console.pi_type = PLCOM_TYPE_PL011;
+               else
+                       plcom_console.pi_type = PLCOM_TYPE_GENERIC_UART;
                plcom_console.pi_iot = &arm_generic_bs_tag;
                plcom_console.pi_iobase = le64toh(spcr->SerialPort.Address);
                plcom_console.pi_size = PL011COM_UART_SIZE;
diff -r 84aec533394f -r bb13ed154281 sys/arch/arm/acpi/plcom_acpi.c
--- a/sys/arch/arm/acpi/plcom_acpi.c    Tue Jan 24 00:24:02 2023 +0000
+++ b/sys/arch/arm/acpi/plcom_acpi.c    Tue Jan 24 06:56:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: plcom_acpi.c,v 1.3 2020/04/25 21:34:26 jmcneill Exp $ */
+/* $NetBSD: plcom_acpi.c,v 1.4 2023/01/24 06:56:40 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom_acpi.c,v 1.3 2020/04/25 21:34:26 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom_acpi.c,v 1.4 2023/01/24 06:56:40 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,9 +50,17 @@
 
 CFATTACH_DECL_NEW(plcom_acpi, sizeof(struct plcom_softc), plcom_acpi_match, plcom_acpi_attach, NULL, NULL);
 
-static const char * const compatible[] = {
-       "ARMH0011",
-       NULL
+enum plcom_acpi_variant {
+       PLCOM_ACPI_GENERIC,
+       PLCOM_ACPI_PL011,
+       PLCOM_ACPI_BCM2837
+};
+
+static const struct device_compatible_entry compat_data[] = {
+       { .compat = "BCM2837",          .value = PLCOM_ACPI_BCM2837 },
+       { .compat = "ARMH0011",         .value = PLCOM_ACPI_PL011 },
+       { .compat = "ARMHB000",         .value = PLCOM_ACPI_GENERIC },
+       DEVICE_COMPAT_EOL
 };
 
 static int
@@ -63,7 +71,7 @@
        if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
                return 0;
 
-       return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
+       return acpi_compatible_match(aa, compat_data);
 }
 
 static void
@@ -98,9 +106,19 @@
 
        sc->sc_hwflags = 0;
        sc->sc_swflags = 0;
-
+       sc->sc_fifolen = 0;
        sc->sc_pi.pi_type = PLCOM_TYPE_PL011;
        sc->sc_pi.pi_flags = PLC_FLAG_32BIT_ACCESS;
+
+       switch (acpi_compatible_lookup(aa, compat_data)->value) {
+       case PLCOM_ACPI_BCM2837:
+               sc->sc_fifolen = 16;
+               break;
+       case PLCOM_ACPI_GENERIC:
+               sc->sc_pi.pi_type = PLCOM_TYPE_GENERIC_UART;
+               break;
+       }
+
        sc->sc_pi.pi_iot = aa->aa_memt;
        sc->sc_pi.pi_iobase = mem->ar_base;
        if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0, &sc->sc_pi.pi_ioh) != 0) {
diff -r 84aec533394f -r bb13ed154281 sys/arch/arm/fdt/plcom_fdt.c
--- a/sys/arch/arm/fdt/plcom_fdt.c      Tue Jan 24 00:24:02 2023 +0000
+++ b/sys/arch/arm/fdt/plcom_fdt.c      Tue Jan 24 06:56:40 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: plcom_fdt.c,v 1.5 2021/01/27 03:10:19 thorpej Exp $ */
+/* $NetBSD: plcom_fdt.c,v 1.6 2023/01/24 06:56:40 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom_fdt.c,v 1.5 2021/01/27 03:10:19 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom_fdt.c,v 1.6 2023/01/24 06:56:40 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,7 +44,8 @@
 static void    plcom_fdt_attach(device_t, device_t, void *);
 
 static const struct device_compatible_entry compat_data[] = {
-       { .compat = "arm,pl011" },
+       { .compat = "arm,pl011", .value = PLCOM_TYPE_PL011 },
+       { .compat = "arm,sbsa-uart", .value = PLCOM_TYPE_GENERIC_UART },
        DEVICE_COMPAT_EOL
 };
 
@@ -70,6 +71,8 @@
        bus_addr_t addr;
        bus_size_t size;
        void *ih;
+       const u_int *data;
+       int len;
 
        if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
                aprint_error(": missing 'reg' property\n");
@@ -94,10 +97,13 @@
                        sc->sc_frequency = clk_get_rate(clk);
        }
 
-       sc->sc_hwflags = PLCOM_HW_TXFIFO_DISABLE;
+       sc->sc_hwflags = 0;
        sc->sc_swflags = 0;
 
-       sc->sc_pi.pi_type = PLCOM_TYPE_PL011;
+       if ((data = fdtbus_get_prop(phandle, "arm,primecell-periphid", &len)) != NULL)
+                sc->sc_pi.pi_periphid = be32toh(data[0]);
+
+       sc->sc_pi.pi_type = of_compatible_lookup(faa->faa_phandle, compat_data)->value;
        sc->sc_pi.pi_flags = PLC_FLAG_32BIT_ACCESS;
        sc->sc_pi.pi_iot = faa->faa_bst;
        sc->sc_pi.pi_iobase = addr;
diff -r 84aec533394f -r bb13ed154281 sys/arch/evbarm/dev/plcom.c
--- a/sys/arch/evbarm/dev/plcom.c       Tue Jan 24 00:24:02 2023 +0000
+++ b/sys/arch/evbarm/dev/plcom.c       Tue Jan 24 06:56:40 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: plcom.c,v 1.66 2022/10/26 23:38:07 riastradh Exp $     */
+/*     $NetBSD: plcom.c,v 1.67 2023/01/24 06:56:40 mlelstv Exp $       */
 
 /*-
  * Copyright (c) 2001 ARM Ltd
@@ -94,7 +94,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.66 2022/10/26 23:38:07 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.67 2023/01/24 06:56:40 mlelstv Exp $");
 
 #include "opt_plcom.h"
 #include "opt_kgdb.h"
@@ -149,7 +149,7 @@
 void   plcom_shutdown  (struct plcom_softc *);
 int    pl010comspeed   (long, long);
 int    pl011comspeed   (long, long);
-static u_char  cflag2lcr (tcflag_t);
+static uint32_t        cflag2lcr (tcflag_t);
 int    plcomparam      (struct tty *, struct termios *);
 void   plcomstart      (struct tty *);
 int    plcomhwiflow    (struct tty *, int);
@@ -267,7 +267,17 @@
        return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >>
            (8 * (reg & 3));
 }
-int nhcr;
+
+static uint16_t
+pread2(struct plcom_instance *pi, bus_size_t reg)
+{
+       if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS))
+               return bus_space_read_2(pi->pi_iot, pi->pi_ioh, reg);
+
+       return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >>
+           (8 * (reg & 3));
+}
+
 static void
 pwrite1(struct plcom_instance *pi, bus_size_t o, uint8_t val)
 {
@@ -283,6 +293,20 @@
 }
 
 static void
+pwrite2(struct plcom_instance *pi, bus_size_t o, uint16_t val)
+{
+       if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) {
+               bus_space_write_2(pi->pi_iot, pi->pi_ioh, o, val);
+       } else {
+               const size_t shift = 8 * (o & 3);
+               o &= -4;
+               uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o);
+               tmp = (val << shift) | (tmp & ~(0xffff << shift));
+               bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp);
+       }
+}
+
+static void
 pwritem1(struct plcom_instance *pi, bus_size_t o, const uint8_t *datap,
     bus_size_t count)
 {
@@ -297,11 +321,13 @@
 }
 
 #define        PREAD1(pi, reg)         pread1(pi, reg)
+#define        PREAD2(pi, reg)         pread2(pi, reg)
 #define        PREAD4(pi, reg)         \
        bus_space_read_4((pi)->pi_iot, (pi)->pi_ioh, (reg))
 
 #define        PWRITE1(pi, reg, val)   pwrite1(pi, reg, val)
 #define        PWRITEM1(pi, reg, d, c) pwritem1(pi, reg, d, c)
+#define        PWRITE2(pi, reg, val)   pwrite2(pi, reg, val)
 #define        PWRITE4(pi, reg, val)   \
        bus_space_write_4((pi)->pi_iot, (pi)->pi_ioh, (reg), (val))
 
@@ -381,14 +407,14 @@
        /* Disable the UART.  */
        bus_space_write_1(iot, ioh, plcom_cr, 0);
        /* Make sure the FIFO is off.  */
-       bus_space_write_1(iot, ioh, plcom_lcr, PL01X_LCR_8BITS);
+       bus_space_write_4(iot, ioh, plcom_lcr, PL01X_LCR_8BITS);
        /* Disable interrupts.  */
        bus_space_write_1(iot, ioh, plcom_iir, 0);
 
        /* Make sure we swallow anything in the receiving register.  */
        data = bus_space_read_1(iot, ioh, plcom_dr);
 
-       if (bus_space_read_1(iot, ioh, plcom_lcr) != PL01X_LCR_8BITS)
+       if (bus_space_read_4(iot, ioh, plcom_lcr) != PL01X_LCR_8BITS)
                return 0;
 
        data = bus_space_read_1(iot, ioh, plcom_fr) & (PL01X_FR_RXFF | PL01X_FR_RXFE);
@@ -424,10 +450,11 @@
                }
                break;
        case PLCOM_TYPE_PL011:
+       case PLCOM_TYPE_GENERIC_UART:
                sc->sc_imsc = PL011_INT_RX | PL011_INT_RT;
                SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
                SET(sc->sc_cr, PL011_MCR(sc->sc_mcr));
-               PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+               PWRITE2(pi, PL011COM_CR, sc->sc_cr);
                PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
                break;
        }
@@ -446,6 +473,7 @@
        switch (pi->pi_type) {
        case PLCOM_TYPE_PL010:
        case PLCOM_TYPE_PL011:
+       case PLCOM_TYPE_GENERIC_UART:
                break;
        default:
                aprint_error_dev(sc->sc_dev,
@@ -470,8 +498,24 @@
                 * hang when trying to print.
                 */
                sc->sc_cr = PL01X_CR_UARTEN;
-               if (pi->pi_type == PLCOM_TYPE_PL011)
+               switch (pi->pi_type) {
+               case PLCOM_TYPE_PL011:
+               case PLCOM_TYPE_GENERIC_UART:
                        SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+                       break;
+               }
+       }
+
+       switch (pi->pi_type) {
+       case PLCOM_TYPE_PL011:
+               if (pi->pi_periphid == 0) {
+                       pi->pi_periphid = PREAD1(pi, PL011COM_PID0) << 0
+                               | PREAD1(pi, PL011COM_PID1) << 8
+                               | PREAD1(pi, PL011COM_PID2) << 16
+                               | PREAD1(pi, PL011COM_PID3) << 24;
+               }
+               aprint_debug_dev(sc->sc_dev, "PID %08x\n", pi->pi_periphid);
+               break;
        }
 
        switch (pi->pi_type) {
@@ -480,7 +524,8 @@
                break;
 



Home | Main Index | Thread Index | Old Index