@@ -482,6 +482,22 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
482482 int ret ;
483483 u64 cmp ;
484484
485+ if (!on ) {
486+ /* Disable CMP 1 */
487+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
488+ IEP_CMP_CFG_CMP_EN (1 ), 0 );
489+
490+ /* clear CMP regs */
491+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
492+ if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
493+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
494+
495+ /* Disable sync */
496+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 );
497+
498+ return 0 ;
499+ }
500+
485501 /* Calculate width of the signal for PPS/PEROUT handling */
486502 ts .tv_sec = req -> on .sec ;
487503 ts .tv_nsec = req -> on .nsec ;
@@ -500,64 +516,39 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
500516 if (ret )
501517 return ret ;
502518
503- if (on ) {
504- /* Configure CMP */
505- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , lower_32_bits (cmp ));
506- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
507- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , upper_32_bits (cmp ));
508- /* Configure SYNC, based on req on width */
509- regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
510- div_u64 (ns_width , iep -> def_inc ));
511- regmap_write (iep -> map , ICSS_IEP_SYNC0_PERIOD_REG , 0 );
512- regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
513- div_u64 (ns_start , iep -> def_inc ));
514- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 ); /* one-shot mode */
515- /* Enable CMP 1 */
516- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
517- IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
518- } else {
519- /* Disable CMP 1 */
520- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
521- IEP_CMP_CFG_CMP_EN (1 ), 0 );
522-
523- /* clear regs */
524- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
525- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
526- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
527- }
519+ /* Configure CMP */
520+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , lower_32_bits (cmp ));
521+ if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
522+ regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , upper_32_bits (cmp ));
523+ /* Configure SYNC, based on req on width */
524+ regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
525+ div_u64 (ns_width , iep -> def_inc ));
526+ regmap_write (iep -> map , ICSS_IEP_SYNC0_PERIOD_REG , 0 );
527+ regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
528+ div_u64 (ns_start , iep -> def_inc ));
529+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 ); /* one-shot mode */
530+ /* Enable CMP 1 */
531+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
532+ IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
528533 } else {
529- if (on ) {
530- u64 start_ns ;
531-
532- iep -> period = ((u64 )req -> period .sec * NSEC_PER_SEC ) +
533- req -> period .nsec ;
534- start_ns = ((u64 )req -> period .sec * NSEC_PER_SEC )
535- + req -> period .nsec ;
536- icss_iep_update_to_next_boundary (iep , start_ns );
537-
538- regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
539- div_u64 (ns_width , iep -> def_inc ));
540- regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
541- div_u64 (ns_start , iep -> def_inc ));
542- /* Enable Sync in single shot mode */
543- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG ,
544- IEP_SYNC_CTRL_SYNC_N_EN (0 ) | IEP_SYNC_CTRL_SYNC_EN );
545- /* Enable CMP 1 */
546- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
547- IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
548- } else {
549- /* Disable CMP 1 */
550- regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
551- IEP_CMP_CFG_CMP_EN (1 ), 0 );
552-
553- /* clear CMP regs */
554- regmap_write (iep -> map , ICSS_IEP_CMP1_REG0 , 0 );
555- if (iep -> plat_data -> flags & ICSS_IEP_64BIT_COUNTER_SUPPORT )
556- regmap_write (iep -> map , ICSS_IEP_CMP1_REG1 , 0 );
557-
558- /* Disable sync */
559- regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG , 0 );
560- }
534+ u64 start_ns ;
535+
536+ iep -> period = ((u64 )req -> period .sec * NSEC_PER_SEC ) +
537+ req -> period .nsec ;
538+ start_ns = ((u64 )req -> period .sec * NSEC_PER_SEC )
539+ + req -> period .nsec ;
540+ icss_iep_update_to_next_boundary (iep , start_ns );
541+
542+ regmap_write (iep -> map , ICSS_IEP_SYNC_PWIDTH_REG ,
543+ div_u64 (ns_width , iep -> def_inc ));
544+ regmap_write (iep -> map , ICSS_IEP_SYNC_START_REG ,
545+ div_u64 (ns_start , iep -> def_inc ));
546+ /* Enable Sync in single shot mode */
547+ regmap_write (iep -> map , ICSS_IEP_SYNC_CTRL_REG ,
548+ IEP_SYNC_CTRL_SYNC_N_EN (0 ) | IEP_SYNC_CTRL_SYNC_EN );
549+ /* Enable CMP 1 */
550+ regmap_update_bits (iep -> map , ICSS_IEP_CMP_CFG_REG ,
551+ IEP_CMP_CFG_CMP_EN (1 ), IEP_CMP_CFG_CMP_EN (1 ));
561552 }
562553
563554 return 0 ;
@@ -568,11 +559,21 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
568559{
569560 int ret = 0 ;
570561
562+ if (!on )
563+ goto disable ;
564+
571565 /* Reject requests with unsupported flags */
572566 if (req -> flags & ~(PTP_PEROUT_DUTY_CYCLE |
573567 PTP_PEROUT_PHASE ))
574568 return - EOPNOTSUPP ;
575569
570+ /* Set default "on" time (1ms) for the signal if not passed by the app */
571+ if (!(req -> flags & PTP_PEROUT_DUTY_CYCLE )) {
572+ req -> on .sec = 0 ;
573+ req -> on .nsec = NSEC_PER_MSEC ;
574+ }
575+
576+ disable :
576577 mutex_lock (& iep -> ptp_clk_mutex );
577578
578579 if (iep -> pps_enabled ) {
@@ -583,12 +584,6 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
583584 if (iep -> perout_enabled == !!on )
584585 goto exit ;
585586
586- /* Set default "on" time (1ms) for the signal if not passed by the app */
587- if (!(req -> flags & PTP_PEROUT_DUTY_CYCLE )) {
588- req -> on .sec = 0 ;
589- req -> on .nsec = NSEC_PER_MSEC ;
590- }
591-
592587 ret = icss_iep_perout_enable_hw (iep , req , on );
593588 if (!ret )
594589 iep -> perout_enabled = !!on ;
0 commit comments