mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	usb: dwc2: Add hibernation updates for ULPI PHY
Added programmming of ULPI_LATCH_EN_DURING_HIB_ENTRY bit in GPWRDN register when using ULPI PHY during entry/exit to/from hibernation. This bit set to 1 during entering to hibernation if ULPI PHY used. On exiting from hibernation this bit reset to 0. Applicable for both host and device modes. Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> Link: https://lore.kernel.org/r/e024cb39a7177ec201c873df25ca6365f2e55947.1708948356.git.Minas.Harutyunyan@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									535a88dc7d
								
							
						
					
					
						commit
						4483ef3c16
					
				
					 4 changed files with 43 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -249,6 +249,11 @@ void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup,
 | 
			
		|||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
	udelay(10);
 | 
			
		||||
 | 
			
		||||
	/* Reset ULPI latch */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
 | 
			
		||||
	/* Disable PMU interrupt */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_PMUINTSEL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -705,6 +705,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
 | 
			
		|||
	gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
 | 
			
		||||
 | 
			
		||||
	/* Reset ULPI latch */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
 | 
			
		||||
	/* De-assert Wakeup Logic */
 | 
			
		||||
	gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn_tmp &= ~GPWRDN_PMUACTV;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5309,6 +5309,8 @@ void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg)
 | 
			
		|||
int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
 | 
			
		||||
{
 | 
			
		||||
	u32 gpwrdn;
 | 
			
		||||
	u32 gusbcfg;
 | 
			
		||||
	u32 pcgcctl;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	/* Change to L2(suspend) state */
 | 
			
		||||
| 
						 | 
				
			
			@ -5328,6 +5330,22 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	gpwrdn = GPWRDN_PWRDNRSTN;
 | 
			
		||||
	udelay(10);
 | 
			
		||||
	gusbcfg = dwc2_readl(hsotg, GUSBCFG);
 | 
			
		||||
	if (gusbcfg & GUSBCFG_ULPI_UTMI_SEL) {
 | 
			
		||||
		/* ULPI interface */
 | 
			
		||||
		gpwrdn |= GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
	}
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
	udelay(10);
 | 
			
		||||
 | 
			
		||||
	/* Suspend the Phy Clock */
 | 
			
		||||
	pcgcctl = dwc2_readl(hsotg, PCGCTL);
 | 
			
		||||
	pcgcctl |= PCGCTL_STOPPCLK;
 | 
			
		||||
	dwc2_writel(hsotg, pcgcctl, PCGCTL);
 | 
			
		||||
	udelay(10);
 | 
			
		||||
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn |= GPWRDN_PMUACTV;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
	udelay(10);
 | 
			
		||||
| 
						 | 
				
			
			@ -5428,6 +5446,11 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
 | 
			
		|||
	if (reset)
 | 
			
		||||
		dwc2_clear_bit(hsotg, DCFG, DCFG_DEVADDR_MASK);
 | 
			
		||||
 | 
			
		||||
	/* Reset ULPI latch */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
 | 
			
		||||
	/* De-assert Wakeup Logic */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_PMUACTV;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5503,6 +5503,11 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
 | 
			
		|||
	gusbcfg = dwc2_readl(hsotg, GUSBCFG);
 | 
			
		||||
	if (gusbcfg & GUSBCFG_ULPI_UTMI_SEL) {
 | 
			
		||||
		/* ULPI interface */
 | 
			
		||||
		udelay(10);
 | 
			
		||||
		gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
		gpwrdn |= GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
		dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
		udelay(10);
 | 
			
		||||
		/* Suspend the Phy Clock */
 | 
			
		||||
		pcgcctl = dwc2_readl(hsotg, PCGCTL);
 | 
			
		||||
		pcgcctl |= PCGCTL_STOPPCLK;
 | 
			
		||||
| 
						 | 
				
			
			@ -5609,6 +5614,11 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
 | 
			
		|||
	dwc2_writel(hsotg, gr->gusbcfg, GUSBCFG);
 | 
			
		||||
	dwc2_writel(hsotg, hr->hcfg, HCFG);
 | 
			
		||||
 | 
			
		||||
	/* Reset ULPI latch */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY;
 | 
			
		||||
	dwc2_writel(hsotg, gpwrdn, GPWRDN);
 | 
			
		||||
 | 
			
		||||
	/* De-assert Wakeup Logic */
 | 
			
		||||
	gpwrdn = dwc2_readl(hsotg, GPWRDN);
 | 
			
		||||
	gpwrdn &= ~GPWRDN_PMUACTV;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue