git: 6690cbdc649e - main - intel: add a shared header for the LPSS private registers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 19 Oct 2026 15:15:27 UTC
The branch main has been updated by seuros:
URL: https://cgit.FreeBSD.org/src/commit/?id=6690cbdc649e7d0b23d96e1490b72068fc791a95
commit 6690cbdc649e7d0b23d96e1490b72068fc791a95
Author: Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-10-19 15:15:09 +0000
Commit: Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-10-19 15:15:09 +0000
intel: add a shared header for the LPSS private registers
The Intel Low Power Subsystem wraps its I2C, SPI and UART functions in a
block of private registers that control the functional clock and the
function and DMA resets.
Refactored to use a single header
Reviewed by: imp, adrian
Differential Revision: https://reviews.freebsd.org/D60859
---
sys/dev/intel/lpss.h | 35 +++++++++++++++++++++++++++++++++++
sys/dev/intel/spi.c | 15 +++++++--------
sys/dev/uart/uart_bus_pci.c | 21 ++++++++-------------
3 files changed, 50 insertions(+), 21 deletions(-)
diff --git a/sys/dev/intel/lpss.h b/sys/dev/intel/lpss.h
new file mode 100644
index 000000000000..688195048cb6
--- /dev/null
+++ b/sys/dev/intel/lpss.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2026 Abdelkader Boudih <seuros@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _DEV_INTEL_LPSS_H_
+#define _DEV_INTEL_LPSS_H_
+
+/*
+ * Intel LPSS private registers, shared by the I2C, SPI and UART functions.
+ * Offsets are relative to the private block, which sits at one of these
+ * bases in the function's first memory BAR.
+ */
+#define LPSS_PRIV_LPT 0x800 /* Lynx Point, Atom SoCs */
+#define LPSS_PRIV_BYT 0x400 /* Bay Trail, Braswell */
+#define LPSS_PRIV_SPT 0x200 /* Sunrise Point and later */
+
+/* CLK - functional clock gate and M/N divider; rate is reference * M / N. */
+#define LPSS_PRIV_CLK 0x00
+#define LPSS_PRIV_CLK_EN (1U << 0)
+#define LPSS_PRIV_CLK_M_SHIFT 1
+#define LPSS_PRIV_CLK_N_SHIFT 16
+#define LPSS_PRIV_CLK_MN_MASK 0x7fff
+#define LPSS_PRIV_CLK_UPDATE (1U << 31) /* latch M and N */
+#define LPSS_PRIV_CLK_MN(m, n) \
+ ((((n) & LPSS_PRIV_CLK_MN_MASK) << LPSS_PRIV_CLK_N_SHIFT) | \
+ (((m) & LPSS_PRIV_CLK_MN_MASK) << LPSS_PRIV_CLK_M_SHIFT))
+
+/* RESETS - function and DMA resets; polarity is inverted from SPT onwards. */
+#define LPSS_PRIV_RESETS 0x04
+#define LPSS_PRIV_RESETS_FUNC 0x3
+#define LPSS_PRIV_RESETS_IDMA (1U << 2)
+
+#endif /* _DEV_INTEL_LPSS_H_ */
diff --git a/sys/dev/intel/spi.c b/sys/dev/intel/spi.c
index 9a0d4305227d..fca74b2f96cc 100644
--- a/sys/dev/intel/spi.c
+++ b/sys/dev/intel/spi.c
@@ -42,6 +42,7 @@
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
+#include <dev/intel/lpss.h>
#include <dev/intel/spi.h>
/**
@@ -123,9 +124,7 @@
#define SPI_CS_CTRL_HW_MODE (1 << 0)
#define SPI_CS_CTRL_CS_HIGH (1 << 1)
-#define INTELSPI_RESETS 0x204
-#define INTELSPI_RESET_HOST (1 << 0) | (1 << 1)
-#define INTELSPI_RESET_DMA (1 << 2)
+#define INTELSPI_RESETS (LPSS_PRIV_SPT + LPSS_PRIV_RESETS)
/* Same order as intelspi_vers */
static const struct intelspi_info {
@@ -133,19 +132,19 @@ static const struct intelspi_info {
uint32_t reg_cs_ctrl;
} intelspi_infos[] = {
[SPI_BAYTRAIL] = {
- .reg_lpss_base = 0x400,
+ .reg_lpss_base = LPSS_PRIV_BYT,
.reg_cs_ctrl = 0x18,
},
[SPI_BRASWELL] = {
- .reg_lpss_base = 0x400,
+ .reg_lpss_base = LPSS_PRIV_BYT,
.reg_cs_ctrl = 0x18,
},
[SPI_LYNXPOINT] = {
- .reg_lpss_base = 0x800,
+ .reg_lpss_base = LPSS_PRIV_LPT,
.reg_cs_ctrl = 0x18,
},
[SPI_SUNRISEPOINT] = {
- .reg_lpss_base = 0x200,
+ .reg_lpss_base = LPSS_PRIV_SPT,
.reg_cs_ctrl = 0x24,
},
};
@@ -509,7 +508,7 @@ intelspi_attach(device_t dev)
/* Release LPSS reset */
if (sc->sc_vers == SPI_SUNRISEPOINT)
INTELSPI_WRITE(sc, INTELSPI_RESETS,
- (INTELSPI_RESET_HOST | INTELSPI_RESET_DMA));
+ LPSS_PRIV_RESETS_FUNC | LPSS_PRIV_RESETS_IDMA);
sc->sc_irq_res = bus_alloc_resource_any(sc->sc_dev,
SYS_RES_IRQ, &sc->sc_irq_rid, RF_ACTIVE | RF_SHAREABLE);
diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c
index 39d3b1323bed..bb7e58a19f99 100644
--- a/sys/dev/uart/uart_bus_pci.c
+++ b/sys/dev/uart/uart_bus_pci.c
@@ -35,6 +35,7 @@
#include <sys/rman.h>
#include <machine/resource.h>
+#include <dev/intel/lpss.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -85,12 +86,8 @@ struct pci_unique_id {
#define PCI_INTEL_LPSS 0x20000000
#define PCI_RID_MASK 0x0000ffff
-/* Intel LPSS private registers, relative to BAR0. */
-#define LPSS_CLK 0x200
-#define LPSS_CLK_EN (1U << 0)
-#define LPSS_CLK_UPDATE (1U << 31)
-#define LPSS_RESETS 0x204
-#define LPSS_RESETS_FUNC 0x3
+#define LPSS_CLK (LPSS_PRIV_SPT + LPSS_PRIV_CLK)
+#define LPSS_RESETS (LPSS_PRIV_SPT + LPSS_PRIV_RESETS)
static const struct pci_id pci_ns8250_ids[] = {
{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14,
@@ -258,19 +255,17 @@ uart_pci_lpss_setup(struct resource *res)
return (ENXIO);
resets = bus_read_4(res, LPSS_RESETS);
- bus_write_4(res, LPSS_RESETS, resets | LPSS_RESETS_FUNC);
+ bus_write_4(res, LPSS_RESETS, resets | LPSS_PRIV_RESETS_FUNC);
bus_barrier(res, LPSS_RESETS, sizeof(uint32_t),
BUS_SPACE_BARRIER_WRITE);
- /*
- * Divide the 100 MHz reference clock down to 44.2368 MHz. Bits
- * 15:1 hold M and bits 30:16 hold N, giving a rate of ref * M / N.
- */
- clk = (15625U << 16) | (6912U << 1);
+ /* Divide the 100 MHz reference clock down to 44.2368 MHz. */
+ clk = LPSS_PRIV_CLK_MN(6912, 15625);
bus_write_4(res, LPSS_CLK, clk);
bus_barrier(res, LPSS_CLK, sizeof(uint32_t),
BUS_SPACE_BARRIER_WRITE);
- bus_write_4(res, LPSS_CLK, clk | LPSS_CLK_EN | LPSS_CLK_UPDATE);
+ bus_write_4(res, LPSS_CLK,
+ clk | LPSS_PRIV_CLK_EN | LPSS_PRIV_CLK_UPDATE);
(void)bus_read_4(res, LPSS_CLK);
return (0);