summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonathon Hall <jonathon.hall@puri.sm>2023-09-14 14:41:20 -0400
committerMatt DeVillier <matt.devillier@amd.corp-partner.google.com>2023-10-20 14:22:07 +0000
commita86704aa10704c47694606e4ebd83fdabad302fa (patch)
tree22c790638480b2f81403ccd10730b2914cab8a9a /src
parent24502f4cb0e44f53f6868f2e4e0c169ad0b60ab3 (diff)
downloadcoreboot-a86704aa10704c47694606e4ebd83fdabad302fa.tar.gz
coreboot-a86704aa10704c47694606e4ebd83fdabad302fa.tar.bz2
coreboot-a86704aa10704c47694606e4ebd83fdabad302fa.zip
mb/purism/librem_jsl: Add support for Librem 11
This adds support for the Librem 11 tablet, using the ME 13.50.15.1436 binary from the original BIOS (version 28.D8.E1.021) and FSP binaries from a Jasper Lake Chromebook. The following features were tested with PureOS: * Audio (speakers, microphone, headset jack) * Cameras * Display * Touchscreen and pen * Keyboard cover, with tablet/laptop mode switch indicated via ACPI * Power and volume buttons * USB-C ports (USB 2/3, DP alt mode, PD charging) * SD card reader * WLAN * Bluetooth * NVMe SSD (socketed) * Battery state information from EC * Accelerometer A UART is accessible with soldering via test points on the mainboard, documented in the mainboard Kconfig with a toggle to enable it for coreboot logging. Change-Id: I545994889ddfb41f56de09b3a42840bccbd7c4aa Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm> Reviewed-on: https://review.coreboot.org/c/coreboot/+/78343 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/purism/librem_jsl/Kconfig82
-rw-r--r--src/mainboard/purism/librem_jsl/Kconfig.name2
-rw-r--r--src/mainboard/purism/librem_jsl/Makefile.inc6
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/ac.asl23
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/battery.asl136
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/button.asl7
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/ec.asl121
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/gpe.asl14
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/mainboard.asl8
-rw-r--r--src/mainboard/purism/librem_jsl/acpi/vbtn.asl62
-rw-r--r--src/mainboard/purism/librem_jsl/board_info.txt8
-rw-r--r--src/mainboard/purism/librem_jsl/bootblock.c28
-rw-r--r--src/mainboard/purism/librem_jsl/data.vbtbin0 -> 7680 bytes
-rw-r--r--src/mainboard/purism/librem_jsl/devicetree.cb184
-rw-r--r--src/mainboard/purism/librem_jsl/dsdt.asl30
-rw-r--r--src/mainboard/purism/librem_jsl/gpio.h285
-rw-r--r--src/mainboard/purism/librem_jsl/hda_verb.c59
-rw-r--r--src/mainboard/purism/librem_jsl/ramstage.c38
-rw-r--r--src/mainboard/purism/librem_jsl/romstage.c46
-rw-r--r--src/mainboard/purism/librem_jsl/spd/isocon8gb.spd.hex32
20 files changed, 1171 insertions, 0 deletions
diff --git a/src/mainboard/purism/librem_jsl/Kconfig b/src/mainboard/purism/librem_jsl/Kconfig
new file mode 100644
index 000000000000..dc4c5e24b8de
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/Kconfig
@@ -0,0 +1,82 @@
+config BOARD_PURISM_BASEBOARD_LIBREM_JSL
+ def_bool n
+ select BOARD_ROMSIZE_KB_16384
+ select DRIVERS_GENERIC_CBFS_SERIAL
+ select DRIVERS_USB_ACPI
+ select DRIVERS_I2C_GENERIC
+ select DRIVERS_I2C_HID
+ select EC_ACPI
+ select HAVE_ACPI_RESUME
+ select HAVE_ACPI_TABLES
+ select HAVE_SPD_IN_CBFS
+ select INTEL_GMA_HAVE_VBT
+ select NO_UART_ON_SUPERIO
+ select SOC_INTEL_COMMON_BLOCK_HDA_VERB
+ select SOC_INTEL_JASPERLAKE
+ select SYSTEM_TYPE_DETACHABLE
+ select USE_LEGACY_8254_TIMER
+
+config BOARD_PURISM_LIBREM_11
+ select BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+if BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+config MAINBOARD_DIR
+ default "purism/librem_jsl"
+
+config MAINBOARD_FAMILY
+ string
+ default "Librem 11" if BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+config MAINBOARD_PART_NUMBER
+ default "Librem 11" if BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+config MAX_CPUS
+ int
+ default 4
+
+config CBFS_SIZE
+ default 0x700000 if BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+config DIMM_MAX
+ default 2
+
+config DIMM_SPD_SIZE
+ default 512
+
+config VGA_BIOS_ID
+ string
+ default "8086,4e61" if BOARD_PURISM_BASEBOARD_LIBREM_JSL
+
+config NO_POST
+ default y
+
+config INTEL_GMA_VBT_FILE
+ default "src/mainboard/purism/librem_jsl/data.vbt"
+
+config ENABLE_UART2
+ bool "Enable UART2 debug output"
+ default n
+ select INTEL_LPSS_UART_FOR_CONSOLE
+ help
+ Enable UART2 for debug output.
+
+ This UART can be used for boot logging by coreboot and payloads.
+
+ For Linux, boot with `console=uart,mmio32,0xfe032000,115200n8`.
+ (0xfe032000 is CONSOLE_UART_BASE_ADDRESS for Jasper Lake.) Blacklist
+ intel_lpss_pci so it does not reconfigure the UART.
+
+ Soldering is required to access these signals. On the reverse side of
+ the board, there are two test points directly underneath the SoC (the
+ only two test points between the heatsink screw holes). The pad
+ nearest the M.2 socket is TX, the other is RX. The signals are 3.3V
+ (do NOT connect directly to an RS-232 serial port).
+
+config UART_FOR_CONSOLE
+ default 2 if ENABLE_UART2
+
+config FSP_TEMP_RAM_SIZE
+ default 0x28000
+
+endif
diff --git a/src/mainboard/purism/librem_jsl/Kconfig.name b/src/mainboard/purism/librem_jsl/Kconfig.name
new file mode 100644
index 000000000000..93f95c0f6904
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/Kconfig.name
@@ -0,0 +1,2 @@
+config BOARD_PURISM_LIBREM_11
+ bool "Librem 11"
diff --git a/src/mainboard/purism/librem_jsl/Makefile.inc b/src/mainboard/purism/librem_jsl/Makefile.inc
new file mode 100644
index 000000000000..7fd4d59f9004
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/Makefile.inc
@@ -0,0 +1,6 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-y += bootblock.c
+ramstage-y += ramstage.c
+ramstage-y += hda_verb.c
+SPD_SOURCES += isocon8gb
diff --git a/src/mainboard/purism/librem_jsl/acpi/ac.asl b/src/mainboard/purism/librem_jsl/acpi/ac.asl
new file mode 100644
index 000000000000..86267e8eba6a
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/ac.asl
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (AC)
+{
+ Name (_HID, "ACPI0003" /* Power Source Device */) // _HID: Hardware ID
+ Name (_PCL, Package (0x01) // _PCL: Power Consumer List
+ {
+ _SB
+ })
+
+ Name (ACEX, One)
+
+ Method (_PSR, 0, NotSerialized) // _PSR: Power Source
+ {
+ Printf ("AC: _PSR: %o", ACEX)
+ Return (ACEX)
+ }
+
+ Method (_STA, 0, NotSerialized) // _STA: Status
+ {
+ Return (0x0F)
+ }
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/battery.asl b/src/mainboard/purism/librem_jsl/acpi/battery.asl
new file mode 100644
index 000000000000..73d5d65c97d6
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/battery.asl
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (BAT0)
+{
+ Name (_HID, EisaId ("PNP0C0A") /* Control Method Battery */) // _HID: Hardware ID
+ Name (_UID, Zero) // _UID: Unique ID
+ Name (_PCL, Package (0x01) // _PCL: Power Consumer List
+ {
+ _SB
+ })
+
+ Name (BTEX, Zero)
+
+ // Test if EC0 is ready, and if it is, if the battery is present
+ Method (BTOK, 0, NotSerialized)
+ {
+ If (^^ECOK) {
+ If (BTEX) {
+ Return (One)
+ }
+ }
+
+ Return (Zero)
+ }
+
+ Method (_STA, 0, NotSerialized) // _STA: Status
+ {
+ If (BTOK ()) {
+ Printf ("BAT0: _STA: present")
+ Return (0x1F)
+ }
+
+ Printf ("BAT0: _STA: not present")
+ Return (0x0F)
+ }
+
+ Name (PBIF, Package (0x0D) // Persistent battery information
+ {
+ One, // 0 - Power Unit - mA/mAh
+ 0xFFFFFFFF, // 1 - Design Capacity
+ 0xFFFFFFFF, // 2 - Last Full Charge Capacity
+ One, // 3 - Battery Technology
+ 0xFFFFFFFF, // 4 - Design Voltage
+ Zero, // 5 - Design Capacity of Warning
+ Zero, // 6 - Design Capacity of Low
+ Zero, // 7 - Battery Capacity Granularity 1
+ Zero, // 8 - Battery Capacity Granularity 2
+ "", // 9 - Model Number
+ "", // 10 - Serial Number
+ "", // 11 - Battery Type
+ "" // 12 - OEM Information
+ })
+
+ Method (IVBI, 0, NotSerialized) // Set invalid battery information
+ {
+ PBIF [1] = 0xFFFFFFFF
+ PBIF [2] = 0xFFFFFFFF
+ PBIF [5] = Zero
+ PBIF [6] = Zero
+ PBIF [7] = Zero
+ PBIF [8] = Zero
+ PBIF [9] = ""
+ PBIF [10] = ""
+ PBIF [11] = ""
+ }
+
+ Method (UPBI, 0, Serialized) // Update battery information
+ {
+ If (BTOK ()) {
+ Local0 = ^^BTDC // design cap
+ Local1 = ^^BTFC // last full capacity
+ // Design capacity
+ PBIF [1] = Local0
+ // Last full charge capacity
+ PBIF [2] = Local1
+ // Warn/low capacities - 15% and 10% of design capacity
+ PBIF [5] = Local1 * 15 / 100
+ PBIF [6] = Local1 * 10 / 100
+ // Granularity is 1% of design capacity
+ PBIF [7] = Local0 / 100
+ PBIF [8] = Local0 / 100
+ PBIF [9] = "BAT"
+ PBIF [10] = "0001"
+ PBIF [11] = "LION"
+ }
+ Else {
+ IVBI ()
+ }
+ }
+
+ Method (_BIF, 0, NotSerialized) // _BIF: Battery Information
+ {
+ UPBI ()
+ Return (PBIF)
+ }
+
+ Name (PBST, Package (0x04) // Persistent battery state
+ {
+ Zero, // 0 - Battery state
+ 0xFFFFFFFF, // 1 - Battery present rate
+ 0xFFFFFFFF, // 2 - Battery remaining capacity
+ 0xFFFFFFFF // 3 - Battery present voltage
+ })
+
+ Method (IVBS, 0, NotSerialized) // Invalid battery state
+ {
+ PBST [0] = Zero
+ PBST [1] = 0xFFFFFFFF
+ PBST [2] = 0xFFFFFFFF
+ PBST [3] = 0xFFFFFFFF
+ }
+
+ Method (UPBS, 0, Serialized)
+ {
+ If (BTOK ()) {
+ // Status flags - 3 bits; this EC does not report the
+ // charge limiting state
+ PBST [0] = ^^BTST
+ // Present rate
+ PBST [1] = ^^BTCR
+ // Remaining capacity
+ PBST [2] = ^^BTRC
+ // Present voltage
+ PBST [3] = ^^BTVT
+ }
+ Else {
+ IVBS ()
+ }
+ }
+
+ Method (_BST, 0, NotSerialized) // _BST: Battery Status
+ {
+ UPBS ()
+ Return (PBST)
+ }
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/button.asl b/src/mainboard/purism/librem_jsl/acpi/button.asl
new file mode 100644
index 000000000000..4e70b2c76248
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/button.asl
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (PWRB)
+{
+ Name (_HID, EisaId ("PNP0C0C"))
+ Name (_PRW, Package () { EC_GPE_SWI, 3 })
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/ec.asl b/src/mainboard/purism/librem_jsl/acpi/ec.asl
new file mode 100644
index 000000000000..dfdcc4290d6e
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/ec.asl
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (EC0)
+{
+ Name (_HID, EisaId ("PNP0C09"))
+ Name (_UID, 0)
+ Name (_GPE, EC_GPE_SWI)
+
+ Name (ECOK, Zero)
+
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x62, 0x62, 0, 1)
+ IO (Decode16, 0x66, 0x66, 0, 1)
+ })
+
+ Method (_STA, 0, NotSerialized) // _STA: Status
+ {
+ Return (0x0F)
+ }
+
+ OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF)
+ Field (ERAM, ByteAcc, Lock, Preserve)
+ {
+ Offset (0x7F),
+ LSTE, 1, /* lid state */
+ , 7,
+ ACEX, 1, /* AC adapter present */
+ BTEX, 1, /* battery present */
+ , 6,
+ Offset (0x84),
+ BTDC, 16, /* battery design capacity - mAh */
+ BTFV, 16, /* battery last full voltage - mV */
+ BTFC, 16, /* battery last full capacity - mAh */
+ Offset (0x8C),
+ BTST, 3, /* battery state */
+ , 5,
+ BTCR, 16, /* battery present current - mA */
+ BTRC, 16, /* battery remaining capacity - mAh */
+ BTVT, 16, /* battery present voltage - mV */
+ Offset (0xA3),
+ DSPO, 8, /* Display off - write 1 to power off display */
+ BCST, 8, /* battery charge start threshold - % */
+ BCET, 8, /* battery charge end threshold - % */
+ }
+
+ #include "button.asl"
+ #include "ac.asl"
+ #include "battery.asl"
+ #include "vbtn.asl"
+
+ Method (PTS, 1, Serialized) {
+ Printf ("EC: PTS: %o", ToHexString(Arg0))
+ If (ECOK) {
+ // Power off display
+ DSPO = One
+ }
+ }
+
+ Method (WAK, 1, Serialized) {
+ Printf ("EC: WAK: %o", ToHexString(Arg0))
+ If (ECOK) {
+ DSPO = Zero
+ ^AC.ACEX = ACEX
+ Notify(BAT0, Zero)
+ Notify(AC, Zero)
+ }
+ }
+
+ Method (_Q54, 0, NotSerialized) // Power button press
+ {
+ Printf ("EC: _Q54: power button press")
+ Notify (PWRB, 0x80)
+ }
+
+ Method (_Q0A, 0, NotSerialized) // Charger plugged or unplugged
+ {
+ Printf ("EC: _Q0A: charger state changed")
+ If (ECOK) {
+ ^AC.ACEX = ACEX
+ }
+ Notify(BAT0, 0x81) // Information change
+ Notify(AC, 0x80) // Status change
+ }
+
+ Method (_Q0B, 0, NotSerialized) // Battery status change
+ {
+ Printf ("EC: _Q0B: battery state changed")
+ Notify(BAT0, 0x81) // Information change
+ Notify(BAT0, 0x80) // Status change
+ }
+
+ /* There is a lid/cover sensor, but it is not reliable with a soft cover. */
+ Method (_Q0C, 0, NotSerialized) // Cover closed
+ {
+ Printf ("EC: _Q0C: cover closed")
+ }
+
+ Method (_Q0D, 0, NotSerialized) // Cover opened
+ {
+ Printf ("EC: _Q0D: cover opened")
+ }
+
+ Method (_REG, 2, Serialized) // _REG: Region Availability
+ {
+ Printf ("EC: _REG: %o, %o", Arg0, Arg1)
+ If ((Arg0 == 0x03) && (Arg1 == One)) {
+ // EC is now available
+ ECOK = One
+
+ // Set current AC and battery state
+ ^AC.ACEX = ACEX
+ ^BAT0.BTEX = BTEX
+
+ // Notify of changes
+ Notify(AC, Zero)
+ Notify(BAT0, Zero)
+
+ Printf ("EC is ready; BTEX=%o, ACEX=%o", BTEX, ACEX)
+ }
+ }
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/gpe.asl b/src/mainboard/purism/librem_jsl/acpi/gpe.asl
new file mode 100644
index 000000000000..bc8359dc523c
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/gpe.asl
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Scope (_GPE)
+{
+ /*
+ * Keyboard dock connector sense. This is GPP_D4, which would seem to
+ * be _L34 for GPE0_DW1, but there is an additional 10h offset for some
+ * reason, even if GPP_D is assigned to DW0 or DW2 instead.
+ */
+ Method (_L44, 0, NotSerialized) {
+ Printf ("GPE _L44");
+ \_SB.PCI0.LPCB.EC0.VBTN.NTFY ()
+ }
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/mainboard.asl b/src/mainboard/purism/librem_jsl/acpi/mainboard.asl
new file mode 100644
index 000000000000..819d30ae4452
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/mainboard.asl
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define EC_GPE_SWI 0x6E /* eSPI SCI */
+
+Scope (\_SB.PCI0.LPCB)
+{
+ #include "ec.asl"
+}
diff --git a/src/mainboard/purism/librem_jsl/acpi/vbtn.asl b/src/mainboard/purism/librem_jsl/acpi/vbtn.asl
new file mode 100644
index 000000000000..3cca8a350249
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/acpi/vbtn.asl
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+Name (FLAP, 0x40) /* Flag indicating device is in laptop mode */
+
+/* Virtual events */
+Name (VTBL, 0xcc) /* Tablet Mode */
+Name (VLAP, 0xcd) /* Laptop Mode */
+
+Device (VBTN)
+{
+ Name (_HID, "INT33D6")
+ Name (_UID, 1)
+ Name (_DDN, "Intel Virtual Button Driver")
+
+ /*
+ * This method is called at driver probe time and must exist or
+ * the driver will not load.
+ */
+ Method (VBDL)
+ {
+ }
+
+ /*
+ * This method returns flags indicating tablet and dock modes.
+ * It is called at driver probe time so the OS knows what the
+ * state of the device is at boot.
+ */
+ Method (VGBS)
+ {
+ Local0 = 0
+ If (CKLP ()) {
+ Local0 |= ^^FLAP
+ }
+ Return (Local0)
+ }
+
+ Method (_STA, 0)
+ {
+ Return (0xF)
+ }
+
+ Method (CKLP, 0)
+ {
+ /* 120 = GPP_D4 */
+ If (\_SB.PCI0.GRXS (120)) {
+ Printf ("VBTN: tablet mode")
+ Return (0) /* Tablet mode */
+ } Else {
+ Printf ("VBTN: laptop mode")
+ Return (1) /* Laptop mode */
+ }
+ }
+
+ Method (NTFY, 0)
+ {
+ /* Notify the new state */
+ If (CKLP ()) {
+ Notify (^^VBTN, ^^VLAP)
+ } Else {
+ Notify (^^VBTN, ^^VTBL)
+ }
+ }
+}
diff --git a/src/mainboard/purism/librem_jsl/board_info.txt b/src/mainboard/purism/librem_jsl/board_info.txt
new file mode 100644
index 000000000000..23538bdb15d4
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/board_info.txt
@@ -0,0 +1,8 @@
+Vendor name: Purism
+Board name: Librem Jasper Lake baseboard
+Category: misc
+Release year: 2023
+ROM package: SOIC-8
+ROM protocol: SPI
+ROM socketed: n
+Flashrom support: y
diff --git a/src/mainboard/purism/librem_jsl/bootblock.c b/src/mainboard/purism/librem_jsl/bootblock.c
new file mode 100644
index 000000000000..c629a6dec4b2
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/bootblock.c
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootblock_common.h>
+#include <console/console.h>
+#include <delay.h>
+#include <device/pci_ops.h>
+#include <ec/acpi/ec.h>
+#include <gpio.h>
+#include <soc/pci_devs.h>
+
+static const struct pad_config early_gpio_table[] = {
+ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2_RXD */
+ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2_TXD */
+};
+
+void bootblock_mainboard_early_init(void)
+{
+ gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table));
+}
+
+void bootblock_mainboard_init(void)
+{
+ /*
+ * Ensure the panel is powered on. ACPI _PTS disables it, if the system
+ * is powered up again we need to turn it on.
+ */
+ ec_write(0xa3, 0);
+}
diff --git a/src/mainboard/purism/librem_jsl/data.vbt b/src/mainboard/purism/librem_jsl/data.vbt
new file mode 100644
index 000000000000..e9143ea04e99
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/data.vbt
Binary files differ
diff --git a/src/mainboard/purism/librem_jsl/devicetree.cb b/src/mainboard/purism/librem_jsl/devicetree.cb
new file mode 100644
index 000000000000..e3b3be202273
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/devicetree.cb
@@ -0,0 +1,184 @@
+chip soc/intel/jasperlake
+
+ register "eist_enable" = "1"
+ register "s0ix_enable" = "0"
+
+ register "SaGv" = "SaGv_Enabled"
+
+ register "AcousticNoiseMitigation" = "1"
+
+ register "FastPkgCRampDisable" = "1"
+
+ register "SlowSlewRate" = "3"
+
+ # TCC limit of 60 C (passively cooled tablet)
+ register "tcc_offset" = "40"
+
+ register "power_limits_config[JSL_N5100_6W_CORE]" = "{
+ .tdp_pl1_override = 5,
+ .tdp_pl2_override = 12,
+ }"
+
+ register "pmc_gpe0_dw0" = "PMC_GPP_F"
+ register "pmc_gpe0_dw1" = "PMC_GPP_D"
+ register "pmc_gpe0_dw2" = "PMC_GPD"
+
+ register "SkipCpuReplacementCheck" = "1"
+
+ device cpu_cluster 0 on end
+
+ register "SerialIoI2cMode" = "{
+ [PchSerialIoIndexI2C0] = PchSerialIoDisabled,
+ [PchSerialIoIndexI2C1] = PchSerialIoDisabled,
+ [PchSerialIoIndexI2C2] = PchSerialIoPci,
+ [PchSerialIoIndexI2C3] = PchSerialIoPci,
+ [PchSerialIoIndexI2C4] = PchSerialIoDisabled,
+ [PchSerialIoIndexI2C5] = PchSerialIoDisabled,
+ }"
+
+ register "SerialIoUartMode[2]" = "PchSerialIoSkipInit"
+
+ # Audio related configurations
+ register "PchHdaDspEnable" = "1"
+ register "PchHdaAudioLinkHdaEnable" = "1"
+
+ device domain 0 on
+ device pci 00.0 on end # Host Bridge
+ device pci 02.0 on end # Integrated Graphics Device
+ device pci 04.0 on end # SA Thermal device
+ device pci 05.0 on end # IPU
+ device pci 09.0 off end # Intel Trace Hub
+ device pci 12.6 off end # GSPI 2
+ device pci 14.0 on # USB xHCI
+ register "usb2_ports[0]" = "USB2_PORT_MID(OC_SKIP)" # Fingerprint reader
+ register "usb2_ports[1]" = "USB2_PORT_MID(OC_SKIP)" # microSD
+ register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # Type-C 1
+ register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" # Type-C 2
+ register "usb2_ports[4]" = "USB2_PORT_EMPTY"
+ register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Internal hub - front and rear cameras
+ register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # Dock pogo pins
+ register "usb2_ports[7]" = "USB2_PORT_MID(OC_SKIP)" # WLAN module
+ register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" # Type-C Port 2
+ register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # Type-C Port 1
+
+ chip drivers/usb/acpi
+ register "desc" = ""Root Hub""
+ register "type" = "UPC_TYPE_HUB"
+ device usb 0.0 on
+ chip drivers/usb/acpi
+ register "desc" = ""Fingerprint Reader""
+ register "type" = "UPC_TYPE_INTERNAL"
+ device usb 2.0 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""microSD Card Reader""
+ register "type" = "UPC_TYPE_INTERNAL"
+ device usb 2.1 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Type-C Port 1""
+ register "type" = "UPC_TYPE_C_USB2_SS_SWITCH"
+ register "group" = "ACPI_PLD_GROUP(0, 0)"
+ device usb 2.2 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Type-C Port 2""
+ register "type" = "UPC_TYPE_C_USB2_SS_SWITCH"
+ register "group" = "ACPI_PLD_GROUP(0, 1)"
+ device usb 2.3 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Cameras""
+ register "type" = "UPC_TYPE_INTERNAL"
+ device usb 2.5 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Keyboard Dock""
+ register "type" = "UPC_TYPE_PROPRIETARY"
+ device usb 2.6 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Bluetooth""
+ register "type" = "UPC_TYPE_INTERNAL"
+ device usb 2.7 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Type-C Port 2""
+ register "type" = "UPC_TYPE_C_USB2_SS_SWITCH"
+ register "group" = "ACPI_PLD_GROUP(0, 1)"
+ device usb 3.0 on end
+ end
+ chip drivers/usb/acpi
+ register "desc" = ""Type-C Port 1""
+ register "type" = "UPC_TYPE_C_USB2_SS_SWITCH"
+ register "group" = "ACPI_PLD_GROUP(0, 0)"
+ device usb 3.1 on end
+ end
+ end
+ end
+ end
+ device pci 14.1 off end # USB xDCI (OTG)
+ device pci 14.2 on end # PMC SRAM
+ device pci 14.3 on # CNVi wifi
+ chip drivers/wifi/generic
+ device generic 0 on end
+ end
+ end
+ device pci 14.5 off end # SD card
+ device pci 15.0 off end # I2C 0
+ device pci 15.1 off end # I2C 1
+ device pci 15.2 on # I2C 2
+ chip drivers/i2c/hid
+ register "generic.hid" = ""GXTP7380""
+ register "generic.cid" = ""PNP0C50""
+ register "generic.desc" = ""Touchscreen""
+ register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_C12)"
+ register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D6)"
+ register "hid_desc_reg_offset" = "1"
+ device i2c 5d on end
+ end
+ end
+ device pci 15.3 on # I2C 3
+ chip drivers/i2c/generic
+ register "hid" = ""MXC6655""
+ register "cid" = ""MXC6655""
+ register "desc" = ""Accelerometer""
+ register "irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_E1)"
+ device i2c 15 on end
+ end
+ end
+ device pci 16.0 off end # HECI 1
+ device pci 16.1 off end # HECI 2
+ device pci 16.4 off end # HECI 3
+ device pci 16.5 off end # HECI 4
+ device pci 17.0 off end # SATA
+ device pci 19.0 on end # I2C 4
+ device pci 19.1 off end # I2C 5
+ device pci 19.2 off end # UART 2
+ device pci 1a.0 off end # eMMC
+ device pci 1c.0 off end # PCI Express Root Port 1
+ device pci 1c.1 off end # PCI Express Root Port 2
+ device pci 1c.2 on # PCI Express Root Port 3 - M.2 M-key, PCIe only
+ register "PcieRpEnable[2]" = "true"
+ register "PcieClkSrcUsage[0]" = "2"
+ register "PcieClkSrcClkReq[0]" = "0"
+ smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280" "SlotDataBusWidth2X"
+ end
+ device pci 1c.3 off end # PCI Express Root Port 4
+ device pci 1c.4 off end # PCI Express Root Port 5
+ device pci 1c.5 off end # PCI Express Root Port 6
+ device pci 1c.6 off end # PCI Express Root Port 7
+ device pci 1c.7 off end # PCI Express Root Port 8
+ device pci 1e.0 off end # UART 0
+ device pci 1e.1 off end # UART 1
+ device pci 1e.2 off end # GSPI 0
+ device pci 1e.3 off end # GSPI 1
+ device pci 1f.0 on end # eSPI Interface
+ device pci 1f.1 off end # P2SB
+ device pci 1f.2 hidden end # Power Management Controller
+ device pci 1f.3 on end # Intel HDA/cAVS
+ device pci 1f.4 off end # SMBus
+ device pci 1f.5 on end # PCH SPI
+ device pci 1f.7 off end # Intel Trace Hub
+ end
+end
diff --git a/src/mainboard/purism/librem_jsl/dsdt.asl b/src/mainboard/purism/librem_jsl/dsdt.asl
new file mode 100644
index 000000000000..713098b7f14a
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/dsdt.asl
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi.h>
+DefinitionBlock(
+ "dsdt.aml",
+ "DSDT",
+ ACPI_DSDT_REV_2,
+ OEM_ID,
+ ACPI_TABLE_CREATOR,
+ 0x20110725
+)
+{
+ #include <acpi/dsdt_top.asl>
+ #include <soc/intel/common/block/acpi/acpi/platform.asl>
+ #include <soc/intel/common/block/acpi/acpi/globalnvs.asl>
+ #include <cpu/intel/common/acpi/cpu.asl>
+
+ Device (\_SB.PCI0)
+ {
+ #include <soc/intel/common/block/acpi/acpi/northbridge.asl>
+ #include <soc/intel/jasperlake/acpi/southbridge.asl>
+ // The volume keys are implemented by the EC as a PS/2 keyboard
+ #include <drivers/pc80/pc/ps2_keyboard.asl>
+ }
+
+ #include "acpi/mainboard.asl"
+ #include "acpi/gpe.asl"
+
+ #include <southbridge/intel/common/acpi/sleepstates.asl>
+}
diff --git a/src/mainboard/purism/librem_jsl/gpio.h b/src/mainboard/purism/librem_jsl/gpio.h
new file mode 100644
index 000000000000..79148ea87653
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/gpio.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef CFG_GPIO_H
+#define CFG_GPIO_H
+
+#include <gpio.h>
+
+static const struct pad_config gpio_table[] = {
+
+ /* ------- GPIO Community 1 ------- */
+
+ /* ------- GPIO Group GPP_G ------- */
+ PAD_NC(GPP_G0, NONE), /* GPIO */
+ PAD_NC(GPP_G1, NONE), /* GPIO */
+ PAD_NC(GPP_G2, NONE), /* GPIO */
+ PAD_NC(GPP_G3, NONE), /* GPIO */
+ PAD_NC(GPP_G4, NONE), /* GPIO */
+ PAD_NC(GPP_G5, NONE), /* GPIO */
+ PAD_NC(GPP_G6, NONE), /* GPIO */
+ PAD_NC(GPP_G7, NONE), /* GPIO */
+
+ /* ------- GPIO Community 2 ------- */
+
+ /* ------- GPIO Group HVMOS ------- */
+
+ /* ------- GPIO Group GPP_E ------- */
+ PAD_NC(GPP_E0, NONE), /* GPIO */
+ /* GPP_E1 - ACCL_1_INT_N */
+ PAD_CFG_GPI_TRIG_OWN(GPP_E1, NONE, PLTRST, OFF, DRIVER), /* GPIO */
+ PAD_NC(GPP_E2, NONE), /* GPIO */
+ PAD_NC(GPP_E3, NONE), /* GPIO */
+ PAD_NC(GPP_E4, NONE), /* GPIO */
+ PAD_NC(GPP_E5, NONE), /* GPIO */
+ PAD_NC(GPP_E6, NONE), /* GPIO */
+ PAD_NC(GPP_E7, NONE), /* GPIO */
+ /* GPP_E8 - UART_BT_WAKE_N */
+ //PAD_CFG_GPI_SCI(GPP_E8, NONE, DEEP, LEVEL, INVERT), /* GPIO */
+ PAD_NC(GPP_E8, NONE),
+ PAD_NC(GPP_E9, NONE), /* GPIO */
+ PAD_NC(GPP_E10, NONE), /* GPIO */
+ PAD_NC(GPP_E11, NONE), /* GPIO */
+ PAD_NC(GPP_E12, NONE), /* GPIO */
+ PAD_NC(GPP_E13, NONE), /* GPIO */
+ PAD_NC(GPP_E14, NONE), /* GPIO */
+ PAD_NC(GPP_E15, NONE), /* GPIO */
+ PAD_NC(GPP_E16, NONE), /* GPIO */
+ PAD_NC(GPP_E17, NONE), /* GPIO */
+ PAD_NC(GPP_E18, NONE), /* GPIO */
+ PAD_NC(GPP_E19, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* CNV_BRI_DT */
+ PAD_CFG_NF(GPP_E21, UP_20K, DEEP, NF1), /* CNV_BRI_RSP */
+ PAD_CFG_NF(GPP_E22, NONE, DEEP, NF1), /* CNV_RGI_DT */
+ PAD_CFG_NF(GPP_E23, UP_20K, DEEP, NF1), /* CNV_RGI_RSP */
+
+ /* ------- GPIO Community 4 ------- */
+
+ /* ------- GPIO Group GPD ------- */
+ PAD_CFG_NF(GPD0, NONE, RSMRST, NF1), /* GPIO_BATLOWB */
+ PAD_CFG_NF(GPD1, NATIVE, RSMRST, NF1), /* GPIO_ACPRESENT */
+ /* GPD2 - SMC_WAKE_SCI_N */
+ PAD_CFG_GPI_SCI(GPD2, NONE, DEEP, LEVEL, INVERT), /* GPIO */
+ PAD_CFG_NF(GPD3, UP_20K, RSMRST, NF1), /* GPIO_PWRBTNB */
+ PAD_CFG_NF(GPD4, NONE, RSMRST, NF1), /* GPIO_SLP_S3B */
+ PAD_CFG_NF(GPD5, NONE, RSMRST, NF1), /* GPIO_SLP_S4B */
+ PAD_CFG_NF(GPD6, NONE, DEEP, NF1), /* GPIO_SLP_AB */
+ PAD_NC(GPD7, NONE), /* GPIO */
+ PAD_CFG_NF(GPD8, NONE, RSMRST, NF1), /* GPIO_SUSCLK */
+ PAD_CFG_NF(GPD9, NONE, DEEP, NF1), /* GPIO_SLP_WLANB */
+ PAD_CFG_NF(GPD10, NONE, DEEP, NF1), /* GPIO_SLP_S5B */
+
+ /* ------- GPIO Community 5 ------- */
+
+ /* ------- GPIO Group GPP_H ------- */
+ /* GPP_H0 - FPS_INT_N */
+ PAD_CFG_GPI_APIC(GPP_H0, NONE, PLTRST, LEVEL, INVERT), /* GPIO */
+ PAD_NC(GPP_H1, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_H2, NONE, DEEP, NF3), /* MODEM_CLKREQ */
+ PAD_NC(GPP_H3, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* I2C2_SDA */
+ PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* I2C2_SCL */
+ PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), /* I2C3_SDA */
+ PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), /* I2C3_SCL */
+ PAD_NC(GPP_H8, NONE), /* GPIO */
+ PAD_NC(GPP_H9, NONE), /* GPIO */
+ PAD_NC(GPP_H10, NONE), /* GPIO */
+ PAD_NC(GPP_H11, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_H12, NONE, DEEP, NF2), /* CNV_RF_RESETB */
+ PAD_NC(GPP_H13, NONE), /* GPIO */
+ PAD_NC(GPP_H14, NONE), /* GPIO */
+ PAD_NC(GPP_H15, NONE), /* GPIO */
+ /* GPP_H16 - FPS_RST_N */
+ PAD_CFG_GPO(GPP_H16, 1, PLTRST), /* GPIO */
+ PAD_NC(GPP_H17, NONE), /* GPIO */
+ PAD_NC(GPP_H18, NONE), /* GPIO */
+ PAD_NC(GPP_H19, NONE), /* GPIO */
+ PAD_NC(GPP_H20, NONE), /* GPIO */
+ PAD_NC(GPP_H21, NONE), /* GPIO */
+ PAD_NC(GPP_H22, NONE), /* GPIO */
+ PAD_NC(GPP_H23, NONE), /* GPIO */
+
+ /* ------- GPIO Group GPP_D ------- */
+ PAD_NC(GPP_D0, NONE), /* GPIO */
+ PAD_NC(GPP_D1, NONE), /* GPIO */
+ /* GPP_D2 - EC_SMI_N */
+ PAD_CFG_GPI_SMI(GPP_D2, NONE, PLTRST, LEVEL, INVERT), /* GPIO */
+ PAD_NC(GPP_D3, NONE), /* GPIO */
+ /* GPP_D4 - GPIO_DK (keyboard dock sense) */
+ PAD_CFG_GPI_SCI(GPP_D4, NONE, DEEP, EDGE_BOTH, NONE), /* GPIO */
+ /* GPP_D5 - SSD_RST_N (NVMe PERESET#) */
+ PAD_CFG_GPO(GPP_D5, 1, PLTRST), /* GPIO */
+ /* GPP_D6 - TCH_PNL_RST_N */
+ PAD_CFG_GPO(GPP_D6, 1, PLTRST), /* GPIO */
+ PAD_NC(GPP_D7, NONE), /* GPIO */
+ PAD_NC(GPP_D8, NONE), /* GPIO */
+ PAD_NC(GPP_D9, NONE), /* GPIO */
+ PAD_NC(GPP_D10, NONE), /* GPIO */
+ PAD_NC(GPP_D11, NONE), /* GPIO */
+ PAD_NC(GPP_D12, NONE), /* GPIO */
+ PAD_NC(GPP_D13, NONE), /* GPIO */
+ PAD_NC(GPP_D14, NONE), /* GPIO */
+ PAD_NC(GPP_D15, NONE), /* GPIO */
+ PAD_NC(GPP_D16, NONE), /* GPIO */
+ PAD_NC(GPP_D17, NONE), /* GPIO */
+ PAD_NC(GPP_D18, NONE), /* GPIO */
+ PAD_NC(GPP_D19, NONE), /* GPIO */
+ PAD_NC(GPP_D20, NONE), /* GPIO */
+ PAD_NC(GPP_D21, NONE), /* GPIO */
+ PAD_NC(GPP_D22, NONE), /* GPIO */
+ PAD_NC(GPP_D23, NONE), /* GPIO */
+
+ /* ------- GPIO Group VGPIO5 ------- */
+ PAD_NC(VGPIO_0, NONE), /* GPIO */
+ PAD_NC(VGPIO_3, NONE), /* GPIO */
+ PAD_NC(VGPIO_4, NONE), /* GPIO */
+ PAD_NC(VGPIO_5, NONE), /* GPIO */
+ PAD_NC(VGPIO_6, NONE), /* GPIO */
+ PAD_NC(VGPIO_7, NONE), /* GPIO */
+ PAD_NC(VGPIO_8, NONE), /* GPIO */
+ PAD_NC(VGPIO_9, NONE), /* GPIO */
+ PAD_NC(VGPIO_10, NONE), /* GPIO */
+ PAD_NC(VGPIO_11, NONE), /* GPIO */
+ PAD_NC(VGPIO_12, NONE), /* GPIO */
+ PAD_NC(VGPIO_13, NONE), /* GPIO */
+ PAD_NC(VGPIO_18, NONE), /* GPIO */
+ PAD_NC(VGPIO_19, NONE), /* GPIO */
+ PAD_NC(VGPIO_20, NONE), /* GPIO */
+ PAD_NC(VGPIO_21, NONE), /* GPIO */
+ PAD_NC(VGPIO_22, NONE), /* GPIO */
+ PAD_NC(VGPIO_23, NONE), /* GPIO */
+ PAD_NC(VGPIO_24, NONE), /* GPIO */
+ PAD_NC(VGPIO_25, NONE), /* GPIO */
+ PAD_NC(VGPIO_30, NONE), /* GPIO */
+ PAD_NC(VGPIO_31, NONE), /* GPIO */
+ PAD_NC(VGPIO_32, NONE), /* GPIO */
+ PAD_NC(VGPIO_33, NONE), /* GPIO */
+ PAD_NC(VGPIO_34, NONE), /* GPIO */
+ PAD_NC(VGPIO_35, NONE), /* GPIO */
+ PAD_NC(VGPIO_36, NONE), /* GPIO */
+ PAD_NC(VGPIO_37, NONE), /* GPIO */
+ PAD_NC(VGPIO_39, NONE), /* GPIO */
+
+ /* ------- GPIO Group GPP_C ------- */
+ PAD_NC(GPP_C0, NONE), /* GPIO */
+ PAD_NC(GPP_C1, NONE), /* GPIO */
+ PAD_NC(GPP_C2, NONE), /* GPIO */
+ PAD_NC(GPP_C3, NONE), /* GPIO */
+ PAD_NC(GPP_C4, NONE), /* GPIO */
+ PAD_NC(GPP_C5, NONE), /* GPIO */
+ PAD_NC(GPP_C6, NONE), /* GPIO */
+ PAD_NC(GPP_C7, NONE), /* GPIO */
+ PAD_CFG_GPO(GPP_C8, 1, PLTRST), /* GPIO */
+ PAD_NC(GPP_C9, NONE), /* GPIO */
+ PAD_NC(GPP_C10, NONE), /* GPIO */
+ PAD_NC(GPP_C11, NONE), /* GPIO */
+ /* GPP_C12 - TCH_PNL_INT_N */
+ PAD_CFG_GPI_TRIG_OWN(GPP_C12, NONE, PLTRST, EDGE_SINGLE, DRIVER), /* GPIO */
+ PAD_NC(GPP_C13, NONE), /* GPIO */
+ PAD_NC(GPP_C14, NONE), /* GPIO */
+ PAD_NC(GPP_C15, NONE), /* GPIO */
+ PAD_NC(GPP_C16, NONE), /* GPIO */
+ PAD_NC(GPP_C17, NONE), /* GPIO */
+ PAD_NC(GPP_C18, NONE), /* GPIO */
+ PAD_NC(GPP_C19, NONE), /* GPIO */
+ /* GPP_C20, GPP_C21 configured in bootblock for UART2 */
+ PAD_NC(GPP_C22, NONE), /* GPIO */
+ PAD_NC(GPP_C23, NONE), /* GPIO */
+
+ /* ------- GPIO Community 6 ------- */
+
+ /* ------- GPIO Group GPP_F ------- */
+ PAD_NC(GPP_F0, NONE), /* GPIO */
+ PAD_NC(GPP_F1, NONE), /* GPIO */
+ PAD_NC(GPP_F2, NONE), /* GPIO */
+ PAD_NC(GPP_F3, NONE), /* GPIO */
+ PAD_NC(GPP_F4, NONE), /* GPIO */
+ PAD_NC(GPP_F5, NONE), /* GPIO */
+ PAD_NC(GPP_F6, NONE), /* GPIO */
+ PAD_NC(GPP_F7, NONE), /* GPIO */
+ PAD_NC(GPP_F8, NONE), /* GPIO */
+ PAD_NC(GPP_F9, NONE), /* GPIO */
+ PAD_NC(GPP_F10, NONE), /* GPIO */
+ PAD_NC(GPP_F11, NONE), /* GPIO */
+ PAD_NC(GPP_F12, NONE), /* GPIO */
+ PAD_NC(GPP_F13, NONE), /* GPIO */
+ PAD_NC(GPP_F14, NONE), /* GPIO */
+ PAD_NC(GPP_F15, NONE), /* GPIO */
+ PAD_NC(GPP_F16, NONE), /* GPIO */
+ PAD_NC(GPP_F17, NONE), /* GPIO */
+ PAD_NC(GPP_F18, NONE), /* GPIO */
+ PAD_NC(GPP_F19, NONE), /* GPIO */
+
+ /* ------- GPIO Group GPP_SPI ------- */
+
+ /* ------- GPIO Group GPP_B ------- */
+ PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), /* GPIO_CORE_VID0 */
+ PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* GPIO_CORE_VID1 */
+ PAD_NC(GPP_B2, NONE), /* GPIO */
+ PAD_NC(GPP_B3, NONE), /* GPIO */
+ PAD_NC(GPP_B4, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* PCIE_CLKREQ0B */
+ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* PCIE_CLKREQ1B */
+ PAD_NC(GPP_B7, NONE), /* GPIO */
+ PAD_NC(GPP_B8, NONE), /* GPIO */
+ PAD_NC(GPP_B9, NONE), /* GPIO */
+ PAD_NC(GPP_B10, NONE), /* GPIO */
+ PAD_NC(GPP_B11, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* GPIO_SLP_S0B */
+ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* GPIO_PLTRSTB */
+ PAD_NC(GPP_B14, NONE), /* GPIO */
+ PAD_NC(GPP_B15, NONE), /* GPIO */
+ PAD_NC(GPP_B16, NONE), /* GPIO */
+ /* GPP_B17 - PCIE_WLAN_RST_N_R */
+ PAD_CFG_GPO(GPP_B17, 1, PLTRST), /* GPIO */
+ PAD_NC(GPP_B18, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_B19, NONE, DEEP, NF1), /* GSPI1_CS0B */
+ PAD_CFG_NF(GPP_B20, NONE, DEEP, NF1), /* GSPI1_CLK */
+ PAD_CFG_NF(GPP_B21, NONE, DEEP, NF1), /* GSPI1_MISO */
+ PAD_CFG_NF(GPP_B22, NONE, DEEP, NF1), /* GSPI1_MOSI */
+ PAD_CFG_NF(GPP_B23, NONE, DEEP, NF1), /* DDI2_HPD */
+
+ /* ------- GPIO Group GPP_A ------- */
+ PAD_CFG_NF(GPP_A0, UP_20K, DEEP, NF1), /* ESPI_IO_0 */
+ PAD_CFG_NF(GPP_A1, UP_20K, DEEP, NF1), /* ESPI_IO_1 */
+ PAD_CFG_NF(GPP_A2, UP_20K, DEEP, NF1), /* ESPI_IO_2 */
+ PAD_CFG_NF(GPP_A3, UP_20K, DEEP, NF1), /* ESPI_IO_3 */
+ PAD_CFG_NF(GPP_A4, UP_20K, DEEP, NF1), /* ESPI_CSB */
+ PAD_CFG_NF(GPP_A5, DN_20K, DEEP, NF1), /* ESPI_CLK */
+ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* ESPI_RESETB */
+ PAD_NC(GPP_A7, NONE), /* GPIO */
+ PAD_NC(GPP_A8, NONE), /* GPIO */
+ PAD_NC(GPP_A9, NONE), /* GPIO */
+ PAD_NC(GPP_A10, NONE), /* GPIO */
+ PAD_NC(GPP_A11, NONE), /* GPIO */
+ PAD_NC(GPP_A12, NONE), /* GPIO */
+ PAD_NC(GPP_A13, NONE), /* GPIO */
+ PAD_NC(GPP_A14, NONE), /* GPIO */
+ PAD_NC(GPP_A15, NONE), /* GPIO */
+ PAD_CFG_NF(GPP_A16, NONE, DEEP, NF1), /* DDI1_HPD */
+ PAD_CFG_NF(GPP_A17, NONE, DEEP, NF1), /* DDI0_HPD */
+ PAD_NC(GPP_A18, NONE), /* GPIO */
+ /* GPP_A19 - WWAN_DISABLE_3P3_N (actually for WLAN despite name) */
+ PAD_CFG_GPO(GPP_A19, 1, PLTRST), /* GPIO */
+
+ /* ------- GPIO Group GPP_S ------- */
+ PAD_NC(GPP_S0, NONE), /* GPIO */
+ PAD_NC(GPP_S1, NONE), /* GPIO */
+ PAD_NC(GPP_S2, NONE), /* GPIO */
+ PAD_NC(GPP_S3, NONE), /* GPIO */
+ PAD_NC(GPP_S4, NONE), /* GPIO */
+ PAD_NC(GPP_S5, NONE), /* GPIO */
+ PAD_NC(GPP_S6, NONE), /* GPIO */
+ PAD_NC(GPP_S7, NONE), /* GPIO */
+
+ /* ------- GPIO Group GPP_R ------- */
+ PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), /* HDA_BCLK */
+ PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), /* HDA_SYNC */
+ PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), /* HDA_SD0 */
+ PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), /* HDA_SDI0 */
+ PAD_CFG_NF(GPP_R4, NONE, DEEP, NF1), /* HDA_RSTB */
+ PAD_NC(GPP_R5, NONE), /* GPIO */
+ PAD_NC(GPP_R6, NONE), /* GPIO */
+ PAD_NC(GPP_R7, NONE), /* GPIO */
+};
+
+#endif /* CFG_GPIO_H */
diff --git a/src/mainboard/purism/librem_jsl/hda_verb.c b/src/mainboard/purism/librem_jsl/hda_verb.c
new file mode 100644
index 000000000000..5014ec4b3eac
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/hda_verb.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/azalia_device.h>
+
+const u32 cim_verb_data[] = {
+ 0x10ec0269, /* Codec Vendor/Device ID: Realtek ALC269 */
+ 0x10ec0269, /* Subsystem ID */
+ 16, /* Number of entries */
+
+ AZALIA_RESET(0x1),
+
+ AZALIA_SUBVENDOR(0, 0x10ec0269),
+ AZALIA_PIN_CFG(0, 0x12, 0x90a60130), /* DMIC */
+ AZALIA_PIN_CFG(0, 0x14, 0x90170110), /* FRONT */
+ AZALIA_PIN_CFG(0, 0x17, 0x40000000), /* N/C */
+ AZALIA_PIN_CFG(0, 0x18, 0x04a11020), /* MIC1 */
+ AZALIA_PIN_CFG(0, 0x19, 0x411111f0), /* N/C */
+ AZALIA_PIN_CFG(0, 0x1a, 0x411111f0), /* N/C */
+ AZALIA_PIN_CFG(0, 0x1b, 0x411111f0), /* N/C */
+ AZALIA_PIN_CFG(0, 0x1d, 0x40e38105), /* BEEP */
+ AZALIA_PIN_CFG(0, 0x1e, 0x411111f0), /* N/C */
+ AZALIA_PIN_CFG(0, 0x21, 0x0421101f), /* HP-OUT */
+
+ /* EQ */
+ 0x02050011,
+ 0x02040710,
+ 0x02050012,
+ 0x02041901,
+
+ 0x0205000D,
+ 0x02044440,
+ 0x02050007,
+ 0x02040040,
+
+ 0x02050002,
+ 0x0204AAB8,
+ 0x02050008,
+ 0x02040300,
+
+ 0x02050017,
+ 0x020400AF,
+ 0x02050005,
+ 0x020400C0,
+
+ 0x8086281a, /* Codec Vendor/Device ID: Intel Jasper Lake HDMI */
+ 0x80860101, /* Subsystem ID */
+ 6, /* Number of entries */
+
+ AZALIA_SUBVENDOR(2, 0x80860101),
+ AZALIA_PIN_CFG(2, 0x04, 0x18560010),
+ AZALIA_PIN_CFG(2, 0x06, 0x18560010),
+ AZALIA_PIN_CFG(2, 0x08, 0x18560010),
+ AZALIA_PIN_CFG(2, 0x0a, 0x18560010),
+ AZALIA_PIN_CFG(2, 0x0b, 0x18560010),
+};
+
+const u32 pc_beep_verbs[] = {};
+
+AZALIA_ARRAY_SIZES;
diff --git a/src/mainboard/purism/librem_jsl/ramstage.c b/src/mainboard/purism/librem_jsl/ramstage.c
new file mode 100644
index 000000000000..b9dd5f2f4d65
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/ramstage.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/ramstage.h>
+#include <acpi/acpigen_ps2_keybd.h>
+#include "gpio.h"
+
+void mainboard_silicon_init_params(FSP_S_CONFIG *supd)
+{
+}
+
+static void mainboard_fill_ssdt(const struct device *dev)
+{
+ /*
+ * Librem 11's PS/2 keyboard has only two keys - volume up and volume
+ * down.
+ */
+ enum ps2_action_key ps2_action_keys[2] = {
+ PS2_KEY_VOL_DOWN,
+ PS2_KEY_VOL_UP
+ };
+ acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys),
+ ps2_action_keys, false, false, false, false);
+}
+
+static void mainboard_init(void *chip_info)
+{
+ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
+}
+
+static void mainboard_enable(struct device *dev)
+{
+ dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
+}
+
+struct chip_operations mainboard_ops = {
+ .init = mainboard_init,
+ .enable_dev = mainboard_enable,
+};
diff --git a/src/mainboard/purism/librem_jsl/romstage.c b/src/mainboard/purism/librem_jsl/romstage.c
new file mode 100644
index 000000000000..65205ad9157b
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/romstage.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <gpio.h>
+#include <memory_info.h>
+#include <soc/meminit.h>
+#include <soc/romstage.h>
+#include <device/pci_ops.h>
+#include <console/console.h>
+
+static const struct mb_cfg board_mem_cfg = {
+ .dq_map[DDR_CH0] = {
+ {0x0f, 0xf0},
+ {0x0f, 0xf0},
+ {0xff, 0x00},
+ {0x00, 0x00},
+ {0x00, 0x00},
+ {0x00, 0x00}
+ },
+ .dq_map[DDR_CH1] = {
+ {0x0f, 0xf0},
+ {0x0f, 0xf0},
+ {0xff, 0x00},
+ {0x00, 0x00},
+ {0x00, 0x00},
+ {0x00, 0x00}
+ },
+
+ .dqs_map[DDR_CH0] = {0, 3, 2, 1, 5, 7, 4, 6},
+ .dqs_map[DDR_CH1] = {3, 1, 2, 0, 4, 7, 6, 5},
+
+ /* Enable Early Command Training */
+ .ect = 1,
+
+ /* User Board Type */
+ .UserBd = BOARD_TYPE_ULT_ULX,
+};
+
+void mainboard_memory_init_params(FSPM_UPD *memupd)
+{
+ const struct spd_info spd_info = {
+ .read_type = READ_SPD_CBFS,
+ .spd_spec.spd_index = 0,
+ };
+
+ memcfg_init(&memupd->FspmConfig, &board_mem_cfg, &spd_info, false);
+}
diff --git a/src/mainboard/purism/librem_jsl/spd/isocon8gb.spd.hex b/src/mainboard/purism/librem_jsl/spd/isocon8gb.spd.hex
new file mode 100644
index 000000000000..b9fd365dce7a
--- /dev/null
+++ b/src/mainboard/purism/librem_jsl/spd/isocon8gb.spd.hex
@@ -0,0 +1,32 @@
+23 11 11 0e 16 29 b8 08 00 40 00 00 02 62 00 00
+00 00 05 0f 92 54 01 00 8a 00 90 a8 90 c0 08 60
+04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 92 00 a7
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 20 00 00 00 4d 54 35 33 44 35 31
+32 4d 36 34 44 34 52 51 2d 30 34 36 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00