Page MenuHomeFreeBSD

D33033.id98638.diff
No OneTemporary

D33033.id98638.diff

Index: sys/amd64/conf/GENERIC
===================================================================
--- sys/amd64/conf/GENERIC
+++ sys/amd64/conf/GENERIC
@@ -240,6 +240,7 @@
# Serial (COM) ports
device uart # Generic UART driver
+device intellpss # Intel Low Power SubSystem
# Parallel port
device ppc
Index: sys/conf/files.x86
===================================================================
--- sys/conf/files.x86
+++ sys/conf/files.x86
@@ -144,6 +144,8 @@
dev/imcsmb/imcsmb.c optional imcsmb
dev/imcsmb/imcsmb_pci.c optional imcsmb pci
dev/intel/spi.c optional intelspi
+dev/intel/lpss.c optional intellpss
+dev/uart/uart_dev_lpss_pci.c optional uart pci intellpss
dev/io/iodev.c optional io
dev/iommu/busdma_iommu.c optional acpi iommu pci
dev/iommu/iommu_gas.c optional acpi iommu pci
Index: sys/dev/intel/lpss.h
===================================================================
--- /dev/null
+++ sys/dev/intel/lpss.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _LPSS_H_
+#define _LPSS_H_
+
+enum lpss_type {
+ LPSS_TYPE_I2C = 0x0,
+ LPSS_TYPE_UART,
+ LPSS_TYPE_SPI,
+};
+
+#define LPSS_REGS_BASE 0x200
+#define LPSS_REGS_SIZE 0x100
+#define LPSS_REGS_NUM (LPSS_REGS_SIZE / sizeof(uint32_t))
+
+struct lpss_softc {
+ device_t dev;
+ struct resource *res;
+ uint64_t base_freq;
+ uint64_t freq;
+ enum lpss_type type;
+ uint32_t regs[LPSS_REGS_NUM];
+};
+
+uint64_t lpss_get_freq(struct lpss_softc *sc);
+int lpss_attach_uart(struct lpss_softc *sc);
+int lpss_resume(struct lpss_softc *sc);
+int lpss_suspend(struct lpss_softc *sc);
+
+#endif /* _LPSS_H_ */
Index: sys/dev/intel/lpss.c
===================================================================
--- /dev/null
+++ sys/dev/intel/lpss.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+
+#include <dev/intel/lpss.h>
+#include <dev/intel/lpssreg.h>
+
+static void
+lpss_get_type(struct lpss_softc *sc)
+{
+
+ sc->type = bus_read_4(sc->res, LPSS_CAPS);
+ sc->type = (sc->type >> LPSS_CAPS_TYPE_SHIFT) & LPSS_CAPS_TYPE_MASK;
+}
+
+static void
+lpss_remap(struct lpss_softc *sc)
+{
+
+ bus_write_4(sc->res, LPSS_REMAP_ADDR,
+ rman_get_start(sc->res));
+}
+
+static void
+lpss_reset(struct lpss_softc *sc)
+{
+
+ bus_write_4(sc->res, LPSS_RESET, 0);
+ bus_write_4(sc->res, LPSS_RESET,
+ LPSS_RESET_FUNC | LPSS_RESET_IDMA);
+}
+
+uint64_t
+lpss_get_freq(struct lpss_softc *sc)
+{
+ uint64_t freq, m, n;
+ uint32_t reg;
+
+ reg = bus_read_4(sc->res, LPSS_CLK);
+
+ freq = sc->base_freq;
+ m = (reg >> LPSS_CLK_MSHIFT) & LPSS_CLK_MMASK;
+ n = (reg >> LPSS_CLK_NSHIFT) & LPSS_CLK_NMASK;
+ if (m != 0 && n != 0) {
+ freq *= m;
+ freq /= n;
+ }
+
+ return (freq);
+}
+
+int
+lpss_attach_uart(struct lpss_softc *sc)
+{
+
+ lpss_get_type(sc);
+ if (sc->type != LPSS_TYPE_UART) {
+ device_printf(sc->dev, "Not a UART\n");
+ return (ENXIO);
+ }
+
+ lpss_reset(sc);
+ lpss_remap(sc);
+
+ return (0);
+}
+
+int
+lpss_resume(struct lpss_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < LPSS_REGS_NUM; i++)
+ bus_write_4(sc->res, LPSS_REGS_BASE + i * sizeof(uint32_t),
+ sc->regs[i]);
+ return (0);
+}
+
+int
+lpss_suspend(struct lpss_softc *sc)
+{
+ int i;
+
+ for (i = 0; i < LPSS_REGS_NUM; i++)
+ sc->regs[i] = bus_read_4(sc->res,
+ LPSS_REGS_BASE + i * sizeof(uint32_t));
+ return (0);
+}
Index: sys/dev/intel/lpssreg.h
===================================================================
--- /dev/null
+++ sys/dev/intel/lpssreg.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _LPSSREG_H_
+#define _LPSSREG_H_
+
+#define LPSS_CLK 0x200
+#define LPSS_CLK_MSHIFT 1
+#define LPSS_CLK_MMASK 0x3FFF
+#define LPSS_CLK_NSHIFT 16
+#define LPSS_CLK_NMASK 0x3FFF
+
+#define LPSS_RESET 0x204
+#define LPSS_RESET_FUNC (3 << 0)
+#define LPSS_RESET_IDMA (1 << 2)
+
+#define LPSS_REMAP_ADDR 0x240
+
+#define LPSS_CAPS 0x2FC
+#define LPSS_CAPS_TYPE_SHIFT 4
+#define LPSS_CAPS_TYPE_MASK 0xF
+#define LPSS_CAPS_NO_IDMA (1 << 8)
+
+#endif /* _LPSSREG_H_ */
+
Index: sys/dev/uart/uart_bus_pci.c
===================================================================
--- sys/dev/uart/uart_bus_pci.c
+++ sys/dev/uart/uart_bus_pci.c
@@ -149,24 +149,8 @@
{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 },
{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 },
{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 },
-{ 0x8086, 0x31bc, 0xffff, 0, "Intel Gemini Lake SIO/LPSS UART 0", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x31be, 0xffff, 0, "Intel Gemini Lake SIO/LPSS UART 1", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x31c0, 0xffff, 0, "Intel Gemini Lake SIO/LPSS UART 2", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x31ee, 0xffff, 0, "Intel Gemini Lake SIO/LPSS UART 3", 0x10,
- 24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller",
0x10 },
-{ 0x8086, 0x5abc, 0xffff, 0, "Intel Apollo Lake SIO/LPSS UART 0", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x5abe, 0xffff, 0, "Intel Apollo Lake SIO/LPSS UART 1", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x5ac0, 0xffff, 0, "Intel Apollo Lake SIO/LPSS UART 2", 0x10,
- 24 * DEFAULT_RCLK, 2 },
-{ 0x8086, 0x5aee, 0xffff, 0, "Intel Apollo Lake SIO/LPSS UART 3", 0x10,
- 24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 },
{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 },
{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 },
Index: sys/dev/uart/uart_dev_lpss_pci.c
===================================================================
--- /dev/null
+++ sys/dev/uart/uart_dev_lpss_pci.c
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_ns8250.h>
+
+#include <dev/intel/lpss.h>
+
+#include "uart_if.h"
+
+struct uart_lpss_softc {
+ struct ns8250_softc ns8250;
+ struct lpss_softc lpss;
+};
+
+static kobj_method_t uart_lpss_ns8250_methods[] = {
+ KOBJMETHOD(uart_probe, ns8250_bus_probe),
+ KOBJMETHOD(uart_attach, ns8250_bus_attach),
+ KOBJMETHOD(uart_detach, ns8250_bus_detach),
+ KOBJMETHOD(uart_flush, ns8250_bus_flush),
+ KOBJMETHOD(uart_getsig, ns8250_bus_getsig),
+ KOBJMETHOD(uart_ioctl, ns8250_bus_ioctl),
+ KOBJMETHOD(uart_ipend, ns8250_bus_ipend),
+ KOBJMETHOD(uart_param, ns8250_bus_param),
+ KOBJMETHOD(uart_receive, ns8250_bus_receive),
+ KOBJMETHOD(uart_setsig, ns8250_bus_setsig),
+ KOBJMETHOD(uart_transmit, ns8250_bus_transmit),
+ KOBJMETHOD(uart_grab, ns8250_bus_grab),
+ KOBJMETHOD(uart_ungrab, ns8250_bus_ungrab),
+ KOBJMETHOD_END
+};
+
+struct uart_class uart_lpss_class = {
+ "lpss",
+ uart_lpss_ns8250_methods,
+ sizeof(struct lpss_softc),
+ .uc_ops = &uart_ns8250_ops,
+ .uc_range = 8,
+ .uc_rclk = 1843200,
+ .uc_rshift = 2,
+ .uc_riowidth = 4,
+};
+
+struct pci_id {
+ uint16_t vendor;
+ uint16_t device;
+ const char *desc;
+ uint64_t base_freq;
+};
+
+static const struct pci_id uart_lpss_ids[] = {
+ { 0x8086, 0x31bc, "Intel Gemini Lake SIO/LPSS UART 0", 100000000},
+ { 0x8086, 0x31be, "Intel Gemini Lake SIO/LPSS UART 1", 100000000},
+ { 0x8086, 0x31c0, "Intel Gemini Lake SIO/LPSS UART 2", 100000000},
+ { 0x8086, 0x31ee, "Intel Gemini Lake SIO/LPSS UART 3", 100000000},
+ { 0x8086, 0x5abc, "Intel Apollo Lake SIO/LPSS UART 0", 100000000},
+ { 0x8086, 0x5abe, "Intel Apollo Lake SIO/LPSS UART 1", 100000000},
+ { 0x8086, 0x5ac0, "Intel Apollo Lake SIO/LPSS UART 2", 100000000},
+ { 0x8086, 0x5aee, "Intel Apollo Lake SIO/LPSS UART 3", 100000000},
+ { 0xffff, 0, NULL}
+};
+
+static int
+uart_lpss_probe(device_t dev)
+{
+ struct uart_lpss_softc *sc;
+ uint64_t freq;
+ uint16_t device, vendor;
+ int error, i, rid;
+
+ sc = device_get_softc(dev);
+ vendor = pci_get_vendor(dev);
+ device = pci_get_device(dev);
+ for (i = 0; i < nitems(uart_lpss_ids) - 1; i++) {
+ if (vendor == uart_lpss_ids[i].vendor &&
+ device == uart_lpss_ids[i].device)
+ break;
+ }
+ if (uart_lpss_ids[i].vendor == 0xffff)
+ return (ENXIO);
+ sc->ns8250.base.sc_class = &uart_lpss_class;
+ rid = 0x10;
+ sc->lpss.dev = dev;
+ sc->lpss.base_freq = uart_lpss_ids[i].base_freq;
+ sc->lpss.res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &rid, RF_ACTIVE);
+ freq = lpss_get_freq(&sc->lpss);
+ bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lpss.res);
+ error = uart_bus_probe(dev, 2, 4, (int)freq, rid, 0, 0);
+ if (error != 0)
+ return (error);
+ device_set_desc(dev, uart_lpss_ids[i].desc);
+ return (0);
+}
+
+static int
+uart_lpss_attach(device_t dev)
+{
+ struct uart_lpss_softc *sc;
+ int count, error;
+
+ sc = device_get_softc(dev);
+
+ if (pci_msi_count(dev) == 1) {
+ if (pci_alloc_msi(dev, &count) == 0) {
+ sc->ns8250.base.sc_irid = 1;
+ if (bootverbose)
+ device_printf(dev, "Using %d MSI message\n", count);
+ }
+ }
+ sc->lpss.dev = dev;
+ sc->lpss.res = sc->ns8250.base.sc_rres;
+ error = lpss_attach_uart(&sc->lpss);
+ if (error != 0) {
+ pci_release_msi(dev);
+ return (error);
+ }
+ return (uart_bus_attach(dev));
+}
+
+static int
+uart_lpss_detach(device_t dev)
+{
+
+ return (uart_bus_detach(dev));
+}
+
+static int
+uart_lpss_resume(device_t dev)
+{
+ struct uart_lpss_softc *sc;
+
+ sc = device_get_softc(dev);
+ lpss_resume(&sc->lpss);
+ return (uart_bus_resume(dev));
+}
+
+static int
+uart_lpss_suspend(device_t dev)
+{
+ struct uart_lpss_softc *sc;
+
+ sc = device_get_softc(dev);
+ lpss_suspend(&sc->lpss);
+ return (0);
+}
+
+static device_method_t uart_lpss_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uart_lpss_probe),
+ DEVMETHOD(device_attach, uart_lpss_attach),
+ DEVMETHOD(device_detach, uart_lpss_detach),
+ DEVMETHOD(device_resume, uart_lpss_resume),
+ DEVMETHOD(device_suspend, uart_lpss_suspend),
+ DEVMETHOD_END
+};
+
+static driver_t uart_lpss_driver = {
+ uart_driver_name,
+ uart_lpss_methods,
+ sizeof(struct uart_lpss_softc)
+};
+
+DRIVER_MODULE(uart_lpss, pci, uart_lpss_driver, uart_devclass, 0, 0);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 29, 8:29 PM (4 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17845707
Default Alt Text
D33033.id98638.diff (15 KB)

Event Timeline