@@ -519,6 +519,114 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg)
519
519
return 0 ;
520
520
}
521
521
522
+ /*
523
+ * Force the mode of the controller.
524
+ *
525
+ * Forcing the mode is needed for two cases:
526
+ *
527
+ * 1) If the dr_mode is set to either HOST or PERIPHERAL we force the
528
+ * controller to stay in a particular mode regardless of ID pin
529
+ * changes. We do this usually after a core reset.
530
+ *
531
+ * 2) During probe we want to read reset values of the hw
532
+ * configuration registers that are only available in either host or
533
+ * device mode. We may need to force the mode if the current mode does
534
+ * not allow us to access the register in the mode that we want.
535
+ *
536
+ * In either case it only makes sense to force the mode if the
537
+ * controller hardware is OTG capable.
538
+ *
539
+ * Checks are done in this function to determine whether doing a force
540
+ * would be valid or not.
541
+ *
542
+ * If a force is done, it requires a 25ms delay to take effect.
543
+ *
544
+ * Returns true if the mode was forced.
545
+ */
546
+ static bool dwc2_force_mode (struct dwc2_hsotg * hsotg , bool host )
547
+ {
548
+ u32 gusbcfg ;
549
+ u32 set ;
550
+ u32 clear ;
551
+
552
+ dev_dbg (hsotg -> dev , "Forcing mode to %s\n" , host ? "host" : "device" );
553
+
554
+ /*
555
+ * Force mode has no effect if the hardware is not OTG.
556
+ */
557
+ if (!dwc2_hw_is_otg (hsotg ))
558
+ return false;
559
+
560
+ /*
561
+ * If dr_mode is either peripheral or host only, there is no
562
+ * need to ever force the mode to the opposite mode.
563
+ */
564
+ if (WARN_ON (host && hsotg -> dr_mode == USB_DR_MODE_PERIPHERAL ))
565
+ return false;
566
+
567
+ if (WARN_ON (!host && hsotg -> dr_mode == USB_DR_MODE_HOST ))
568
+ return false;
569
+
570
+ gusbcfg = dwc2_readl (hsotg -> regs + GUSBCFG );
571
+
572
+ set = host ? GUSBCFG_FORCEHOSTMODE : GUSBCFG_FORCEDEVMODE ;
573
+ clear = host ? GUSBCFG_FORCEDEVMODE : GUSBCFG_FORCEHOSTMODE ;
574
+
575
+ /*
576
+ * If the force mode bit is already set, don't set it.
577
+ */
578
+ if ((gusbcfg & set ) && !(gusbcfg & clear ))
579
+ return false;
580
+
581
+ gusbcfg &= ~clear ;
582
+ gusbcfg |= set ;
583
+ dwc2_writel (gusbcfg , hsotg -> regs + GUSBCFG );
584
+
585
+ msleep (25 );
586
+ return true;
587
+ }
588
+
589
+ /*
590
+ * Clears the force mode bits.
591
+ */
592
+ static void dwc2_clear_force_mode (struct dwc2_hsotg * hsotg )
593
+ {
594
+ u32 gusbcfg ;
595
+
596
+ gusbcfg = dwc2_readl (hsotg -> regs + GUSBCFG );
597
+ gusbcfg &= ~GUSBCFG_FORCEHOSTMODE ;
598
+ gusbcfg &= ~GUSBCFG_FORCEDEVMODE ;
599
+ dwc2_writel (gusbcfg , hsotg -> regs + GUSBCFG );
600
+
601
+ /*
602
+ * NOTE: This long sleep is _very_ important, otherwise the core will
603
+ * not stay in host mode after a connector ID change!
604
+ */
605
+ usleep_range (150000 , 160000 );
606
+ }
607
+
608
+ /*
609
+ * Sets or clears force mode based on the dr_mode parameter.
610
+ */
611
+ void dwc2_force_dr_mode (struct dwc2_hsotg * hsotg )
612
+ {
613
+ switch (hsotg -> dr_mode ) {
614
+ case USB_DR_MODE_HOST :
615
+ dwc2_force_mode (hsotg , true);
616
+ break ;
617
+ case USB_DR_MODE_PERIPHERAL :
618
+ dwc2_force_mode (hsotg , false);
619
+ break ;
620
+ case USB_DR_MODE_OTG :
621
+ dwc2_clear_force_mode (hsotg );
622
+ break ;
623
+ default :
624
+ dev_warn (hsotg -> dev , "%s() Invalid dr_mode=%d\n" ,
625
+ __func__ , hsotg -> dr_mode );
626
+ break ;
627
+ }
628
+ }
629
+
522
630
/*
523
631
* Do core a soft reset of the core. Be careful with this because it
524
632
* resets all the internal state machines of the core.
@@ -529,35 +637,12 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg)
529
637
int dwc2_core_reset_and_force_dr_mode (struct dwc2_hsotg * hsotg )
530
638
{
531
639
int retval ;
532
- u32 gusbcfg ;
533
640
534
641
retval = dwc2_core_reset (hsotg );
535
642
if (retval )
536
643
return retval ;
537
644
538
- if (hsotg -> dr_mode == USB_DR_MODE_HOST ) {
539
- gusbcfg = dwc2_readl (hsotg -> regs + GUSBCFG );
540
- gusbcfg &= ~GUSBCFG_FORCEDEVMODE ;
541
- gusbcfg |= GUSBCFG_FORCEHOSTMODE ;
542
- dwc2_writel (gusbcfg , hsotg -> regs + GUSBCFG );
543
- } else if (hsotg -> dr_mode == USB_DR_MODE_PERIPHERAL ) {
544
- gusbcfg = dwc2_readl (hsotg -> regs + GUSBCFG );
545
- gusbcfg &= ~GUSBCFG_FORCEHOSTMODE ;
546
- gusbcfg |= GUSBCFG_FORCEDEVMODE ;
547
- dwc2_writel (gusbcfg , hsotg -> regs + GUSBCFG );
548
- } else if (hsotg -> dr_mode == USB_DR_MODE_OTG ) {
549
- gusbcfg = dwc2_readl (hsotg -> regs + GUSBCFG );
550
- gusbcfg &= ~GUSBCFG_FORCEHOSTMODE ;
551
- gusbcfg &= ~GUSBCFG_FORCEDEVMODE ;
552
- dwc2_writel (gusbcfg , hsotg -> regs + GUSBCFG );
553
- }
554
-
555
- /*
556
- * NOTE: This long sleep is _very_ important, otherwise the core will
557
- * not stay in host mode after a connector ID change!
558
- */
559
- usleep_range (150000 , 160000 );
560
-
645
+ dwc2_force_dr_mode (hsotg );
561
646
return 0 ;
562
647
}
563
648
@@ -3117,6 +3202,22 @@ void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
3117
3202
dwc2_set_param_hibernation (hsotg , params -> hibernation );
3118
3203
}
3119
3204
3205
+ /*
3206
+ * Forces either host or device mode if the controller is not
3207
+ * currently in that mode.
3208
+ *
3209
+ * Returns true if the mode was forced.
3210
+ */
3211
+ static bool dwc2_force_mode_if_needed (struct dwc2_hsotg * hsotg , bool host )
3212
+ {
3213
+ if (host && dwc2_is_host_mode (hsotg ))
3214
+ return false;
3215
+ else if (!host && dwc2_is_device_mode (hsotg ))
3216
+ return false;
3217
+
3218
+ return dwc2_force_mode (hsotg , host );
3219
+ }
3220
+
3120
3221
/**
3121
3222
* During device initialization, read various hardware configuration
3122
3223
* registers and interpret the contents.
0 commit comments