Commit 2b28485d authored by Rajaravi Krishna Katta's avatar Rajaravi Krishna Katta Committed by Oded Gabbay

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: default avatarRajaravi Krishna Katta <rkatta@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 2ee58fee
...@@ -2956,6 +2956,10 @@ int hl_set_voltage(struct hl_device *hdev, ...@@ -2956,6 +2956,10 @@ int hl_set_voltage(struct hl_device *hdev,
int sensor_index, u32 attr, long value); int sensor_index, u32 attr, long value);
int hl_set_current(struct hl_device *hdev, int hl_set_current(struct hl_device *hdev,
int sensor_index, u32 attr, long value); 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_get(struct hl_hw_sob *hw_sob);
void hw_sob_put(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); 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, ...@@ -236,6 +236,23 @@ static int hl_read(struct device *dev, enum hwmon_sensor_types type,
else else
rc = hl_get_pwm_info(hdev, channel, attr, val); rc = hl_get_pwm_info(hdev, channel, attr, val);
break; 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: default:
return -EINVAL; return -EINVAL;
} }
...@@ -316,6 +333,20 @@ static int hl_write(struct device *dev, enum hwmon_sensor_types type, ...@@ -316,6 +333,20 @@ static int hl_write(struct device *dev, enum hwmon_sensor_types type,
else else
hl_set_current(hdev, channel, attr, val); hl_set_current(hdev, channel, attr, val);
break; 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: default:
return -EINVAL; return -EINVAL;
} }
...@@ -378,6 +409,15 @@ static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type, ...@@ -378,6 +409,15 @@ static umode_t hl_is_visible(const void *data, enum hwmon_sensor_types type,
return 0644; return 0644;
} }
break; 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: default:
break; break;
} }
...@@ -633,6 +673,60 @@ int hl_set_current(struct hl_device *hdev, ...@@ -633,6 +673,60 @@ int hl_set_current(struct hl_device *hdev,
return rc; 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) int hl_hwmon_init(struct hl_device *hdev)
{ {
struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev; struct device *dev = hdev->pdev ? &hdev->pdev->dev : hdev->dev;
......
...@@ -598,6 +598,16 @@ enum cpucp_pll_type_attributes { ...@@ -598,6 +598,16 @@ enum cpucp_pll_type_attributes {
cpucp_pll_pci, 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. * MSI type enumeration table for all ASICs and future SW versions.
* For future ASIC-LKD compatibility, we can only add new enumerations. * For future ASIC-LKD compatibility, we can only add new enumerations.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment