]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
habanalabs: add opcode to INFO IOCTL to return clock rate
authorOded Gabbay <oded.gabbay@gmail.com>
Thu, 10 Oct 2019 12:48:59 +0000 (15:48 +0300)
committerOded Gabbay <oded.gabbay@gmail.com>
Thu, 21 Nov 2019 09:35:45 +0000 (11:35 +0200)
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>
drivers/misc/habanalabs/goya/goya.c
drivers/misc/habanalabs/goya/goyaP.h
drivers/misc/habanalabs/goya/goya_hwmgr.c
drivers/misc/habanalabs/habanalabs.h
drivers/misc/habanalabs/habanalabs_ioctl.c
include/uapi/misc/habanalabs.h

index d49f5ecd903b37477cdfca9aaac10f5d167c8467..ac574d18c139ff58100db29ebb9e20f86d28146f 100644 (file)
@@ -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
 };
 
 /*
index 89b6574f8e4ffc65e799c0defc8c7b1a471967a1..c3230cb6e25c4b0572c8876b1b26bb69479e5a24 100644 (file)
@@ -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_ */
index a2a700c3d5970fb88c7815df1f419ba520ddfadc..b2ebc01e27f40c3c48cde432778fa52b854dee48 100644 (file)
@@ -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)
 {
index 91445371b08ba2b92a6bc7d57a32779b335de58f..4ff2da8596530249af2ce5ab2000140dbd40f73f 100644 (file)
@@ -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);
 };
 
 
index 66d9c710073c64491b04ae8c863d69ff6675919d..cd4b5a9ceac163b9d257adaff2f9363f89f87f1d 100644 (file)
@@ -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;
index 53e4ff73578e7c3bd0f806eaa6251ce8d6c557c0..783793c8be1c8e1e6782df8071b5261b88037e8a 100644 (file)
@@ -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;