amdsmu: Add Krackan Point support
Reviewed by: obiwac, emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D56619
This commit is contained in:
+14
-4
@@ -30,11 +30,21 @@ amdsmu_match(device_t dev, const struct amdsmu_product **product_out)
|
||||
const uint16_t vendorid = pci_get_vendor(dev);
|
||||
const uint16_t deviceid = pci_get_device(dev);
|
||||
|
||||
const uint32_t model = CPUID_TO_MODEL(cpu_id);
|
||||
|
||||
for (size_t i = 0; i < nitems(amdsmu_products); i++) {
|
||||
const struct amdsmu_product *prod = &amdsmu_products[i];
|
||||
|
||||
if (vendorid == prod->amdsmu_vendorid &&
|
||||
deviceid == prod->amdsmu_deviceid) {
|
||||
|
||||
/*
|
||||
* Some Krackan Point devices have different ip blocks
|
||||
* based on CPU model.
|
||||
*/
|
||||
if (prod->model != 0x00 && model != prod->model)
|
||||
continue;
|
||||
|
||||
if (product_out != NULL)
|
||||
*product_out = prod;
|
||||
return (true);
|
||||
@@ -105,7 +115,7 @@ amdsmu_cmd(device_t dev, enum amdsmu_msg msg, uint32_t arg, uint32_t *ret)
|
||||
amdsmu_write4(sc, SMU_REG_RESPONSE, SMU_RES_WAIT);
|
||||
|
||||
/* Write out command to registers. */
|
||||
amdsmu_write4(sc, SMU_REG_MESSAGE, msg);
|
||||
amdsmu_write4(sc, sc->product->amdsmu_msg, msg);
|
||||
amdsmu_write4(sc, SMU_REG_ARGUMENT, arg);
|
||||
|
||||
/* Wait for SMU response and handle it. */
|
||||
@@ -175,7 +185,7 @@ amdsmu_get_ip_blocks(device_t dev)
|
||||
sc->ip_blocks_active[i] = active;
|
||||
if (!active)
|
||||
continue;
|
||||
printf("%s%s", amdsmu_ip_blocks_names[i],
|
||||
printf("%s%s", sc->product->ip_blocks_names[i],
|
||||
i + 1 < sc->product->ip_block_count ? " " : "\n");
|
||||
}
|
||||
|
||||
@@ -193,10 +203,10 @@ amdsmu_get_ip_blocks(device_t dev)
|
||||
/* Create the sysctl node itself for the IP block. */
|
||||
snprintf(sysctl_descr, sizeof sysctl_descr,
|
||||
"Metrics about the %s AMD IP block",
|
||||
amdsmu_ip_blocks_names[i]);
|
||||
sc->product->ip_blocks_names[i]);
|
||||
sc->ip_block_sysctlnodes[i] = SYSCTL_ADD_NODE(sc->sysctlctx,
|
||||
SYSCTL_CHILDREN(sc->ip_blocks_sysctlnode), OID_AUTO,
|
||||
amdsmu_ip_blocks_names[i], CTLFLAG_RD, NULL, sysctl_descr);
|
||||
sc->product->ip_blocks_names[i], CTLFLAG_RD, NULL, sysctl_descr);
|
||||
if (sc->ip_block_sysctlnodes[i] == NULL) {
|
||||
device_printf(dev,
|
||||
"could not add sysctl node for \"%s\"\n", sysctl_descr);
|
||||
|
||||
+72
-26
@@ -14,7 +14,11 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/cputypes.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <x86/cputypes.h>
|
||||
|
||||
#include <dev/amdsmu/amdsmu_reg.h>
|
||||
@@ -22,26 +26,7 @@
|
||||
#define SMU_RES_READ_PERIOD_US 50
|
||||
#define SMU_RES_READ_MAX 20000
|
||||
|
||||
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_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[] = {
|
||||
static const char *amdsmu_ip_blocks_names[] = {
|
||||
"DISPLAY",
|
||||
"CPU",
|
||||
"GFX",
|
||||
@@ -66,7 +51,69 @@ static const char *const amdsmu_ip_blocks_names[] = {
|
||||
"VPE",
|
||||
};
|
||||
|
||||
CTASSERT(nitems(amdsmu_ip_blocks_names) <= 32);
|
||||
static const char *amdsmu_ip_blocks_names_v2[] = {
|
||||
"DISPLAY",
|
||||
"CPU",
|
||||
"GFX",
|
||||
"VDD",
|
||||
"VDD_CCX",
|
||||
"ACP",
|
||||
"VCN_0",
|
||||
"VCN_1",
|
||||
"ISP",
|
||||
"NBIO",
|
||||
"DF",
|
||||
"USB3_0",
|
||||
"USB3_1",
|
||||
"LAPIC",
|
||||
"USB3_2",
|
||||
"USB4_RT0",
|
||||
"USB4_RT1",
|
||||
"USB4_0",
|
||||
"USB4_1",
|
||||
"MPM",
|
||||
"JPEG_0",
|
||||
"JPEG_1",
|
||||
"IPU",
|
||||
"UMSCH",
|
||||
"VPE",
|
||||
};
|
||||
|
||||
#define IP_MAX_BLOCK_NAMES 32
|
||||
|
||||
CTASSERT(nitems(amdsmu_ip_blocks_names) <= IP_MAX_BLOCK_NAMES);
|
||||
CTASSERT(nitems(amdsmu_ip_blocks_names_v2) <= IP_MAX_BLOCK_NAMES);
|
||||
|
||||
static const struct amdsmu_product {
|
||||
uint16_t amdsmu_vendorid;
|
||||
uint16_t amdsmu_deviceid;
|
||||
uint32_t model;
|
||||
int16_t idlemask_reg;
|
||||
size_t ip_block_count;
|
||||
const char **ip_blocks_names;
|
||||
uint32_t amdsmu_msg;
|
||||
} amdsmu_products[] = {
|
||||
{ CPU_VENDOR_AMD, PCI_DEVICEID_AMD_CEZANNE_ROOT, 0x00,
|
||||
SMU_REG_IDLEMASK_CEZANNE, 12 , amdsmu_ip_blocks_names,
|
||||
SMU_REG_MSG_CEZANNE},
|
||||
{ CPU_VENDOR_AMD, PCI_DEVICEID_AMD_REMBRANDT_ROOT, 0x00,
|
||||
SMU_REG_IDLEMASK_PHOENIX, 12 , amdsmu_ip_blocks_names,
|
||||
SMU_REG_MSG_CEZANNE},
|
||||
{ CPU_VENDOR_AMD, PCI_DEVICEID_AMD_PHOENIX_ROOT, 0x00,
|
||||
SMU_REG_IDLEMASK_PHOENIX, 21 , amdsmu_ip_blocks_names,
|
||||
SMU_REG_MSG_CEZANNE},
|
||||
{ CPU_VENDOR_AMD, PCI_DEVICEID_AMD_KRACKAN_POINT_ROOT, 0x00,
|
||||
SMU_REG_IDLEMASK_KRACKAN, 22, amdsmu_ip_blocks_names,
|
||||
SMU_REG_MSG_KRACKAN },
|
||||
{ CPU_VENDOR_AMD, PCI_DEVICEID_AMD_KRACKAN_POINT_ROOT, 0x70,
|
||||
SMU_REG_IDLEMASK_KRACKAN, 25, amdsmu_ip_blocks_names_v2,
|
||||
SMU_REG_MSG_KRACKAN },
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
};
|
||||
|
||||
struct amdsmu_softc {
|
||||
const struct amdsmu_product *product;
|
||||
@@ -88,14 +135,13 @@ struct amdsmu_softc {
|
||||
|
||||
uint32_t active_ip_blocks;
|
||||
struct sysctl_oid *ip_blocks_sysctlnode;
|
||||
struct sysctl_oid *ip_block_sysctlnodes[
|
||||
nitems(amdsmu_ip_blocks_names)];
|
||||
bool ip_blocks_active[
|
||||
nitems(amdsmu_ip_blocks_names)];
|
||||
struct sysctl_oid *ip_block_sysctlnodes[IP_MAX_BLOCK_NAMES];
|
||||
bool ip_blocks_active[IP_MAX_BLOCK_NAMES];
|
||||
|
||||
bus_space_handle_t metrics_space;
|
||||
struct amdsmu_metrics metrics;
|
||||
uint32_t idlemask;
|
||||
uint32_t smu_msg;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
|
||||
@@ -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_KRACKAN_POINT_ROOT 0x1122
|
||||
#define PCI_DEVICEID_AMD_CEZANNE_ROOT 0x1630
|
||||
#define PCI_DEVICEID_AMD_REMBRANDT_ROOT 0x14B5
|
||||
#define PCI_DEVICEID_AMD_PHOENIX_ROOT 0x14E8
|
||||
@@ -28,14 +29,18 @@
|
||||
#define SMU_PHYSBASE_ADDR_HI 0x13B102EC
|
||||
|
||||
#define SMU_MEM_SIZE 0x1000
|
||||
|
||||
#define SMU_REG_SPACE_OFF 0x10000
|
||||
|
||||
#define SMU_REG_MESSAGE 0x538
|
||||
#define SMU_REG_RESPONSE 0x980
|
||||
#define SMU_REG_ARGUMENT 0x9BC
|
||||
|
||||
#define SMU_REG_IDLEMASK_CEZANNE 0x94
|
||||
#define SMU_REG_IDLEMASK_PHOENIX 0xD14
|
||||
#define SMU_REG_IDLEMASK_KRACKAN 0xF14
|
||||
|
||||
#define SMU_REG_MSG_CEZANNE 0x538
|
||||
#define SMU_REG_MSG_KRACKAN 0x938
|
||||
|
||||
enum amdsmu_res {
|
||||
SMU_RES_WAIT = 0x00,
|
||||
|
||||
Reference in New Issue
Block a user