mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	ARM: at91: pm: fix self-refresh for sama7g5
It has been discovered that on some parts, from time to time, self-refresh
procedure doesn't work as expected. Debugging and investigating it proved
that disabling AC DLL introduce glitches in RAM controllers which
leads to unexpected behavior. This is confirmed as a hardware bug. DLL
bypass disables 3 DLLs: 2 DX DLLs and AC DLL. Thus, keep only DX DLLs
disabled. This introduce 6mA extra current consumption on VDDCORE when
switching to any ULP mode or standby mode but the self-refresh procedure
still works.
Fixes: f0bbf17958 ("ARM: at91: pm: add self-refresh support for sama7g5")
Suggested-by: Frederic Schumacher <frederic.schumacher@microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Tested-by: Cristian Birsan <cristian.birsan@microchip.com>
Link: https://lore.kernel.org/r/20220826083927.3107272-3-claudiu.beznea@microchip.com
			
			
This commit is contained in:
		
							parent
							
								
									f04445fa09
								
							
						
					
					
						commit
						a02875c4cb
					
				
					 2 changed files with 21 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -172,9 +172,15 @@ sr_ena_2:
 | 
			
		|||
	/* Put DDR PHY's DLL in bypass mode for non-backup modes. */
 | 
			
		||||
	cmp	r7, #AT91_PM_BACKUP
 | 
			
		||||
	beq	sr_ena_3
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_PIR]
 | 
			
		||||
	orr	tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_PIR]
 | 
			
		||||
 | 
			
		||||
	/* Disable DX DLLs. */
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
 | 
			
		||||
	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]
 | 
			
		||||
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
 | 
			
		||||
	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]
 | 
			
		||||
 | 
			
		||||
sr_ena_3:
 | 
			
		||||
	/* Power down DDR PHY data receivers. */
 | 
			
		||||
| 
						 | 
				
			
			@ -221,10 +227,14 @@ sr_ena_3:
 | 
			
		|||
	bic	tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_DSGCR]
 | 
			
		||||
 | 
			
		||||
	/* Take DDR PHY's DLL out of bypass mode. */
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_PIR]
 | 
			
		||||
	bic	tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_PIR]
 | 
			
		||||
	/* Enable DX DLLs. */
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
 | 
			
		||||
	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_DX0DLLCR]
 | 
			
		||||
 | 
			
		||||
	ldr	tmp1, [r3, #DDR3PHY_DX1DLLCR]
 | 
			
		||||
	bic	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
 | 
			
		||||
	str	tmp1, [r3, #DDR3PHY_DX1DLLCR]
 | 
			
		||||
 | 
			
		||||
	/* Enable quasi-dynamic programming. */
 | 
			
		||||
	mov	tmp1, #0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,10 @@
 | 
			
		|||
 | 
			
		||||
#define DDR3PHY_ZQ0SR0				(0x188)		/* ZQ status register 0 */
 | 
			
		||||
 | 
			
		||||
#define	DDR3PHY_DX0DLLCR			(0x1CC)		/* DDR3PHY DATX8 DLL Control Register */
 | 
			
		||||
#define	DDR3PHY_DX1DLLCR			(0x20C)		/* DDR3PHY DATX8 DLL Control Register */
 | 
			
		||||
#define		DDR3PHY_DXDLLCR_DLLDIS		(1 << 31)	/* DLL Disable */
 | 
			
		||||
 | 
			
		||||
/* UDDRC */
 | 
			
		||||
#define UDDRC_STAT				(0x04)		/* UDDRC Operating Mode Status Register */
 | 
			
		||||
#define		UDDRC_STAT_SELFREF_TYPE_DIS	(0x0 << 4)	/* SDRAM is not in Self-refresh */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue