Skip to content

Commit

Permalink
BH: Expose non-hwmon telemetry in sysfs
Browse files Browse the repository at this point in the history
- Augment telemetry discovery to support board id, some FW versions, and
  SOC clock speeds.
- Partially integrate with existing mechanism for exposing non-hwmon
  metrics in sysfs, but provide Blackhole-specific "show"
  implementations.
  • Loading branch information
joelsmithTT committed Jan 22, 2025
1 parent d871572 commit 198b850
Showing 1 changed file with 85 additions and 1 deletion.
86 changes: 85 additions & 1 deletion blackhole.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@
#define ARC_TELEMETRY_DATA RESET_SCRATCH(12)

// These are from ARC FW telemetry.h, guaranteed not to change
#define TELEMETRY_BOARD_ID 1
#define TELEMETRY_VCORE 6
#define TELEMETRY_POWER 7
#define TELEMETRY_CURRENT 8
#define TELEMETRY_ASIC_TEMP 11
#define TELEMETRY_AICLK 14
#define TELEMETRY_AXICLK 15
#define TELEMETRY_ARCCLK 16
#define TELEMETRY_BM_APP_FW_VERSION 26
#define TELEMETRY_FLASH_BUNDLE_VERSION 28

struct TLB_2M_REG {
union {
Expand Down Expand Up @@ -120,6 +126,74 @@ static struct blackhole_hwmon_attr bh_hwmon_attrs[] = {
{ TELEMETRY_POWER, hwmon_power, hwmon_power_input, 0x0 },
};

static ssize_t bh_show_attribute(struct device *dev, struct device_attribute *attr, char *buf) {
struct tenstorrent_device *tt_dev = dev_get_drvdata(dev);
struct blackhole_device *bh = tt_dev_to_bh_dev(tt_dev);
struct tt_attribute_data *data = container_of(attr, struct tt_attribute_data, attr);
u32 addr = data->reg_offset;
u32 value = 0;

if (addr != 0)
value = noc_read32(bh, ARC_X, ARC_Y, addr);

return sprintf(buf, "%u\n", value);
}

static ssize_t bh_show_card_serial(struct device *dev, struct device_attribute *attr, char *buf) {
struct tenstorrent_device *tt_dev = dev_get_drvdata(dev);
struct blackhole_device *bh = tt_dev_to_bh_dev(tt_dev);
struct tt_attribute_data *data = container_of(attr, struct tt_attribute_data, attr);
u32 addr = data->reg_offset;
u32 board_id_hi = 0;
u32 board_id_lo = 0;

if (addr != 0) {
board_id_hi = noc_read32(bh, ARC_X, ARC_Y, addr + 0);
board_id_lo = noc_read32(bh, ARC_X, ARC_Y, addr + 4);
}
return scnprintf(buf, PAGE_SIZE, "%08X%08X\n", board_id_hi, board_id_lo);
}

static ssize_t bh_show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) {
struct tenstorrent_device *tt_dev = dev_get_drvdata(dev);
struct tt_attribute_data *data = container_of(attr, struct tt_attribute_data, attr);
struct blackhole_device *bh = tt_dev_to_bh_dev(tt_dev);
u32 addr = data->reg_offset;
u32 fw_ver = 0;
u32 major, minor, patch, ver;

if (addr != 0)
fw_ver = noc_read32(bh, ARC_X, ARC_Y, addr);

major = (fw_ver >> 24) & 0xFF;
minor = (fw_ver >> 16) & 0xFF;
patch = (fw_ver >> 8) & 0xFF;
ver = fw_ver & 0xFF;
return scnprintf(buf, PAGE_SIZE, "%u.%u.%u.%u\n", major, minor, patch, ver);
}

// Addresses are set by telemetry_probe
static struct tt_attribute_data bh_attributes[] = {
{ __ATTR(tt_aiclk, S_IRUGO, bh_show_attribute, NULL) },
{ __ATTR(tt_axiclk, S_IRUGO, bh_show_attribute, NULL) },
{ __ATTR(tt_arcclk, S_IRUGO, bh_show_attribute, NULL) },
{ __ATTR(tt_serial, S_IRUGO, bh_show_card_serial, NULL) },
{ __ATTR(tt_m3app_fw_ver, S_IRUGO, bh_show_fw_ver, NULL) },
{ __ATTR(tt_fw_bundle_ver, S_IRUGO, bh_show_fw_ver, NULL) },
{ __ATTR_NULL }
};

// Must match bh_attributes array
static int bh_attributes_ids[] = {
TELEMETRY_AICLK,
TELEMETRY_AXICLK,
TELEMETRY_ARCCLK,
TELEMETRY_BOARD_ID,
TELEMETRY_BM_APP_FW_VERSION,
TELEMETRY_FLASH_BUNDLE_VERSION,
-1,
};

static umode_t bh_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr, int channel) {
int i;

Expand Down Expand Up @@ -218,20 +292,30 @@ static int telemetry_probe(struct tenstorrent_device *tt_dev) {
u16 offset = (tag_entry >> 16) & 0xFFFF;
u32 addr = data_addr + (offset * 4);

// Check if this tag is one hwmon cares about
// First, check if this tag is one hwmon cares about
for (j = 0; j < ARRAY_SIZE(bh_hwmon_attrs); ++j) {
if (bh_hwmon_attrs[j].tag_id == tag_id) {
bh_hwmon_attrs[j].addr = addr;
break;
}
}

// Check if it's a device attribute we will expose in sysfs
for (j = 0; j < ARRAY_SIZE(bh_attributes_ids); ++j) {
if (bh_attributes_ids[j] == tag_id) {
bh_attributes[j].reg_offset = addr;
break;
}
}
}

hwmon_device = devm_hwmon_device_register_with_info(&bh->tt.pdev->dev, "blackhole", bh, &bh_hwmon_chip_info, NULL);

if (IS_ERR(hwmon_device))
return PTR_ERR(hwmon_device);

tt_dev->attributes = bh_attributes;

return 0;
}

Expand Down

0 comments on commit 198b850

Please sign in to comment.