Index | Thread | Search

From:
Gregory Norton <gregory.norton@me.com>
Subject:
Re: ispi_pci: enable support for 9-series pch
To:
tech@openbsd.org
Date:
Thu, 11 Jun 2026 10:13:33 -0400

Download raw body.

Thread
I knew I would miss something obvious.

Added the version type to the ispi_acpi variant as well in case we ever 
need to use it again from the ic/ispi code.
Also removed the redundant check for the version in attach.

- Greg


diff --git sys/dev/acpi/ispi_acpi.c sys/dev/acpi/ispi_acpi.c
index 2a648b2d4..cf1f38d3c 100644
--- sys/dev/acpi/ispi_acpi.c
+++ sys/dev/acpi/ispi_acpi.c
@@ -75,6 +75,7 @@ ispi_acpi_attach(struct device *parent, struct device 
*self, void *aux)

  	sc->sc_acpi = (struct acpi_softc *)parent;
  	sc->sc_devnode = aa->aaa_node;
+	sc->sc_vers = SPI_SUNRISEPOINT;
  	rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);

  	printf(": %s", sc->sc_devnode->name);
diff --git sys/dev/ic/ispivar.h sys/dev/ic/ispivar.h
index 6131616b5..8d44bda97 100644
--- sys/dev/ic/ispivar.h
+++ sys/dev/ic/ispivar.h
@@ -42,6 +42,13 @@
  #define DPRINTF(x)
  #endif

+enum ispi_version {
+	SPI_BAYTRAIL,
+	SPI_BRASWELL,
+	SPI_LYNXPOINT,
+	SPI_SUNRISEPOINT
+};
+
  struct ispi_softc {
  	struct device		sc_dev;

@@ -69,6 +76,7 @@ struct ispi_softc {
  	struct aml_node		*sc_devnode;
  #endif
  	u_int32_t		sc_caps;
+	enum ispi_version	sc_vers;
  };

  void		ispi_init(struct ispi_softc *sc);
diff --git sys/dev/pci/ispi_pci.c sys/dev/pci/ispi_pci.c
index c77e67180..852f2c9b7 100644
--- sys/dev/pci/ispi_pci.c
+++ sys/dev/pci/ispi_pci.c
@@ -44,6 +44,7 @@ const struct cfattach ispi_pci_ca = {
  };

  const struct pci_matchid ispi_pci_ids[] = {
+	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_9SERIES_LP_SPI },
  	{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3 },
  };

@@ -62,26 +63,34 @@ ispi_pci_attach(struct device *parent, struct device 
*self, void *aux)
  	pci_intr_handle_t ih;
  	const char *intrstr = NULL;
  	uint8_t type;
+	int mtype;

  	memcpy(&sc->sc_paa, pa, sizeof(sc->sc_paa));

  	pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);

-	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT, 0,
+	mtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
+	if (pci_mapreg_map(pa, PCI_MAPREG_START, mtype, 0,
  	    &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) {
  		printf(": can't map mem space\n");
  		return;
  	}

-	sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS);
-	type = (sc->sc_caps & LPSS_CAPS_TYPE_MASK) >> LPSS_CAPS_TYPE_SHIFT;
-	if (type != LPSS_CAPS_TYPE_SPI) {
-		printf(": type %d not supported\n", type);
-		return;
-	}
-
  	switch (PCI_PRODUCT(pa->pa_id)) {
+	case PCI_PRODUCT_INTEL_9SERIES_LP_SPI:
+		sc->sc_vers = SPI_LYNXPOINT;
+
+		/* SPT */
+		sc->sc_lpss_reg_offset = 0x800;
+		sc->sc_reg_cs_ctrl = 0x18;
+		sc->sc_rx_threshold = 2;
+		sc->sc_tx_threshold = 32;
+		sc->sc_tx_threshold_hi = 56;
+		sc->sc_ssp_clk = 9600000;
+		break;
  	case PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3:
+		sc->sc_vers = SPI_SUNRISEPOINT;
+
  		/* SPT */
  		sc->sc_lpss_reg_offset = 0x200;
  		sc->sc_reg_cs_ctrl = 0x24;
@@ -96,9 +105,26 @@ ispi_pci_attach(struct device *parent, struct device 
*self, void *aux)
  		return;
  	}

-	/* un-reset - page 958 */
-	bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
-	    (LPSS_RESETS_FUNC | LPSS_RESETS_IDMA));
+	sc->sc_caps = 0;
+	if (sc->sc_vers == SPI_SUNRISEPOINT) {
+		/*
+		 * sunrise point supports capability validation
+		 * and includes a dedicated reset register
+		 */
+
+		/* validate capabilities */
+		sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS);
+		type = (sc->sc_caps & LPSS_CAPS_TYPE_MASK) >> LPSS_CAPS_TYPE_SHIFT;
+		if (type != LPSS_CAPS_TYPE_SPI) {
+			printf(": type %d not supported\n", type);
+			bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
+			return;
+		}
+
+		/* un-reset - page 958 */
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
+			(LPSS_RESETS_FUNC | LPSS_RESETS_IDMA));
+	}

  	/* install interrupt handler */
  	if (pci_intr_map(&sc->sc_paa, &ih) == 0) {


On 2026-06-10 20:25, Gregory Norton wrote:
> Hi all, first patch so might be rough.
> 
> I've added support for the SPI part of the intel 9-series PCH as found 
> on the 2015 macbook8,1. When used with the aplhidev patches from Joshua 
> Stein, it enables the keyboard and trackpad to function (albeit some 
> quirks with backlight).
> 
> The 9-series (and 8-series) chipsets didn't yet support a dedicated 
> reset register or the ability to check the device's capabilities. 
> Referring to the source for intel_spi in FreeBSD, looks like they do a 
> similar skip over those checks for older models.
> 
> These changes should also open the path for 8-series, braswell, and 
> baytrail chipsets if the need arises.
> 
> - Greg
> 
> 
> diff --git sys/dev/ic/ispivar.h sys/dev/ic/ispivar.h
> index 6131616b5..8d44bda97 100644
> --- sys/dev/ic/ispivar.h
> +++ sys/dev/ic/ispivar.h
> @@ -42,6 +42,13 @@
>   #define DPRINTF(x)
>   #endif
> 
> +enum ispi_version {
> +    SPI_BAYTRAIL,
> +    SPI_BRASWELL,
> +    SPI_LYNXPOINT,
> +    SPI_SUNRISEPOINT
> +};
> +
>   struct ispi_softc {
>       struct device        sc_dev;
> 
> @@ -69,6 +76,7 @@ struct ispi_softc {
>       struct aml_node        *sc_devnode;
>   #endif
>       u_int32_t        sc_caps;
> +    enum ispi_version    sc_vers;
>   };
> 
>   void        ispi_init(struct ispi_softc *sc);
> diff --git sys/dev/pci/ispi_pci.c sys/dev/pci/ispi_pci.c
> index c77e67180..a23946336 100644
> --- sys/dev/pci/ispi_pci.c
> +++ sys/dev/pci/ispi_pci.c
> @@ -44,6 +44,7 @@ const struct cfattach ispi_pci_ca = {
>   };
> 
>   const struct pci_matchid ispi_pci_ids[] = {
> +    { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_9SERIES_LP_SPI },
>       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3 },
>   };
> 
> @@ -62,26 +63,34 @@ ispi_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>       pci_intr_handle_t ih;
>       const char *intrstr = NULL;
>       uint8_t type;
> +    int mtype;
> 
>       memcpy(&sc->sc_paa, pa, sizeof(sc->sc_paa));
> 
>       pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
> 
> -    if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT, 0,
> +    mtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
> +    if (pci_mapreg_map(pa, PCI_MAPREG_START, mtype, 0,
>           &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) {
>           printf(": can't map mem space\n");
>           return;
>       }
> 
> -    sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS);
> -    type = (sc->sc_caps & LPSS_CAPS_TYPE_MASK) >> LPSS_CAPS_TYPE_SHIFT;
> -    if (type != LPSS_CAPS_TYPE_SPI) {
> -        printf(": type %d not supported\n", type);
> -        return;
> -    }
> -
>       switch (PCI_PRODUCT(pa->pa_id)) {
> +    case PCI_PRODUCT_INTEL_9SERIES_LP_SPI:
> +        sc->sc_vers = SPI_LYNXPOINT;
> +
> +        /* SPT */
> +        sc->sc_lpss_reg_offset = 0x800;
> +        sc->sc_reg_cs_ctrl = 0x18;
> +        sc->sc_rx_threshold = 2;
> +        sc->sc_tx_threshold = 32;
> +        sc->sc_tx_threshold_hi = 56;
> +        sc->sc_ssp_clk = 9600000;
> +        break;
>       case PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3:
> +        sc->sc_vers = SPI_SUNRISEPOINT;
> +
>           /* SPT */
>           sc->sc_lpss_reg_offset = 0x200;
>           sc->sc_reg_cs_ctrl = 0x24;
> @@ -96,9 +105,27 @@ ispi_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>           return;
>       }
> 
> -    /* un-reset - page 958 */
> -    bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
> -        (LPSS_RESETS_FUNC | LPSS_RESETS_IDMA));
> +    sc->sc_caps = 0;
> +    if (sc->sc_vers == SPI_SUNRISEPOINT) {
> +        /*
> +         * sunrise point supports capability validation
> +         * and includes a dedicated reset register
> +         */
> +
> +        /* validate capabilities */
> +        sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS);
> +        type = (sc->sc_caps & LPSS_CAPS_TYPE_MASK) >> 
> LPSS_CAPS_TYPE_SHIFT;
> +        if (type != LPSS_CAPS_TYPE_SPI) {
> +            printf(": type %d not supported\n", type);
> +            bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize);
> +            return;
> +        }
> +
> +        /* un-reset - page 958 */
> +        if (sc->sc_vers == SPI_SUNRISEPOINT)
> +            bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
> +                (LPSS_RESETS_FUNC | LPSS_RESETS_IDMA));
> +    }
> 
>       /* install interrupt handler */
>       if (pci_intr_map(&sc->sc_paa, &ih) == 0) {
>