Commit 25e7aeba authored by Tomer Tayar's avatar Tomer Tayar Committed by Oded Gabbay

habanalabs: Add INFO IOCTL opcode for time sync information

Add a new opcode to the INFO IOCTL that retrieves the device time
alongside the host time, to allow a user application that want to measure
device time together with host time (such as a profiler) to synchronize
these times.
Signed-off-by: default avatarTomer Tayar <ttayar@habana.ai>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent ba7193c9
...@@ -5200,6 +5200,13 @@ static void goya_set_dma_mask_from_fw(struct hl_device *hdev) ...@@ -5200,6 +5200,13 @@ static void goya_set_dma_mask_from_fw(struct hl_device *hdev)
} }
} }
u64 goya_get_device_time(struct hl_device *hdev)
{
u64 device_time = ((u64) RREG32(mmPSOC_TIMESTAMP_CNTCVU)) << 32;
return device_time | RREG32(mmPSOC_TIMESTAMP_CNTCVL);
}
static const struct hl_asic_funcs goya_funcs = { static const struct hl_asic_funcs goya_funcs = {
.early_init = goya_early_init, .early_init = goya_early_init,
.early_fini = goya_early_fini, .early_fini = goya_early_fini,
...@@ -5263,7 +5270,8 @@ static const struct hl_asic_funcs goya_funcs = { ...@@ -5263,7 +5270,8 @@ static const struct hl_asic_funcs goya_funcs = {
.get_queue_id_for_cq = goya_get_queue_id_for_cq, .get_queue_id_for_cq = goya_get_queue_id_for_cq,
.read_device_fw_version = goya_read_device_fw_version, .read_device_fw_version = goya_read_device_fw_version,
.load_firmware_to_device = goya_load_firmware_to_device, .load_firmware_to_device = goya_load_firmware_to_device,
.set_dma_mask_from_fw = goya_set_dma_mask_from_fw .set_dma_mask_from_fw = goya_set_dma_mask_from_fw,
.get_device_time = goya_get_device_time
}; };
/* /*
......
...@@ -231,5 +231,6 @@ void goya_mmu_remove_device_cpu_mappings(struct hl_device *hdev); ...@@ -231,5 +231,6 @@ 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); int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk);
u32 goya_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx); u32 goya_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx);
u64 goya_get_device_time(struct hl_device *hdev);
#endif /* GOYAP_H_ */ #endif /* GOYAP_H_ */
...@@ -554,6 +554,7 @@ enum hl_pll_frequency { ...@@ -554,6 +554,7 @@ enum hl_pll_frequency {
* @load_firmware_to_device: load the firmware to the device's memory * @load_firmware_to_device: load the firmware to the device's memory
* @set_dma_mask_from_fw: set the DMA mask in the driver according to the * @set_dma_mask_from_fw: set the DMA mask in the driver according to the
* firmware configuration * firmware configuration
* @get_device_time: Get the device time.
*/ */
struct hl_asic_funcs { struct hl_asic_funcs {
int (*early_init)(struct hl_device *hdev); int (*early_init)(struct hl_device *hdev);
...@@ -646,6 +647,7 @@ struct hl_asic_funcs { ...@@ -646,6 +647,7 @@ struct hl_asic_funcs {
enum hl_fw_component fwc); enum hl_fw_component fwc);
int (*load_firmware_to_device)(struct hl_device *hdev); int (*load_firmware_to_device)(struct hl_device *hdev);
void (*set_dma_mask_from_fw)(struct hl_device *hdev); void (*set_dma_mask_from_fw)(struct hl_device *hdev);
u64 (*get_device_time)(struct hl_device *hdev);
}; };
......
...@@ -258,6 +258,22 @@ static int get_reset_count(struct hl_device *hdev, struct hl_info_args *args) ...@@ -258,6 +258,22 @@ static int get_reset_count(struct hl_device *hdev, struct hl_info_args *args)
min((size_t) max_size, sizeof(reset_count))) ? -EFAULT : 0; min((size_t) max_size, sizeof(reset_count))) ? -EFAULT : 0;
} }
static int time_sync_info(struct hl_device *hdev, struct hl_info_args *args)
{
struct hl_info_time_sync time_sync = {0};
u32 max_size = args->return_size;
void __user *out = (void __user *) (uintptr_t) args->return_pointer;
if ((!max_size) || (!out))
return -EINVAL;
time_sync.device_time = hdev->asic_funcs->get_device_time(hdev);
time_sync.host_time = ktime_get_raw_ns();
return copy_to_user(out, &time_sync,
min((size_t) max_size, sizeof(time_sync))) ? -EFAULT : 0;
}
static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
struct device *dev) struct device *dev)
{ {
...@@ -315,6 +331,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, ...@@ -315,6 +331,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
rc = get_clk_rate(hdev, args); rc = get_clk_rate(hdev, args);
break; break;
case HL_INFO_TIME_SYNC:
return time_sync_info(hdev, args);
default: default:
dev_err(dev, "Invalid request %d\n", args->op); dev_err(dev, "Invalid request %d\n", args->op);
rc = -ENOTTY; rc = -ENOTTY;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "psoc_mme_pll_regs.h" #include "psoc_mme_pll_regs.h"
#include "psoc_pci_pll_regs.h" #include "psoc_pci_pll_regs.h"
#include "psoc_emmc_pll_regs.h" #include "psoc_emmc_pll_regs.h"
#include "psoc_timestamp_regs.h"
#include "cpu_if_regs.h" #include "cpu_if_regs.h"
#include "cpu_ca53_cfg_regs.h" #include "cpu_ca53_cfg_regs.h"
#include "cpu_pll_regs.h" #include "cpu_pll_regs.h"
......
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright 2016-2018 HabanaLabs, Ltd.
* All Rights Reserved.
*
*/
/************************************
** This is an auto-generated file **
** DO NOT EDIT BELOW **
************************************/
#ifndef ASIC_REG_PSOC_TIMESTAMP_REGS_H_
#define ASIC_REG_PSOC_TIMESTAMP_REGS_H_
/*
*****************************************
* PSOC_TIMESTAMP (Prototype: TIMESTAMP)
*****************************************
*/
#define mmPSOC_TIMESTAMP_CNTCR 0xC49000
#define mmPSOC_TIMESTAMP_CNTSR 0xC49004
#define mmPSOC_TIMESTAMP_CNTCVL 0xC49008
#define mmPSOC_TIMESTAMP_CNTCVU 0xC4900C
#define mmPSOC_TIMESTAMP_CNTFID0 0xC49020
#define mmPSOC_TIMESTAMP_PIDR4 0xC49FD0
#define mmPSOC_TIMESTAMP_PIDR5 0xC49FD4
#define mmPSOC_TIMESTAMP_PIDR6 0xC49FD8
#define mmPSOC_TIMESTAMP_PIDR7 0xC49FDC
#define mmPSOC_TIMESTAMP_PIDR0 0xC49FE0
#define mmPSOC_TIMESTAMP_PIDR1 0xC49FE4
#define mmPSOC_TIMESTAMP_PIDR2 0xC49FE8
#define mmPSOC_TIMESTAMP_PIDR3 0xC49FEC
#define mmPSOC_TIMESTAMP_CIDR0 0xC49FF0
#define mmPSOC_TIMESTAMP_CIDR1 0xC49FF4
#define mmPSOC_TIMESTAMP_CIDR2 0xC49FF8
#define mmPSOC_TIMESTAMP_CIDR3 0xC49FFC
#endif /* ASIC_REG_PSOC_TIMESTAMP_REGS_H_ */
...@@ -101,6 +101,8 @@ enum hl_device_status { ...@@ -101,6 +101,8 @@ enum hl_device_status {
* HL_INFO_RESET_COUNT - Retrieve the counts of the soft and hard reset * HL_INFO_RESET_COUNT - Retrieve the counts of the soft and hard reset
* operations performed on the device since the last * operations performed on the device since the last
* time the driver was loaded. * time the driver was loaded.
* HL_INFO_TIME_SYNC - Retrieve the device's time alongside the host's time
* for synchronization.
*/ */
#define HL_INFO_HW_IP_INFO 0 #define HL_INFO_HW_IP_INFO 0
#define HL_INFO_HW_EVENTS 1 #define HL_INFO_HW_EVENTS 1
...@@ -111,6 +113,7 @@ enum hl_device_status { ...@@ -111,6 +113,7 @@ enum hl_device_status {
#define HL_INFO_HW_EVENTS_AGGREGATE 7 #define HL_INFO_HW_EVENTS_AGGREGATE 7
#define HL_INFO_CLK_RATE 8 #define HL_INFO_CLK_RATE 8
#define HL_INFO_RESET_COUNT 9 #define HL_INFO_RESET_COUNT 9
#define HL_INFO_TIME_SYNC 10
#define HL_INFO_VERSION_MAX_LEN 128 #define HL_INFO_VERSION_MAX_LEN 128
#define HL_INFO_CARD_NAME_MAX_LEN 16 #define HL_INFO_CARD_NAME_MAX_LEN 16
...@@ -169,6 +172,11 @@ struct hl_info_reset_count { ...@@ -169,6 +172,11 @@ struct hl_info_reset_count {
__u32 soft_reset_cnt; __u32 soft_reset_cnt;
}; };
struct hl_info_time_sync {
__u64 device_time;
__u64 host_time;
};
struct hl_info_args { struct hl_info_args {
/* Location of relevant struct in userspace */ /* Location of relevant struct in userspace */
__u64 return_pointer; __u64 return_pointer;
......
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