mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
drivers:nvpps:optimize TSC align trigger freq
- use TSC lock trigger interval param from dt to optimize As per HW suggestion we should not trigger sync on every PPS edge. TSC needs atleast 2 PPS edges to align with the PTP clock. - save platform specific register offset during drv init time instead of checking plat id everytime in monitoring thread Bug 5042311 Bug 4899241 Bug 5082436 Signed-off-by: Sheetal Tigadoli <stigadoli@nvidia.com> Change-Id: I22befbc2a52c22ace1a8573b9a34a544ed1ae8f9 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3294329 (cherry picked from commit 209dc26eddd2cd5e9d88ea8c6eb603706cd3c3f0) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3292322 Reviewed-by: Amlan Kundu <akundu@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Jon Hunter
parent
61ba5d28d0
commit
ef2e125868
@@ -91,9 +91,12 @@ struct nvpps_device_data {
|
||||
bool support_tsc;
|
||||
uint32_t soc_id;
|
||||
void (*ptp_tsc_sync_cfg_fn)(struct platform_device *pdata);
|
||||
uint32_t lck_sts_offset;
|
||||
uint32_t lck_ctrl_offset;
|
||||
uint8_t k_int_val;
|
||||
uint32_t lock_threshold_val;
|
||||
uint32_t pps_freq;
|
||||
uint32_t lck_trig_interval;
|
||||
struct hte_ts_desc desc;
|
||||
struct gpio_desc *gpio_in;
|
||||
};
|
||||
@@ -208,6 +211,13 @@ static struct device_node *emac_node;
|
||||
|
||||
#define _NANO_SECS (1000000000ULL)
|
||||
|
||||
/* Macro defines the interval(in PPS edge cnt) at which PTP-TSC lock is triggered */
|
||||
#define DEFAULT_TSC_LOCK_TRIGGER_INTERVAL 1U
|
||||
/* Macro defines the Min interval(in PPS edge cnt) at which PTP-TSC lock is triggered */
|
||||
#define MIN_TSC_LOCK_TRIGGER_INTERVAL 1U
|
||||
/* Macro defines the Max interval(in PPS edge cnt) at which PTP-TSC lock is triggered */
|
||||
#define MAX_TSC_LOCK_TRIGGER_INTERVAL 8U
|
||||
|
||||
enum {
|
||||
NV_SOC_T19X = 0U,
|
||||
NV_SOC_T23X,
|
||||
@@ -223,6 +233,8 @@ struct tegra_chip_data {
|
||||
bool support_tsc;
|
||||
uint32_t soc_id;
|
||||
void (*ptp_tsc_sync_cfg_fn)(struct platform_device *pdata);
|
||||
uint32_t lck_sts_offset;
|
||||
uint32_t lck_ctrl_offset;
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
|
||||
@@ -415,31 +427,23 @@ static void tsc_timer_callback(struct timer_list *t)
|
||||
{
|
||||
struct nvpps_device_data *pdev_data = (struct nvpps_device_data *)from_timer(pdev_data, t, tsc_timer);
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) */
|
||||
uint32_t lck_sts_offset = 0;
|
||||
uint32_t lck_ctrl_offset = 0;
|
||||
uint32_t reg_val = 0;
|
||||
|
||||
if (pdev_data->soc_id == NV_SOC_T26X) {
|
||||
lck_sts_offset = T26X_TSC_LOCKING_STATUS_OFFSET;
|
||||
lck_ctrl_offset = T26X_TSC_LOCKING_CONTROL_OFFSET;
|
||||
} else if (pdev_data->soc_id == NV_SOC_T23X) {
|
||||
lck_sts_offset = T23X_TSC_LOCKING_STATUS_OFFSET;
|
||||
lck_ctrl_offset = T23X_TSC_LOCKING_CONTROL_OFFSET;
|
||||
} else {
|
||||
if (pdev_data->soc_id == NV_SOC_T19X) {
|
||||
/* We should not be reaching here */
|
||||
dev_err(pdev_data->dev, "Invalid SOC ID\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
reg_val = readl(pdev_data->tsc_reg_map_base + lck_sts_offset);
|
||||
reg_val = readl(pdev_data->tsc_reg_map_base + pdev_data->lck_sts_offset);
|
||||
|
||||
if ((reg_val & BIT(TSC_LOCKED_STATUS_BIT_OFFSET)) == 0) {
|
||||
writel((BIT(TSC_LOCKED_STATUS_BIT_OFFSET) | BIT(TSC_ALIGNED_STATUS_BIT_OFFSET)), pdev_data->tsc_reg_map_base + lck_sts_offset);
|
||||
writel(BIT(TSC_LOCK_CTRL_ALIGN_BIT_OFFSET), pdev_data->tsc_reg_map_base + lck_ctrl_offset);
|
||||
writel((BIT(TSC_LOCKED_STATUS_BIT_OFFSET) | BIT(TSC_ALIGNED_STATUS_BIT_OFFSET)), pdev_data->tsc_reg_map_base + pdev_data->lck_sts_offset);
|
||||
writel(BIT(TSC_LOCK_CTRL_ALIGN_BIT_OFFSET), pdev_data->tsc_reg_map_base + pdev_data->lck_ctrl_offset);
|
||||
}
|
||||
|
||||
/* set the next expire time */
|
||||
mod_timer(&pdev_data->tsc_timer, jiffies + msecs_to_jiffies(TSC_POLL_TIMER/pdev_data->pps_freq));
|
||||
mod_timer(&pdev_data->tsc_timer, jiffies + msecs_to_jiffies((TSC_POLL_TIMER / pdev_data->pps_freq) * pdev_data->lck_trig_interval));
|
||||
}
|
||||
|
||||
|
||||
@@ -986,7 +990,10 @@ static void nvpps_t26x_ptp_tsc_sync_config(struct platform_device *pdev)
|
||||
if ((pdev_data->lock_threshold_val < MIN_T26X_LOCK_THRESHOLD_1NS) ||
|
||||
(pdev_data->lock_threshold_val > MAX_T26X_LOCK_THRESHOLD_16MS)) {
|
||||
//Use default value
|
||||
dev_warn(&pdev->dev, "ptp_tsc_lock_threshold value should be minimum 1ns(i.e 0x1). Using default value 20us(i.e 20000ns)\n");
|
||||
dev_warn(&pdev->dev,
|
||||
"Invalid input for ptp_tsc_lock_threshold dt property. Supported range : %u to %u. "
|
||||
"Using default value 20us(i.e 20000ns)\n",
|
||||
MIN_T26X_LOCK_THRESHOLD_1NS, MAX_T26X_LOCK_THRESHOLD_16MS);
|
||||
pdev_data->lock_threshold_val = DEFAULT_T26X_LOCK_THRESHOLD_20US;
|
||||
}
|
||||
}
|
||||
@@ -1192,6 +1199,8 @@ static int nvpps_probe(struct platform_device *pdev)
|
||||
pdev_data->support_tsc = cdata->support_tsc;
|
||||
pdev_data->soc_id = cdata->soc_id;
|
||||
pdev_data->ptp_tsc_sync_cfg_fn = cdata->ptp_tsc_sync_cfg_fn;
|
||||
pdev_data->lck_sts_offset = cdata->lck_sts_offset;
|
||||
pdev_data->lck_ctrl_offset = cdata->lck_ctrl_offset;
|
||||
|
||||
nvpps_fill_default_mac_phc_info(pdev, pdev_data);
|
||||
|
||||
@@ -1306,6 +1315,22 @@ static int nvpps_probe(struct platform_device *pdev)
|
||||
|
||||
/* skip PTP TSC sync configuration if `ptp_tsc_sync_dis` is set */
|
||||
if ((of_property_read_bool(np, "ptp_tsc_sync_dis")) == false) {
|
||||
/* read tsc lock trigger interval from dt */
|
||||
index = of_property_read_u32(np, "ptp_tsc_sync_trig_interval", &pdev_data->lck_trig_interval);
|
||||
if (index < 0) {
|
||||
dev_info(&pdev->dev,
|
||||
"using default value 1 for `ptp_tsc_sync_trig_interval` i.e On every PPS edge,"
|
||||
" Alignment is triggered if TSC is not synchronized to PTP\n");
|
||||
pdev_data->lck_trig_interval = DEFAULT_TSC_LOCK_TRIGGER_INTERVAL;
|
||||
}
|
||||
if ((pdev_data->lck_trig_interval < MIN_TSC_LOCK_TRIGGER_INTERVAL) ||
|
||||
(pdev_data->lck_trig_interval > MAX_TSC_LOCK_TRIGGER_INTERVAL)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Invalid input provided for ptp_tsc_sync_trig_interval. Allowed range is %u - %u\n",
|
||||
MIN_TSC_LOCK_TRIGGER_INTERVAL, MAX_TSC_LOCK_TRIGGER_INTERVAL);
|
||||
err = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
if (pdev_data->ptp_tsc_sync_cfg_fn != NULL)
|
||||
pdev_data->ptp_tsc_sync_cfg_fn(pdev);
|
||||
} else {
|
||||
@@ -1383,16 +1408,22 @@ static const struct tegra_chip_data tegra264_chip_data = {
|
||||
.support_tsc = true,
|
||||
.soc_id = NV_SOC_T26X,
|
||||
.ptp_tsc_sync_cfg_fn = &nvpps_t26x_ptp_tsc_sync_config,
|
||||
.lck_sts_offset = T26X_TSC_LOCKING_STATUS_OFFSET,
|
||||
.lck_ctrl_offset = T26X_TSC_LOCKING_CONTROL_OFFSET,
|
||||
};
|
||||
static const struct tegra_chip_data tegra234_chip_data = {
|
||||
.support_tsc = true,
|
||||
.soc_id = NV_SOC_T23X,
|
||||
.ptp_tsc_sync_cfg_fn = &nvpps_t23x_ptp_tsc_sync_config,
|
||||
.lck_sts_offset = T23X_TSC_LOCKING_STATUS_OFFSET,
|
||||
.lck_ctrl_offset = T23X_TSC_LOCKING_CONTROL_OFFSET,
|
||||
};
|
||||
static const struct tegra_chip_data tegra194_chip_data = {
|
||||
.support_tsc = false,
|
||||
.soc_id = NV_SOC_T19X,
|
||||
.ptp_tsc_sync_cfg_fn = NULL,
|
||||
.lck_sts_offset = (uint32_t)(~0),
|
||||
.lck_ctrl_offset = (uint32_t)(~0),
|
||||
};
|
||||
static const struct of_device_id nvpps_of_table[] = {
|
||||
{ .compatible = "nvidia,tegra194-nvpps", .data = &tegra194_chip_data },
|
||||
|
||||
Reference in New Issue
Block a user