mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
drivers:nvpps:cleanup & modularize driver code structure
cleanup & modularize driver code structure to separate out HW dependent & independent parts to facilitate adding support for new SoCs This patch - restructure SoC specific code into separate files - Add function pointers to call HW specific sequences - adds a common header which is needed by all platforms - cleans up obsolete code such as memmap of phc regs, xavier support, etc - Removes default value assumption for lock_threshold, pps_freq, sync_trig_interval Bug 5175333 Change-Id: I106e130fdaa1a166a4a2c9bbaeb3b924af90ab66 Signed-off-by: Sheetal Tigadoli <stigadoli@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3321185 Reviewed-by: Kiran Kumar Bobbu <kbobbu@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
This commit is contained in:
committed by
Jon Hunter
parent
b656843df9
commit
262f358456
@@ -1,10 +1,10 @@
|
|||||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
#
|
#
|
||||||
# NVPPS driver and PTP Framework.
|
# NVPPS driver and PTP Framework.
|
||||||
#
|
#
|
||||||
|
|
||||||
nvpps-y := nvpps_main.o ptp-notifier.o
|
nvpps-y := nvpps_main.o ptp-notifier.o nvpps_t26x.o nvpps_t23x.o
|
||||||
|
|
||||||
obj-m := nvpps.o
|
obj-m := nvpps.o
|
||||||
|
|||||||
64
drivers/nvpps/nvpps_common.h
Normal file
64
drivers/nvpps/nvpps_common.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
#ifndef __NVPPS_COMMON_H__
|
||||||
|
#define __NVPPS_COMMON_H__
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <asm/arch_timer.h>
|
||||||
|
#include <linux/platform/tegra/ptp-notifier.h>
|
||||||
|
|
||||||
|
struct soc_dev_data;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NV_SOC_T23X = 0U,
|
||||||
|
NV_SOC_T26X,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chip specific ops
|
||||||
|
* @soc_id: chip id (NV_SOC_T23X or NV_SOC_T26X)
|
||||||
|
* @ptp_tsc_sync_cfg_fn: function pointer for PTP-TSC sync related TSC HW configuration
|
||||||
|
* @ptp_tsc_synchronize_fn: function pointer for triggering PTP-TSC synchronization
|
||||||
|
* @ptp_tsc_get_is_locked_fn: function pointer to get PTP-TSC sync status, return boolean true if PTP & TSC are synced else return boolean false
|
||||||
|
* @ptp_tsc_suspend_sync_fn: function pointer for suspending PTP-TSC synchronization
|
||||||
|
* @ptp_tsc_resume_sync_fn: function pointer for resuming PTP-TSC synchronization
|
||||||
|
* @get_monotonic_tsc_ts_fn: function pointer to get TSC monotonic timestamp in TSC Cycles, This API can be called in isr context
|
||||||
|
* @get_tsc_res_ns_fn: function pointer to get TSC resolution in nanoseconds
|
||||||
|
* @get_ptp_tsc_concurrent_ts_ns_fn: function pointer to get PTP-TSC concurrent timestamps in nanosecs, This API can be called in isr context
|
||||||
|
* @get_ptp_ts_ns_fn: function pointer to get PTP timestamp in nanoseconds, This API can be called in isr context
|
||||||
|
*/
|
||||||
|
struct chip_ops {
|
||||||
|
uint32_t soc_id;
|
||||||
|
int32_t (*ptp_tsc_sync_cfg_fn)(struct soc_dev_data *soc_data);
|
||||||
|
void (*ptp_tsc_synchronize_fn)(struct soc_dev_data *soc_data);
|
||||||
|
bool (*ptp_tsc_get_is_locked_fn)(struct soc_dev_data *soc_data);
|
||||||
|
int32_t (*ptp_tsc_suspend_sync_fn)(struct soc_dev_data *soc_data);
|
||||||
|
int32_t (*ptp_tsc_resume_sync_fn)(struct soc_dev_data *soc_data);
|
||||||
|
int32_t (*get_monotonic_tsc_ts_fn)(struct soc_dev_data *soc_data, uint64_t *tsc_ts);
|
||||||
|
int32_t (*get_tsc_res_ns_fn)(struct soc_dev_data *soc_data, uint64_t *tsc_res_ns);
|
||||||
|
int32_t (*get_ptp_ts_ns_fn)(struct device_node *mac_node, uint64_t *ptp_ts);
|
||||||
|
int32_t (*get_ptp_tsc_concurrent_ts_ns_fn)(struct device_node *mac_node, struct ptp_tsc_data *data);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct soc_dev_data {
|
||||||
|
/* nvpps device */
|
||||||
|
struct device *dev;
|
||||||
|
/* chip specific ops */
|
||||||
|
const struct chip_ops *ops;
|
||||||
|
/* Variable to hold mmapped addr of TSC registers */
|
||||||
|
void __iomem *reg_map_base;
|
||||||
|
/* Variable to hold base pa of primary MAC interface */
|
||||||
|
uint64_t pri_mac_base_pa;
|
||||||
|
/* variable to hold configured lock threshold value
|
||||||
|
* which is to be programmed in the TSC register
|
||||||
|
*/
|
||||||
|
uint32_t lock_threshold_val;
|
||||||
|
/* variable which defines the number of the pulse per second of
|
||||||
|
* input signal, from MAC interface to TSC
|
||||||
|
*/
|
||||||
|
uint32_t pps_freq;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __NVPPS_COMMON_H__ */
|
||||||
File diff suppressed because it is too large
Load Diff
293
drivers/nvpps/nvpps_t23x.c
Normal file
293
drivers/nvpps/nvpps_t23x.c
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include "nvpps_t23x.h"
|
||||||
|
|
||||||
|
/* T23X Registers */
|
||||||
|
#define T23X_TSC_STSCRSR_OFFSET 0x104
|
||||||
|
#define T23X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x58)
|
||||||
|
#define T23X_TSC_CAPTURE_CONTROL_PTX_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x5c)
|
||||||
|
#define T23X_TSC_LOCKING_CONFIGURATION_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0xe4)
|
||||||
|
#define T23X_TSC_LOCKING_CONTROL_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0xe8)
|
||||||
|
#define T23X_TSC_LOCKING_STATUS_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0xec)
|
||||||
|
#define T23X_TSC_LOCKING_REF_FREQUENCY_CONFIGURATION_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0xf0)
|
||||||
|
#define T23X_TSC_LOCKING_DIFF_CONFIGURATION_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0xf4)
|
||||||
|
#define T23X_TSC_LOCKING_ADJUST_CONFIGURATION_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x108)
|
||||||
|
#define T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x10c)
|
||||||
|
#define T23X_TSC_LOCKING_ADJUST_NUM_CONTROL_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x110)
|
||||||
|
#define T23X_TSC_LOCKING_ADJUST_DELTA_CONTROL_OFFSET (T23X_TSC_STSCRSR_OFFSET + 0x114)
|
||||||
|
|
||||||
|
|
||||||
|
#define T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_THRSLD_SHIFT 16U
|
||||||
|
#define T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_K_INT_SHIFT 8U
|
||||||
|
#define T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_M_SHIFT 4U
|
||||||
|
#define T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_EN_SHIFT 0U
|
||||||
|
|
||||||
|
#define T23X_TSC_LOCKED_STATUS_BIT_OFFSET 1U
|
||||||
|
#define T23X_TSC_ALIGNED_STATUS_BIT_OFFSET 0U
|
||||||
|
#define T23X_TSC_LOCK_CTRL_ALIGN_BIT_OFFSET 0U
|
||||||
|
|
||||||
|
#define T23X_DEFAULT_REF_FREQ_INC_1S 0x1DCD650 /* 1s expressed in tick count */
|
||||||
|
|
||||||
|
#define T23X_MIN_LOCK_THRESHOLD_1US 0x1FU
|
||||||
|
#define T23X_MAX_LOCK_THRESHOLD_2MS 0xFFFFU
|
||||||
|
|
||||||
|
|
||||||
|
#define T23X_TSC_CAPTURE_CONFIG_SRC_SELECT_SHIFT 8U
|
||||||
|
#define T23X_TSC_CAPTURE_CONFIG_SRC_SELECT_MASK 0xffU
|
||||||
|
|
||||||
|
/* Default K_INT nominal value used to calculate gain factor */
|
||||||
|
#define T23X_DEFAULT_K_INT_NOM_VAL 371U
|
||||||
|
|
||||||
|
#define T23X_MAX_K_INT_VAL 0xFF
|
||||||
|
#define T23X_MAX_M_VAL 0x3
|
||||||
|
|
||||||
|
/* Number of MAC interface available to sync with TSC */
|
||||||
|
#define T23X_MAC_INTERFACE_CNT 5
|
||||||
|
/* MAC interface physical base addr */
|
||||||
|
#define T23X_EQOS_MAC_BASE_PA 0x2310000u
|
||||||
|
#define T23X_MGBE0_MAC_BASE_PA 0x6810000u
|
||||||
|
#define T23X_MGBE1_MAC_BASE_PA 0x6910000u
|
||||||
|
#define T23X_MGBE2_MAC_BASE_PA 0x6a10000u
|
||||||
|
#define T23X_MGBE3_MAC_BASE_PA 0x6b10000u
|
||||||
|
|
||||||
|
/* HW info mapping table */
|
||||||
|
typedef struct {
|
||||||
|
uint64_t mac_base_pa;
|
||||||
|
uint8_t tsc_src_idx;
|
||||||
|
} t23x_hw_info_t;
|
||||||
|
|
||||||
|
static const t23x_hw_info_t t23x_hw_info_arr[T23X_MAC_INTERFACE_CNT] = {
|
||||||
|
{T23X_EQOS_MAC_BASE_PA, 0},
|
||||||
|
{T23X_MGBE0_MAC_BASE_PA, 1},
|
||||||
|
{T23X_MGBE1_MAC_BASE_PA, 2},
|
||||||
|
{T23X_MGBE2_MAC_BASE_PA, 3},
|
||||||
|
{T23X_MGBE3_MAC_BASE_PA, 4}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_validate_input_params(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
/* Check if PPS frequency is within valid range:
|
||||||
|
* - Supported frequencies are 1Hz, 2Hz and 4Hz
|
||||||
|
* - Value 0 is invalid (no PPS signal)
|
||||||
|
* - Value 3Hz is invalid (must be power of 2)
|
||||||
|
* - Values > 4Hz are invalid (hardware limitation)
|
||||||
|
*/
|
||||||
|
if ((soc_data->pps_freq > 4U) ||
|
||||||
|
(soc_data->pps_freq == 0U) ||
|
||||||
|
(soc_data->pps_freq == 3U)) { // supporting max allow value 1 to 4
|
||||||
|
dev_err(soc_data->dev, "Invalid PPS(%uHz) freq input provided. Supported PPS frequencies are 1, 2, and 4Hz\n", soc_data->pps_freq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert to usec */
|
||||||
|
soc_data->lock_threshold_val = (soc_data->lock_threshold_val / 1000U);
|
||||||
|
/* convert to Reg programmable value */
|
||||||
|
soc_data->lock_threshold_val = (soc_data->lock_threshold_val * T23X_MIN_LOCK_THRESHOLD_1US);
|
||||||
|
|
||||||
|
/* Check if lock threshold value is within valid range:
|
||||||
|
* Minimum: 0x1F (1us)
|
||||||
|
* Maximum: 0xFFFF (2.11ms)
|
||||||
|
*/
|
||||||
|
if ((soc_data->lock_threshold_val < T23X_MIN_LOCK_THRESHOLD_1US) ||
|
||||||
|
(soc_data->lock_threshold_val > T23X_MAX_LOCK_THRESHOLD_2MS)) {
|
||||||
|
dev_err(soc_data->dev,
|
||||||
|
"Invalid input provided for ptp_tsc_lock_threshold. Refer binding doc for valid range\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_ptp_tsc_sync_config(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
uint32_t tsc_config_ptx_0;
|
||||||
|
uint8_t tsc_src_idx;
|
||||||
|
uint32_t k = 0, m = 0;
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
if (nvpps_t23x_validate_input_params(soc_data)) {
|
||||||
|
dev_err(soc_data->dev, "DT param validation failed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < T23X_MAC_INTERFACE_CNT; i++) {
|
||||||
|
if (t23x_hw_info_arr[i].mac_base_pa == soc_data->pri_mac_base_pa) {
|
||||||
|
tsc_src_idx = t23x_hw_info_arr[i].tsc_src_idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == T23X_MAC_INTERFACE_CNT) {
|
||||||
|
dev_err(soc_data->dev, "Primary MAC provided is not listed as PPS source to TSC\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* k is calculated as below and is coded as k = (K_INT << M) */
|
||||||
|
k = T23X_DEFAULT_K_INT_NOM_VAL * soc_data->pps_freq;
|
||||||
|
|
||||||
|
while ((k > T23X_MAX_K_INT_VAL) && (m < T23X_MAX_M_VAL)) {
|
||||||
|
k = k >> 1;
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//onetime config to init PTP TSC Sync logic
|
||||||
|
writel(0x119, soc_data->reg_map_base + T23X_TSC_LOCKING_CONFIGURATION_OFFSET);
|
||||||
|
writel(soc_data->lock_threshold_val, soc_data->reg_map_base + T23X_TSC_LOCKING_DIFF_CONFIGURATION_OFFSET);
|
||||||
|
writel(0x1, soc_data->reg_map_base + T23X_TSC_LOCKING_CONTROL_OFFSET);
|
||||||
|
writel((0x50001 | (k << T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_K_INT_SHIFT) |
|
||||||
|
(m << T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_M_SHIFT)),
|
||||||
|
soc_data->reg_map_base + T23X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET);
|
||||||
|
writel(0x67, soc_data->reg_map_base + T23X_TSC_LOCKING_ADJUST_DELTA_CONTROL_OFFSET);
|
||||||
|
writel(0x313, soc_data->reg_map_base + T23X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
writel(0x1, soc_data->reg_map_base + T23X_TSC_STSCRSR_OFFSET);
|
||||||
|
/* Configure LOCKING_REF_FREQ_CONFIG register */
|
||||||
|
writel((T23X_DEFAULT_REF_FREQ_INC_1S/soc_data->pps_freq), soc_data->reg_map_base + T23X_TSC_LOCKING_REF_FREQUENCY_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
tsc_config_ptx_0 = readl(soc_data->reg_map_base + T23X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
/* clear and set the ptp src based on ethernet interface passed
|
||||||
|
* from dt for tsc to lock onto.
|
||||||
|
*/
|
||||||
|
tsc_config_ptx_0 = tsc_config_ptx_0 & ~(T23X_TSC_CAPTURE_CONFIG_SRC_SELECT_MASK << T23X_TSC_CAPTURE_CONFIG_SRC_SELECT_SHIFT);
|
||||||
|
tsc_config_ptx_0 = tsc_config_ptx_0 | (tsc_src_idx << T23X_TSC_CAPTURE_CONFIG_SRC_SELECT_SHIFT);
|
||||||
|
writel(tsc_config_ptx_0, soc_data->reg_map_base + T23X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
tsc_config_ptx_0 = readl(soc_data->reg_map_base + T23X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool nvpps_t23x_ptp_tsc_get_is_locked(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
bool lck_sts = false;
|
||||||
|
uint32_t reg_val = readl(soc_data->reg_map_base + T23X_TSC_LOCKING_STATUS_OFFSET);
|
||||||
|
|
||||||
|
if ((reg_val & BIT(T23X_TSC_LOCKED_STATUS_BIT_OFFSET)) != 0) {
|
||||||
|
lck_sts = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lck_sts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvpps_t23x_ptp_tsc_synchronize(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
writel((BIT(T23X_TSC_LOCKED_STATUS_BIT_OFFSET) | BIT(T23X_TSC_ALIGNED_STATUS_BIT_OFFSET)), soc_data->reg_map_base + T23X_TSC_LOCKING_STATUS_OFFSET);
|
||||||
|
writel(BIT(T23X_TSC_LOCK_CTRL_ALIGN_BIT_OFFSET), soc_data->reg_map_base + T23X_TSC_LOCKING_CONTROL_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_ptp_tsc_suspend_sync(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
/* Stub implementation */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_ptp_tsc_resume_sync(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
/* Stub implementation */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_get_tsc_res_ns(struct soc_dev_data *soc_data, uint64_t *tsc_res_ns)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (tsc_res_ns == NULL) {
|
||||||
|
dev_err(soc_data->dev, "NULL input passed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _PICO_SECS (1000000000000ULL)
|
||||||
|
*tsc_res_ns = (_PICO_SECS / (u64)arch_timer_get_cntfrq()) / 1000;
|
||||||
|
#undef _PICO_SECS
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
static inline u64 __arch_counter_get_cntvct(void)
|
||||||
|
{
|
||||||
|
u64 cval;
|
||||||
|
|
||||||
|
asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
|
||||||
|
|
||||||
|
return cval;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) */
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_get_monotonic_tsc_ts(struct soc_dev_data *soc_data, uint64_t *tsc_ts)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (tsc_ts == NULL) {
|
||||||
|
dev_err(soc_data->dev, "NULL input passed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tsc_ts = __arch_counter_get_cntvct();
|
||||||
|
if (*tsc_ts == 0) {
|
||||||
|
dev_err(soc_data->dev, "Invalid monotonic Time\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_get_ptp_ts_ns(struct device_node *mac_node, uint64_t *ptp_ts)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
ret = tegra_get_hwtime(mac_node, ptp_ts, PTP_HWTIME);
|
||||||
|
if (ret) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t23x_get_ptp_tsc_concurrent_ts_ns(struct device_node *mac_node, struct ptp_tsc_data *data)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
ret = tegra_get_hwtime(mac_node, data, PTP_TSC_HWTIME);
|
||||||
|
if (ret) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NVPPS_NO_DT
|
||||||
|
const struct chip_ops tegra234_chip_ops = {
|
||||||
|
.soc_id = NV_SOC_T23X,
|
||||||
|
.ptp_tsc_sync_cfg_fn = &nvpps_t23x_ptp_tsc_sync_config,
|
||||||
|
.ptp_tsc_synchronize_fn = &nvpps_t23x_ptp_tsc_synchronize,
|
||||||
|
.ptp_tsc_get_is_locked_fn = &nvpps_t23x_ptp_tsc_get_is_locked,
|
||||||
|
.ptp_tsc_suspend_sync_fn = &nvpps_t23x_ptp_tsc_suspend_sync,
|
||||||
|
.ptp_tsc_resume_sync_fn = &nvpps_t23x_ptp_tsc_resume_sync,
|
||||||
|
.get_monotonic_tsc_ts_fn = &nvpps_t23x_get_monotonic_tsc_ts,
|
||||||
|
.get_tsc_res_ns_fn = &nvpps_t23x_get_tsc_res_ns,
|
||||||
|
.get_ptp_ts_ns_fn = &nvpps_t23x_get_ptp_ts_ns,
|
||||||
|
.get_ptp_tsc_concurrent_ts_ns_fn = &nvpps_t23x_get_ptp_tsc_concurrent_ts_ns,
|
||||||
|
};
|
||||||
|
#endif /* NVPPS_NO_DT */
|
||||||
13
drivers/nvpps/nvpps_t23x.h
Normal file
13
drivers/nvpps/nvpps_t23x.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
#ifndef __NVPPS_T23X_H__
|
||||||
|
#define __NVPPS_T23X_H__
|
||||||
|
|
||||||
|
#include "nvpps_common.h"
|
||||||
|
|
||||||
|
#ifndef NVPPS_NO_DT
|
||||||
|
extern const struct chip_ops tegra234_chip_ops;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NVPPS_T23X_H__ */
|
||||||
335
drivers/nvpps/nvpps_t26x.c
Normal file
335
drivers/nvpps/nvpps_t26x.c
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include "nvpps_t26x.h"
|
||||||
|
|
||||||
|
/* T26X Registers */
|
||||||
|
#define T26X_TSC_STSCRSR_OFFSET 0x104
|
||||||
|
#define T26X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0x58)
|
||||||
|
#define T26X_TSC_CAPTURE_CONTROL_PTX_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0x5c)
|
||||||
|
#define T26X_TSC_LOCKING_CONFIGURATION_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0xe4)
|
||||||
|
#define T26X_TSC_LOCKING_CONTROL_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0xe8)
|
||||||
|
#define T26X_TSC_LOCKING_STATUS_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0xec)
|
||||||
|
#define T26X_TSC_LOCKING_REF_FREQUENCY_CONFIGURATION_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0xf0)
|
||||||
|
#define T26X_TSC_LOCKING_DIFF_CONFIGURATION_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0xfc)
|
||||||
|
//M field is 6:4, 6th bit is addition in Thor
|
||||||
|
#define T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0x128)
|
||||||
|
#define T26X_TSC_LOCKING_ADJUST_DELTA_CONTROL_OFFSET (T26X_TSC_STSCRSR_OFFSET + 0x130)
|
||||||
|
|
||||||
|
#define T26X_TSC_LOCKING_CONFIG_PPS_SRC_PTX 0x1
|
||||||
|
|
||||||
|
#define T26X_TSC_LOCKING_CONFIG_SRC_SEL_SHIFT 8U
|
||||||
|
#define T26X_TSC_LOCKING_CONFIG_EDGE_SEL_SHIFT 4U
|
||||||
|
#define T26X_TSC_LOCKING_CONFIG_EN_SHIFT 0U
|
||||||
|
|
||||||
|
#define T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_THRSLD_SHIFT 16U
|
||||||
|
#define T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_K_INT_SHIFT 8U
|
||||||
|
#define T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_M_SHIFT 4U
|
||||||
|
#define T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_EN_SHIFT 0U
|
||||||
|
|
||||||
|
#define T26X_TSC_CAPTURE_CONFIG_EDGE_SHIFT 4U
|
||||||
|
#define T26X_TSC_CAPTURE_CONFIG_EN_SHIFT 0U
|
||||||
|
|
||||||
|
#define T26X_TSC_LOCKED_STATUS_BIT_OFFSET 1U
|
||||||
|
#define T26X_TSC_ALIGNED_STATUS_BIT_OFFSET 0U
|
||||||
|
|
||||||
|
#define T26X_TSC_LOCK_CTRL_ALIGN_BIT_OFFSET 0U
|
||||||
|
|
||||||
|
#define T26X_CAPTURE_CONFIG_SRC_SELECT_SHIFT 8U
|
||||||
|
|
||||||
|
#define CONFIG_RISING_EDGE 0x1
|
||||||
|
|
||||||
|
#define T26X_MIN_LOCK_THRESHOLD_1NS 0x1
|
||||||
|
#define T26X_MAX_LOCK_THRESHOLD_16MS 0xFFFFFF
|
||||||
|
|
||||||
|
/* DELTA INCREMENT value to add/remove(in slow convergence case) from current adjust value */
|
||||||
|
#define T26X_DEFAULT_DELTA_INC_STEP 0x67U
|
||||||
|
/* THRESHOLD used in determining when FAST ADJUST Convergence is to be applied by HW */
|
||||||
|
#define T26X_DEFAULT_FAST_ADJ_THRSLD 0x64U
|
||||||
|
|
||||||
|
/* Default K_INT nominal value used to calculate gain factor.
|
||||||
|
* The actual float Knominal value is 2.485, for calculation purpose this is converted to int by multiplying with 1000
|
||||||
|
*/
|
||||||
|
#define T26X_DEFAULT_K_INT_NOM_VAL 2485U
|
||||||
|
|
||||||
|
#define T26X_DEFAULT_REF_FREQ_INC_1S 1000000000 /* 1s expressed in ns */
|
||||||
|
|
||||||
|
/* Number of MAC interface available to sync with TSC */
|
||||||
|
#define T26X_MAC_INTERFACE_CNT 5
|
||||||
|
/* MAC interface physical base addr */
|
||||||
|
#define T26X_EQOS_MAC_BASE_PA 0xa808910000
|
||||||
|
#define T26X_MGBE0_MAC_BASE_PA 0xa808a10000
|
||||||
|
#define T26X_MGBE1_MAC_BASE_PA 0xa808b10000
|
||||||
|
#define T26X_MGBE2_MAC_BASE_PA 0xa808d10000
|
||||||
|
#define T26X_MGBE3_MAC_BASE_PA 0xa808e10000
|
||||||
|
|
||||||
|
/* HW info mapping table */
|
||||||
|
typedef struct {
|
||||||
|
uint64_t mac_base_pa;
|
||||||
|
uint8_t tsc_src_idx;
|
||||||
|
} t26x_hw_info_t;
|
||||||
|
|
||||||
|
static const t26x_hw_info_t t26x_hw_info_arr[T26X_MAC_INTERFACE_CNT] = {
|
||||||
|
{T26X_EQOS_MAC_BASE_PA, 0},
|
||||||
|
{T26X_MGBE0_MAC_BASE_PA, 1},
|
||||||
|
{T26X_MGBE1_MAC_BASE_PA, 2},
|
||||||
|
{T26X_MGBE2_MAC_BASE_PA, 3},
|
||||||
|
{T26X_MGBE3_MAC_BASE_PA, 4}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_validate_input_params(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
/* Check if PPS frequency is:
|
||||||
|
* - Greater than max allowed value of 8Hz
|
||||||
|
* - Value 0 is invalid (no PPS signal)
|
||||||
|
* - Value 3Hz, 6Hz, 7Hz are invalid (must be power of 2 or 5)
|
||||||
|
* Only frequencies of 1, 2, 4, 5 and 8Hz are supported
|
||||||
|
*/
|
||||||
|
if ((soc_data->pps_freq > 8U) ||
|
||||||
|
(soc_data->pps_freq == 0U) ||
|
||||||
|
(soc_data->pps_freq == 3U) ||
|
||||||
|
(soc_data->pps_freq == 6U) ||
|
||||||
|
(soc_data->pps_freq == 7U)) { // supporting max allow value 1 to 8
|
||||||
|
dev_err(soc_data->dev,
|
||||||
|
"Invalid PPS(%uHz) freq input provided. Supported PPS frequencies are 1, 2, 4, 5 and 8Hz\n", soc_data->pps_freq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if lock threshold value is within valid range:
|
||||||
|
* Minimum: 0x1 (1ns)
|
||||||
|
* Maximum: 0xFFFFFF (16ms)
|
||||||
|
*/
|
||||||
|
if ((soc_data->lock_threshold_val < T26X_MIN_LOCK_THRESHOLD_1NS) ||
|
||||||
|
(soc_data->lock_threshold_val > T26X_MAX_LOCK_THRESHOLD_16MS)) {
|
||||||
|
dev_err(soc_data->dev,
|
||||||
|
"Invalid input provided for ptp_tsc_lock_threshold. Refer binding doc for valid range\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_ptp_tsc_sync_config(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
uint32_t reg_val = 0;
|
||||||
|
uint32_t k = 0, i;
|
||||||
|
uint8_t tsc_src_idx;
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (nvpps_t26x_validate_input_params(soc_data)) {
|
||||||
|
dev_err(soc_data->dev, "DT param validation failed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < T26X_MAC_INTERFACE_CNT; i++) {
|
||||||
|
if (t26x_hw_info_arr[i].mac_base_pa == soc_data->pri_mac_base_pa) {
|
||||||
|
tsc_src_idx = t26x_hw_info_arr[i].tsc_src_idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == T26X_MAC_INTERFACE_CNT) {
|
||||||
|
dev_err(soc_data->dev, "Primary MAC provided is not listed as PPS source to TSC\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure LOCKING_CONFIGURATION register */
|
||||||
|
/* Select PTX as PPS Source & Rising edge as edge select */
|
||||||
|
reg_val = ((T26X_TSC_LOCKING_CONFIG_PPS_SRC_PTX << T26X_TSC_LOCKING_CONFIG_SRC_SEL_SHIFT) |
|
||||||
|
(CONFIG_RISING_EDGE << T26X_TSC_LOCKING_CONFIG_EDGE_SEL_SHIFT));
|
||||||
|
|
||||||
|
writel(reg_val, soc_data->reg_map_base + T26X_TSC_LOCKING_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
/* Configure LOCKING_DIFF_CONFIGURATION register with lock threshold value */
|
||||||
|
dev_info(soc_data->dev, "Using Lock threshold value(in ns) : %u\n", soc_data->lock_threshold_val);
|
||||||
|
|
||||||
|
writel(soc_data->lock_threshold_val, soc_data->reg_map_base + T26X_TSC_LOCKING_DIFF_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
|
||||||
|
/* Configure LOCKING_ADJSUT_DELTA_CONTROL register */
|
||||||
|
writel(T26X_DEFAULT_DELTA_INC_STEP, soc_data->reg_map_base + T26X_TSC_LOCKING_ADJUST_DELTA_CONTROL_OFFSET);
|
||||||
|
|
||||||
|
/* Configure LOCKING_FAST_ADJUST_CONFIG register */
|
||||||
|
|
||||||
|
/* round off the calculated K_int value to nearest integer */
|
||||||
|
k = ((((T26X_DEFAULT_K_INT_NOM_VAL * soc_data->pps_freq) % 1000) >= 500) ? 1 : 0);
|
||||||
|
k = k + ((T26X_DEFAULT_K_INT_NOM_VAL * soc_data->pps_freq) / 1000);
|
||||||
|
|
||||||
|
/* Set THRESHOLD, K_INT, M and ENABLE bits */
|
||||||
|
reg_val = ((T26X_DEFAULT_FAST_ADJ_THRSLD << T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_THRSLD_SHIFT) |
|
||||||
|
(k << T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_K_INT_SHIFT) |
|
||||||
|
(0 << T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_M_SHIFT) | /* M = 0 always */
|
||||||
|
(BIT(T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET_EN_SHIFT)));
|
||||||
|
|
||||||
|
writel(reg_val, soc_data->reg_map_base + T26X_TSC_LOCKING_FAST_ADJUST_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
/* Configure LOCKING_REF_FREQ_CONFIG register */
|
||||||
|
|
||||||
|
writel((T26X_DEFAULT_REF_FREQ_INC_1S/soc_data->pps_freq), soc_data->reg_map_base + T26X_TSC_LOCKING_REF_FREQUENCY_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
/* Configure CAPTURE_CONFIGURATION_PTX register */
|
||||||
|
/* Select PPS src MAC */
|
||||||
|
reg_val = (tsc_src_idx << T26X_CAPTURE_CONFIG_SRC_SELECT_SHIFT);
|
||||||
|
/* Use PPS Rising EDGE to capture TSC values */
|
||||||
|
reg_val = (reg_val | (CONFIG_RISING_EDGE << T26X_TSC_CAPTURE_CONFIG_EDGE_SHIFT));
|
||||||
|
|
||||||
|
writel(reg_val, soc_data->reg_map_base + T26X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
|
||||||
|
|
||||||
|
/* Configure CAPTURE_CONTROL register */
|
||||||
|
/* Enable updating capture value registers on PPS edge */
|
||||||
|
writel(0x1, soc_data->reg_map_base + T26X_TSC_CAPTURE_CONTROL_PTX_OFFSET);
|
||||||
|
|
||||||
|
/* Configure T26X_TSC_LOCKING_CONFIG register */
|
||||||
|
/* Enable HW LOCKING Mechanism */
|
||||||
|
reg_val = readl(soc_data->reg_map_base + T26X_TSC_LOCKING_CONFIGURATION_OFFSET);
|
||||||
|
reg_val = (reg_val | BIT(T26X_TSC_LOCKING_CONFIG_EN_SHIFT));
|
||||||
|
writel(reg_val, soc_data->reg_map_base + T26X_TSC_LOCKING_CONFIGURATION_OFFSET);
|
||||||
|
|
||||||
|
/* Configure T26X_TSC_CAPTURE_CONFIG register */
|
||||||
|
/* Enable ability to feed the HW Lock mechanism */
|
||||||
|
reg_val = readl(soc_data->reg_map_base + T26X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
reg_val = (reg_val | BIT(T26X_TSC_CAPTURE_CONFIG_EN_SHIFT));
|
||||||
|
writel(reg_val, soc_data->reg_map_base + T26X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
|
||||||
|
reg_val = readl(soc_data->reg_map_base + T26X_TSC_CAPTURE_CONFIGURATION_PTX_OFFSET);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool nvpps_t26x_ptp_tsc_get_is_locked(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
bool lck_sts = false;
|
||||||
|
uint32_t reg_val = readl(soc_data->reg_map_base + T26X_TSC_LOCKING_STATUS_OFFSET);
|
||||||
|
|
||||||
|
if ((reg_val & BIT(T26X_TSC_LOCKED_STATUS_BIT_OFFSET)) != 0) {
|
||||||
|
lck_sts = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lck_sts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvpps_t26x_ptp_tsc_synchronize(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
writel((BIT(T26X_TSC_LOCKED_STATUS_BIT_OFFSET) | BIT(T26X_TSC_ALIGNED_STATUS_BIT_OFFSET)), soc_data->reg_map_base + T26X_TSC_LOCKING_STATUS_OFFSET);
|
||||||
|
writel(BIT(T26X_TSC_LOCK_CTRL_ALIGN_BIT_OFFSET), soc_data->reg_map_base + T26X_TSC_LOCKING_CONTROL_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_ptp_tsc_suspend_sync(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
/* Stub implementation */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_ptp_tsc_resume_sync(struct soc_dev_data *soc_data)
|
||||||
|
{
|
||||||
|
/* Stub implementation */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_get_tsc_res_ns(struct soc_dev_data *soc_data, uint64_t *tsc_res_ns)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (tsc_res_ns == NULL) {
|
||||||
|
dev_err(soc_data->dev, "NULL input passed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _PICO_SECS (1000000000000ULL)
|
||||||
|
*tsc_res_ns = (_PICO_SECS / (u64)arch_timer_get_cntfrq()) / 1000;
|
||||||
|
#undef _PICO_SECS
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||||
|
static inline u64 __arch_counter_get_cntvct(void)
|
||||||
|
{
|
||||||
|
u64 cval;
|
||||||
|
|
||||||
|
asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
|
||||||
|
|
||||||
|
return cval;
|
||||||
|
}
|
||||||
|
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) */
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_get_monotonic_tsc_ts(struct soc_dev_data *soc_data, uint64_t *tsc_ts)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (tsc_ts == NULL) {
|
||||||
|
dev_err(soc_data->dev, "NULL input passed\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tsc_ts = __arch_counter_get_cntvct();
|
||||||
|
|
||||||
|
if (*tsc_ts == 0) {
|
||||||
|
dev_err(soc_data->dev, "Invalid monotonic Time\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_get_ptp_ts_ns(struct device_node *mac_node, uint64_t *ptp_ts)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
ret = tegra_get_hwtime(mac_node, ptp_ts, PTP_HWTIME);
|
||||||
|
if (ret) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nvpps_t26x_get_ptp_tsc_concurrent_ts_ns(struct device_node *mac_node, struct ptp_tsc_data *data)
|
||||||
|
{
|
||||||
|
int32_t ret = -EINVAL;
|
||||||
|
|
||||||
|
ret = tegra_get_hwtime(mac_node, data, PTP_TSC_HWTIME);
|
||||||
|
if (ret) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NVPPS_NO_DT
|
||||||
|
/* Define the tegra264_chip_data structure */
|
||||||
|
const struct chip_ops tegra264_chip_ops = {
|
||||||
|
.soc_id = NV_SOC_T26X,
|
||||||
|
.ptp_tsc_sync_cfg_fn = &nvpps_t26x_ptp_tsc_sync_config,
|
||||||
|
.ptp_tsc_synchronize_fn = &nvpps_t26x_ptp_tsc_synchronize,
|
||||||
|
.ptp_tsc_get_is_locked_fn = &nvpps_t26x_ptp_tsc_get_is_locked,
|
||||||
|
.ptp_tsc_suspend_sync_fn = &nvpps_t26x_ptp_tsc_suspend_sync,
|
||||||
|
.ptp_tsc_resume_sync_fn = &nvpps_t26x_ptp_tsc_resume_sync,
|
||||||
|
.get_monotonic_tsc_ts_fn = &nvpps_t26x_get_monotonic_tsc_ts,
|
||||||
|
.get_tsc_res_ns_fn = &nvpps_t26x_get_tsc_res_ns,
|
||||||
|
.get_ptp_ts_ns_fn = &nvpps_t26x_get_ptp_ts_ns,
|
||||||
|
.get_ptp_tsc_concurrent_ts_ns_fn = &nvpps_t26x_get_ptp_tsc_concurrent_ts_ns,
|
||||||
|
};
|
||||||
|
#endif /* NVPPS_NO_DT */
|
||||||
13
drivers/nvpps/nvpps_t26x.h
Normal file
13
drivers/nvpps/nvpps_t26x.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
|
#ifndef __NVPPS_T26X_H__
|
||||||
|
#define __NVPPS_T26X_H__
|
||||||
|
|
||||||
|
#include "nvpps_common.h"
|
||||||
|
|
||||||
|
#ifndef NVPPS_NO_DT
|
||||||
|
extern const struct chip_ops tegra264_chip_ops;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NVPPS_T26X_H__ */
|
||||||
Reference in New Issue
Block a user