Skip to content

Commit 92d3690

Browse files
committed
Merge branch 'add-perout-configuration-support-in-iep-driver'
Meghana Malladi says: ==================== Add perout configuration support in IEP driver IEP driver supported both perout and pps signal generation but perout feature is faulty with half-cooked support due to some missing configuration. Hence perout feature is removed as a bug fix. This patch series adds back this feature which configures perout signal based on the arguments passed by the perout request. This patch series is continuation to the bug fix: https://lore.kernel.org/[email protected] as suggested by Jakub Kicinski and Jacob Keller: https://lore.kernel.org/[email protected] v3: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 1cc3462 + 220cb1b commit 92d3690

File tree

1 file changed

+59
-4
lines changed

1 file changed

+59
-4
lines changed

drivers/net/ethernet/ti/icssg/icss_iep.c

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,25 @@ static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns)
406406
static int icss_iep_perout_enable_hw(struct icss_iep *iep,
407407
struct ptp_perout_request *req, int on)
408408
{
409+
struct timespec64 ts;
410+
u64 ns_start;
411+
u64 ns_width;
409412
int ret;
410413
u64 cmp;
411414

415+
/* Calculate width of the signal for PPS/PEROUT handling */
416+
ts.tv_sec = req->on.sec;
417+
ts.tv_nsec = req->on.nsec;
418+
ns_width = timespec64_to_ns(&ts);
419+
420+
if (req->flags & PTP_PEROUT_PHASE) {
421+
ts.tv_sec = req->phase.sec;
422+
ts.tv_nsec = req->phase.nsec;
423+
ns_start = timespec64_to_ns(&ts);
424+
} else {
425+
ns_start = 0;
426+
}
427+
412428
if (iep->ops && iep->ops->perout_enable) {
413429
ret = iep->ops->perout_enable(iep->clockops_data, req, on, &cmp);
414430
if (ret)
@@ -419,10 +435,12 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
419435
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
420436
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
421437
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
422-
/* Configure SYNC, 1ms pulse width */
423-
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, 1000000);
438+
/* Configure SYNC, based on req on width */
439+
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
440+
div_u64(ns_width, iep->def_inc));
424441
regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
425-
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG, 0);
442+
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
443+
div_u64(ns_start, iep->def_inc));
426444
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
427445
/* Enable CMP 1 */
428446
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
@@ -447,6 +465,10 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
447465
+ req->period.nsec;
448466
icss_iep_update_to_next_boundary(iep, start_ns);
449467

468+
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
469+
div_u64(ns_width, iep->def_inc));
470+
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
471+
div_u64(ns_start, iep->def_inc));
450472
/* Enable Sync in single shot mode */
451473
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
452474
IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
@@ -474,7 +496,37 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
474496
static int icss_iep_perout_enable(struct icss_iep *iep,
475497
struct ptp_perout_request *req, int on)
476498
{
477-
return -EOPNOTSUPP;
499+
int ret = 0;
500+
501+
/* Reject requests with unsupported flags */
502+
if (req->flags & ~(PTP_PEROUT_DUTY_CYCLE |
503+
PTP_PEROUT_PHASE))
504+
return -EOPNOTSUPP;
505+
506+
mutex_lock(&iep->ptp_clk_mutex);
507+
508+
if (iep->pps_enabled) {
509+
ret = -EBUSY;
510+
goto exit;
511+
}
512+
513+
if (iep->perout_enabled == !!on)
514+
goto exit;
515+
516+
/* Set default "on" time (1ms) for the signal if not passed by the app */
517+
if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
518+
req->on.sec = 0;
519+
req->on.nsec = NSEC_PER_MSEC;
520+
}
521+
522+
ret = icss_iep_perout_enable_hw(iep, req, on);
523+
if (!ret)
524+
iep->perout_enabled = !!on;
525+
526+
exit:
527+
mutex_unlock(&iep->ptp_clk_mutex);
528+
529+
return ret;
478530
}
479531

480532
static void icss_iep_cap_cmp_work(struct work_struct *work)
@@ -549,10 +601,13 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on)
549601
if (on) {
550602
ns = icss_iep_gettime(iep, NULL);
551603
ts = ns_to_timespec64(ns);
604+
rq.perout.flags = 0;
552605
rq.perout.period.sec = 1;
553606
rq.perout.period.nsec = 0;
554607
rq.perout.start.sec = ts.tv_sec + 2;
555608
rq.perout.start.nsec = 0;
609+
rq.perout.on.sec = 0;
610+
rq.perout.on.nsec = NSEC_PER_MSEC;
556611
ret = icss_iep_perout_enable_hw(iep, &rq.perout, on);
557612
} else {
558613
ret = icss_iep_perout_enable_hw(iep, &rq.perout, on);

0 commit comments

Comments
 (0)