@@ -412,6 +412,22 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
412412 int ret ;
413413 u64 cmp ;
414414
415+ if (!on ) {
416+ /* Disable CMP 1 */
417+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
418+ IEP_CMP_CFG_CMP_EN (1 ), 0 );
419+
420+ /* clear CMP regs */
421+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
422+ if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
423+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
424+
425+ /* Disable sync */
426+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 );
427+
428+ return 0 ;
429+ }
430+
415431 /* Calculate width of the signal for PPS/PEROUT handling */
416432 ts .tv_sec = req -> on .sec ;
417433 ts .tv_nsec = req -> on .nsec ;
@@ -430,64 +446,39 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
430446 if (ret )
431447 return ret ;
432448
433- if (on ) {
434- /* Configure CMP */
435- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , lower_32_bits (cmp ));
436- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
437- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , upper_32_bits (cmp ));
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 ));
441- regmap_write (iep -> map , ICSS_IEP_SYNC0_PERIOD_REG , 0 );
442- regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
443- div_u64 (ns_start , iep -> def_inc ));
444- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 ); /* one-shot mode */
445- /* Enable CMP 1 */
446- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
447- IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
448- } else {
449- /* Disable CMP 1 */
450- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
451- IEP_CMP_CFG_CMP_EN (1 ), 0 );
452-
453- /* clear regs */
454- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
455- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
456- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
457- }
449+ /* Configure CMP */
450+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , lower_32_bits (cmp ));
451+ if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
452+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , upper_32_bits (cmp ));
453+ /* Configure SYNC, based on req on width */
454+ regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
455+ div_u64 (ns_width , iep -> def_inc ));
456+ regmap_write (iep -> map , ICSS_IEP_SYNC0_PERIOD_REG , 0 );
457+ regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
458+ div_u64 (ns_start , iep -> def_inc ));
459+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 ); /* one-shot mode */
460+ /* Enable CMP 1 */
461+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
462+ IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
458463 } else {
459- if (on ) {
460- u64 start_ns ;
461-
462- iep -> period = ((u64 )req -> period .sec * NSEC_PER_SEC ) +
463- req -> period .nsec ;
464- start_ns = ((u64 )req -> period .sec * NSEC_PER_SEC )
465- + req -> period .nsec ;
466- icss_iep_update_to_next_boundary (iep , start_ns );
467-
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 ));
472- /* Enable Sync in single shot mode */
473- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG ,
474- IEP_SYNC_CTRL_SYNC_N_EN (0 ) | IEP_SYNC_CTRL_SYNC_EN );
475- /* Enable CMP 1 */
476- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
477- IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
478- } else {
479- /* Disable CMP 1 */
480- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
481- IEP_CMP_CFG_CMP_EN (1 ), 0 );
482-
483- /* clear CMP regs */
484- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
485- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
486- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
487-
488- /* Disable sync */
489- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 );
490- }
464+ u64 start_ns ;
465+
466+ iep -> period = ((u64 )req -> period .sec * NSEC_PER_SEC ) +
467+ req -> period .nsec ;
468+ start_ns = ((u64 )req -> period .sec * NSEC_PER_SEC )
469+ + req -> period .nsec ;
470+ icss_iep_update_to_next_boundary (iep , start_ns );
471+
472+ regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
473+ div_u64 (ns_width , iep -> def_inc ));
474+ regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
475+ div_u64 (ns_start , iep -> def_inc ));
476+ /* Enable Sync in single shot mode */
477+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG ,
478+ IEP_SYNC_CTRL_SYNC_N_EN (0 ) | IEP_SYNC_CTRL_SYNC_EN );
479+ /* Enable CMP 1 */
480+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
481+ IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
491482 }
492483
493484 return 0 ;
@@ -498,11 +489,21 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
498489{
499490 int ret = 0 ;
500491
492+ if (!on )
493+ goto disable ;
494+
501495 /* Reject requests with unsupported flags */
502496 if (req -> flags & ~(PTP_PEROUT_DUTY_CYCLE |
503497 PTP_PEROUT_PHASE ))
504498 return - EOPNOTSUPP ;
505499
500+ /* Set default "on" time (1ms) for the signal if not passed by the app */
501+ if (!(req -> flags & PTP_PEROUT_DUTY_CYCLE )) {
502+ req -> on .sec = 0 ;
503+ req -> on .nsec = NSEC_PER_MSEC ;
504+ }
505+
506+ disable :
506507 mutex_lock (& iep -> ptp_clk_mutex );
507508
508509 if (iep -> pps_enabled ) {
@@ -513,12 +514,6 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
513514 if (iep -> perout_enabled == !!on )
514515 goto exit ;
515516
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-
522517 ret = icss_iep_perout_enable_hw (iep , req , on );
523518 if (!ret )
524519 iep -> perout_enabled = !!on ;
0 commit comments