mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
habanalabs: add opcode to INFO IOCTL to return clock rate
Add a new opcode to the INFO IOCTL to allow the user application to retrieve the ASIC's current and maximum clock rate. The rate is returned in MHz. Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com> Reviewed-by: Tomer Tayar <ttayar@habana.ai>
This commit is contained in:
parent
8fdacf2a53
commit
62c1e124a9
6 changed files with 74 additions and 6 deletions
|
@ -5148,7 +5148,8 @@ static const struct hl_asic_funcs goya_funcs = {
|
|||
.init_iatu = goya_init_iatu,
|
||||
.rreg = hl_rreg,
|
||||
.wreg = hl_wreg,
|
||||
.halt_coresight = goya_halt_coresight
|
||||
.halt_coresight = goya_halt_coresight,
|
||||
.get_clk_rate = goya_get_clk_rate
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -233,4 +233,6 @@ void goya_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size,
|
|||
void *vaddr);
|
||||
void goya_mmu_remove_device_cpu_mappings(struct hl_device *hdev);
|
||||
|
||||
int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk);
|
||||
|
||||
#endif /* GOYAP_H_ */
|
||||
|
|
|
@ -32,6 +32,37 @@ void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
|
|||
}
|
||||
}
|
||||
|
||||
int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
|
||||
{
|
||||
long value;
|
||||
|
||||
if (hl_device_disabled_or_in_reset(hdev))
|
||||
return -ENODEV;
|
||||
|
||||
value = hl_get_frequency(hdev, MME_PLL, false);
|
||||
|
||||
if (value < 0) {
|
||||
dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n",
|
||||
value);
|
||||
return value;
|
||||
}
|
||||
|
||||
*max_clk = (value / 1000 / 1000);
|
||||
|
||||
value = hl_get_frequency(hdev, MME_PLL, true);
|
||||
|
||||
if (value < 0) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to retrieve device current clock %ld\n",
|
||||
value);
|
||||
return value;
|
||||
}
|
||||
|
||||
*cur_clk = (value / 1000 / 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
|
|
|
@ -508,6 +508,7 @@ enum hl_pll_frequency {
|
|||
* @rreg: Read a register. Needed for simulator support.
|
||||
* @wreg: Write a register. Needed for simulator support.
|
||||
* @halt_coresight: stop the ETF and ETR traces.
|
||||
* @get_clk_rate: Retrieve the ASIC current and maximum clock rate in MHz
|
||||
*/
|
||||
struct hl_asic_funcs {
|
||||
int (*early_init)(struct hl_device *hdev);
|
||||
|
@ -590,6 +591,7 @@ struct hl_asic_funcs {
|
|||
u32 (*rreg)(struct hl_device *hdev, u32 reg);
|
||||
void (*wreg)(struct hl_device *hdev, u32 reg, u32 val);
|
||||
void (*halt_coresight)(struct hl_device *hdev);
|
||||
int (*get_clk_rate)(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -221,6 +221,25 @@ static int device_utilization(struct hl_device *hdev, struct hl_info_args *args)
|
|||
min((size_t) max_size, sizeof(device_util))) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int get_clk_rate(struct hl_device *hdev, struct hl_info_args *args)
|
||||
{
|
||||
struct hl_info_clk_rate clk_rate = {0};
|
||||
u32 max_size = args->return_size;
|
||||
void __user *out = (void __user *) (uintptr_t) args->return_pointer;
|
||||
int rc;
|
||||
|
||||
if ((!max_size) || (!out))
|
||||
return -EINVAL;
|
||||
|
||||
rc = hdev->asic_funcs->get_clk_rate(hdev, &clk_rate.cur_clk_rate_mhz,
|
||||
&clk_rate.max_clk_rate_mhz);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return copy_to_user(out, &clk_rate,
|
||||
min((size_t) max_size, sizeof(clk_rate))) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
|
||||
struct device *dev)
|
||||
{
|
||||
|
@ -271,6 +290,10 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
|
|||
rc = hw_events_info(hdev, true, args);
|
||||
break;
|
||||
|
||||
case HL_INFO_CLK_RATE:
|
||||
rc = get_clk_rate(hdev, args);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(dev, "Invalid request %d\n", args->op);
|
||||
rc = -ENOTTY;
|
||||
|
|
|
@ -88,13 +88,16 @@ enum hl_device_status {
|
|||
* internal engine.
|
||||
* HL_INFO_DEVICE_STATUS - Retrieve the device's status. This opcode doesn't
|
||||
* require an open context.
|
||||
* HL_INFO_DEVICE_UTILIZATION - Retrieve the total utilization of the device
|
||||
* over the last period specified by the user.
|
||||
* The period can be between 100ms to 1s, in
|
||||
* resolution of 100ms. The return value is a
|
||||
* percentage of the utilization rate.
|
||||
* HL_INFO_DEVICE_UTILIZATION - Retrieve the total utilization of the device
|
||||
* over the last period specified by the user.
|
||||
* The period can be between 100ms to 1s, in
|
||||
* resolution of 100ms. The return value is a
|
||||
* percentage of the utilization rate.
|
||||
* HL_INFO_HW_EVENTS_AGGREGATE - Receive an array describing how many times each
|
||||
* event occurred since the driver was loaded.
|
||||
* HL_INFO_CLK_RATE - Retrieve the current and maximum clock rate
|
||||
* of the device in MHz. The maximum clock rate is
|
||||
* configurable via sysfs parameter
|
||||
*/
|
||||
#define HL_INFO_HW_IP_INFO 0
|
||||
#define HL_INFO_HW_EVENTS 1
|
||||
|
@ -103,6 +106,7 @@ enum hl_device_status {
|
|||
#define HL_INFO_DEVICE_STATUS 4
|
||||
#define HL_INFO_DEVICE_UTILIZATION 6
|
||||
#define HL_INFO_HW_EVENTS_AGGREGATE 7
|
||||
#define HL_INFO_CLK_RATE 8
|
||||
|
||||
#define HL_INFO_VERSION_MAX_LEN 128
|
||||
|
||||
|
@ -149,6 +153,11 @@ struct hl_info_device_utilization {
|
|||
__u32 pad;
|
||||
};
|
||||
|
||||
struct hl_info_clk_rate {
|
||||
__u32 cur_clk_rate_mhz;
|
||||
__u32 max_clk_rate_mhz;
|
||||
};
|
||||
|
||||
struct hl_info_args {
|
||||
/* Location of relevant struct in userspace */
|
||||
__u64 return_pointer;
|
||||
|
|
Loading…
Reference in a new issue