Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Mar 2026 04:51:26 +0000
From:      Aymeric Wibo <obiwac@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 69124109c5a0 - main - amdsmu: Cezanne support
Message-ID:  <69cb52ce.3bc58.6b33821b@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by obiwac:

URL: https://cgit.FreeBSD.org/src/commit/?id=69124109c5a00bb748cd8d3e9ede7291b34b577c

commit 69124109c5a00bb748cd8d3e9ede7291b34b577c
Author:     Aymeric Wibo <obiwac@FreeBSD.org>
AuthorDate: 2026-02-28 15:43:26 +0000
Commit:     Aymeric Wibo <obiwac@FreeBSD.org>
CommitDate: 2026-03-31 04:48:59 +0000

    amdsmu: Cezanne support
    
    Add support for Cezanne chips.  The only real difference vs
    Rembrandt/Phoenix is the idlemask register.
    
    Also simplify getting IP block count by having this straight in struct
    amdsmu_product and remove Strix Point from the list for now, as that
    doesn't support S0ix and our driver can't handle that.
    
    Reviewed by:    mckusick
    Approved by:    mckusick
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D55594
---
 sys/dev/amdsmu/amdsmu.c     | 34 ++++++++++++----------------------
 sys/dev/amdsmu/amdsmu.h     | 19 +++++++++++++++----
 sys/dev/amdsmu/amdsmu_reg.h |  5 ++++-
 3 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/sys/dev/amdsmu/amdsmu.c b/sys/dev/amdsmu/amdsmu.c
index 9a6873b43517..7b97888887c5 100644
--- a/sys/dev/amdsmu/amdsmu.c
+++ b/sys/dev/amdsmu/amdsmu.c
@@ -58,9 +58,12 @@ amdsmu_identify(driver_t *driver, device_t parent)
 static int
 amdsmu_probe(device_t dev)
 {
+	struct amdsmu_softc *sc;
+
 	if (resource_disabled("amdsmu", 0))
 		return (ENXIO);
-	if (!amdsmu_match(device_get_parent(dev), NULL))
+	sc = device_get_softc(dev);
+	if (!amdsmu_match(device_get_parent(dev), &sc->product))
 		return (ENXIO);
 	device_set_descf(dev, "AMD System Management Unit");
 
@@ -154,28 +157,11 @@ static int
 amdsmu_get_ip_blocks(device_t dev)
 {
 	struct amdsmu_softc *sc = device_get_softc(dev);
-	const uint16_t deviceid = pci_get_device(dev);
 	int err;
 	struct amdsmu_metrics *m = &sc->metrics;
 	bool active;
 	char sysctl_descr[32];
 
-	/* Get IP block count. */
-	switch (deviceid) {
-	case PCI_DEVICEID_AMD_REMBRANDT_ROOT:
-		sc->ip_block_count = 12;
-		break;
-	case PCI_DEVICEID_AMD_PHOENIX_ROOT:
-		sc->ip_block_count = 21;
-		break;
-	/* TODO How many IP blocks does Strix Point (and the others) have? */
-	case PCI_DEVICEID_AMD_STRIX_POINT_ROOT:
-	default:
-		sc->ip_block_count = nitems(amdsmu_ip_blocks_names);
-	}
-	KASSERT(sc->ip_block_count <= nitems(amdsmu_ip_blocks_names),
-	    ("too many IP blocks for array"));
-
 	/* Get and print out IP blocks. */
 	err = amdsmu_cmd(dev, SMU_MSG_GET_SUP_CONSTRAINTS, 0,
 	    &sc->active_ip_blocks);
@@ -184,13 +170,13 @@ amdsmu_get_ip_blocks(device_t dev)
 		return (err);
 	}
 	device_printf(dev, "Active IP blocks: ");
-	for (size_t i = 0; i < sc->ip_block_count; i++) {
+	for (size_t i = 0; i < sc->product->ip_block_count; i++) {
 		active = (sc->active_ip_blocks & (1 << i)) != 0;
 		sc->ip_blocks_active[i] = active;
 		if (!active)
 			continue;
 		printf("%s%s", amdsmu_ip_blocks_names[i],
-		    i + 1 < sc->ip_block_count ? " " : "\n");
+		    i + 1 < sc->product->ip_block_count ? " " : "\n");
 	}
 
 	/* Create a sysctl node for IP blocks. */
@@ -203,7 +189,7 @@ amdsmu_get_ip_blocks(device_t dev)
 	}
 
 	/* Create a sysctl node for each IP block. */
-	for (size_t i = 0; i < sc->ip_block_count; i++) {
+	for (size_t i = 0; i < sc->product->ip_block_count; i++) {
 		/* Create the sysctl node itself for the IP block. */
 		snprintf(sysctl_descr, sizeof sysctl_descr,
 		    "Metrics about the %s AMD IP block",
@@ -293,7 +279,7 @@ amdsmu_fetch_idlemask(device_t dev)
 {
 	struct amdsmu_softc *sc = device_get_softc(dev);
 
-	sc->idlemask = amdsmu_read4(sc, SMU_REG_IDLEMASK);
+	sc->idlemask = amdsmu_read4(sc, sc->product->idlemask_reg);
 }
 
 static void
@@ -301,6 +287,10 @@ amdsmu_suspend(device_t dev, enum power_stype stype)
 {
 	if (stype != POWER_STYPE_SUSPEND_TO_IDLE)
 		return;
+	/*
+	 * XXX It seems that Cezanne needs a special workaround here for
+	 * firmware versions < 64.53.  See amd_pmc_verify_czn_rtc() in Linux.
+	 */
 	if (amdsmu_cmd(dev, SMU_MSG_SLEEP_HINT, true, NULL) != 0)
 		device_printf(dev, "failed to hint to SMU to enter sleep");
 }
diff --git a/sys/dev/amdsmu/amdsmu.h b/sys/dev/amdsmu/amdsmu.h
index 857fa21cba4e..4286d515ae77 100644
--- a/sys/dev/amdsmu/amdsmu.h
+++ b/sys/dev/amdsmu/amdsmu.h
@@ -25,10 +25,20 @@
 static const struct amdsmu_product {
 	uint16_t	amdsmu_vendorid;
 	uint16_t	amdsmu_deviceid;
+	int16_t		idlemask_reg;
+	size_t		ip_block_count;
 } amdsmu_products[] = {
-	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_REMBRANDT_ROOT },
-	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_PHOENIX_ROOT },
-	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_STRIX_POINT_ROOT },
+	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_CEZANNE_ROOT,
+	    SMU_REG_IDLEMASK_CEZANNE,	12 },
+	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_REMBRANDT_ROOT,
+	    SMU_REG_IDLEMASK_PHOENIX,	12 },
+	{ CPU_VENDOR_AMD,	PCI_DEVICEID_AMD_PHOENIX_ROOT,
+	    SMU_REG_IDLEMASK_PHOENIX,	21 },
+	/*
+	 * XXX Strix Point (PCI_DEVICEID_AMD_STRIX_POINT_ROOT) doesn't support
+	 * S0i3 and thus doesn't have an idlemask.  Since our driver doesn't
+	 * yet understand this, don't attach to Strix Point for the time being.
+	 */
 };
 
 static const char *const amdsmu_ip_blocks_names[] = {
@@ -59,6 +69,8 @@ static const char *const amdsmu_ip_blocks_names[] = {
 CTASSERT(nitems(amdsmu_ip_blocks_names) <= 32);
 
 struct amdsmu_softc {
+	const struct amdsmu_product	*product;
+
 	struct sysctl_ctx_list	*sysctlctx;
 	struct sysctl_oid	*sysctlnode;
 
@@ -76,7 +88,6 @@ struct amdsmu_softc {
 
 	uint32_t		active_ip_blocks;
 	struct sysctl_oid	*ip_blocks_sysctlnode;
-	size_t			ip_block_count;
 	struct sysctl_oid	*ip_block_sysctlnodes[
 				    nitems(amdsmu_ip_blocks_names)];
 	bool			ip_blocks_active[
diff --git a/sys/dev/amdsmu/amdsmu_reg.h b/sys/dev/amdsmu/amdsmu_reg.h
index d45fa60941d5..6afbcf006535 100644
--- a/sys/dev/amdsmu/amdsmu_reg.h
+++ b/sys/dev/amdsmu/amdsmu_reg.h
@@ -16,6 +16,7 @@
  * out?  Also, there are way more of these.  I couldn't find a centralized place
  * which lists them though.
  */
+#define PCI_DEVICEID_AMD_CEZANNE_ROOT		0x1630
 #define PCI_DEVICEID_AMD_REMBRANDT_ROOT		0x14B5
 #define PCI_DEVICEID_AMD_PHOENIX_ROOT		0x14E8
 #define PCI_DEVICEID_AMD_STRIX_POINT_ROOT	0x14A4
@@ -32,7 +33,9 @@
 #define SMU_REG_MESSAGE		0x538
 #define SMU_REG_RESPONSE	0x980
 #define SMU_REG_ARGUMENT	0x9BC
-#define SMU_REG_IDLEMASK	0xD14
+
+#define SMU_REG_IDLEMASK_CEZANNE	0x94
+#define SMU_REG_IDLEMASK_PHOENIX	0xD14
 
 enum amdsmu_res {
 	SMU_RES_WAIT		= 0x00,


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69cb52ce.3bc58.6b33821b>