Page MenuHomeFreeBSD

D55594.id.diff
No OneTemporary

D55594.id.diff

diff --git a/sys/dev/amdsmu/amdsmu.h b/sys/dev/amdsmu/amdsmu.h
--- 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 @@
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 @@
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.c b/sys/dev/amdsmu/amdsmu.c
--- a/sys/dev/amdsmu/amdsmu.c
+++ b/sys/dev/amdsmu/amdsmu.c
@@ -58,9 +58,12 @@
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 @@
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 @@
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 @@
}
/* 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 @@
{
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 @@
{
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_reg.h b/sys/dev/amdsmu/amdsmu_reg.h
--- 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,

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 2, 8:46 AM (39 m, 24 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29120312
Default Alt Text
D55594.id.diff (4 KB)

Event Timeline