forked from Minki/linux
habanalabs: enable power info via HWMON framework
Add support to retrieve following power info via HWMON: - instantaneous power value - highest value since last reset - reset the highest place holder Signed-off-by: Rajaravi Krishna Katta <rkatta@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
2ee58fee3f
commit
2b28485d0a
@ -2956,6 +2956,10 @@ int hl_set_voltage(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long value);
|
||||
int hl_set_current(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long value);
|
||||
int hl_set_power(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long value);
|
||||
int hl_get_power(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long *value);
|
||||
void hw_sob_get(struct hl_hw_sob *hw_sob);
|
||||
void hw_sob_put(struct hl_hw_sob *hw_sob);
|
||||
void hl_encaps_handle_do_release(struct kref *ref);
|
||||
|
@ -236,6 +236,23 @@ static int hl_read(struct device *dev, enum hwmon_sensor_types type,
|
||||
else
|
||||
rc = hl_get_pwm_info(hdev, channel, attr, val);
|
||||
break;
|
||||
case hwmon_power:
|
||||
switch (attr) {
|
||||
case hwmon_power_input:
|
||||
cpucp_attr = CPUCP_POWER_INPUT;
|
||||
break;
|
||||
case hwmon_power_input_highest:
|
||||
cpucp_attr = CPUCP_POWER_INPUT_HIGHEST;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (use_cpucp_enum)
|
||||
rc = hl_get_power(hdev, channel, cpucp_attr, val);
|
||||
else
|
||||
rc = hl_get_power(hdev, channel, attr, val);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -316,6 +333,20 @@ static int hl_write(struct device *dev, enum hwmon_sensor_types type,
|
||||
else
|
||||
hl_set_current(hdev, channel, attr, val);
|
||||
break;
|
||||
case hwmon_power:
|
||||
switch (attr) {
|
||||
case hwmon_power_reset_history:
|
||||
cpucp_attr = CPUCP_POWER_RESET_INPUT_HISTORY;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (use_cpucp_enum)
|
||||
hl_set_power(hdev, channel, cpucp_attr, val);
|
||||
else
|
||||
hl_set_power(hdev, channel, attr, val);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -378,6 +409,15 @@ static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
|
||||
return 0644;
|
||||
}
|
||||
break;
|
||||
case hwmon_power:
|
||||
switch (attr) {
|
||||
case hwmon_power_input:
|
||||
case hwmon_power_input_highest:
|
||||
return 0444;
|
||||
case hwmon_power_reset_history:
|
||||
return 0200;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -633,6 +673,60 @@ int hl_set_current(struct hl_device *hdev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_set_power(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long value)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
int rc;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
|
||||
CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.sensor_index = __cpu_to_le16(sensor_index);
|
||||
pkt.type = __cpu_to_le16(attr);
|
||||
pkt.value = __cpu_to_le64(value);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
0, NULL);
|
||||
|
||||
if (rc)
|
||||
dev_err(hdev->dev,
|
||||
"Failed to set power of sensor %d, error %d\n",
|
||||
sensor_index, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_get_power(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long *value)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
u64 result;
|
||||
int rc;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_POWER_GET <<
|
||||
CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.sensor_index = __cpu_to_le16(sensor_index);
|
||||
pkt.type = __cpu_to_le16(attr);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
0, &result);
|
||||
|
||||
*value = (long) result;
|
||||
|
||||
if (rc) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to get power of sensor %d, error %d\n",
|
||||
sensor_index, rc);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_hwmon_init(struct hl_device *hdev)
|
||||
{
|
||||
struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
|
||||
|
@ -598,6 +598,16 @@ enum cpucp_pll_type_attributes {
|
||||
cpucp_pll_pci,
|
||||
};
|
||||
|
||||
/*
|
||||
* cpucp_power_type aligns with hwmon_power_attributes
|
||||
* defined in Linux kernel hwmon.h file
|
||||
*/
|
||||
enum cpucp_power_type {
|
||||
CPUCP_POWER_INPUT = 8,
|
||||
CPUCP_POWER_INPUT_HIGHEST = 9,
|
||||
CPUCP_POWER_RESET_INPUT_HISTORY = 11
|
||||
};
|
||||
|
||||
/*
|
||||
* MSI type enumeration table for all ASICs and future SW versions.
|
||||
* For future ASIC-LKD compatibility, we can only add new enumerations.
|
||||
|
Loading…
Reference in New Issue
Block a user