arch/arm/mach-socfpga/self-refresh.S

Source file repositories/reference/linux-study-clean/arch/arm/mach-socfpga/self-refresh.S

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-socfpga/self-refresh.S
Extension
.S
Size
3134 bytes
Lines
126
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: arch/arm
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <asm/assembler.h>

#define MAX_LOOP_COUNT		1000

/* Register offset */
#define SDR_CTRLGRP_LOWPWREQ_ADDR       0x54
#define SDR_CTRLGRP_LOWPWRACK_ADDR      0x58

/* Bitfield positions */
#define SELFRSHREQ_POS                  3
#define SELFRSHREQ_MASK                 0x8

#define SELFRFSHACK_POS                 1
#define SELFRFSHACK_MASK                0x2

	/*
	 * This code assumes that when the bootloader configured
	 * the sdram controller for the DDR on the board it
	 * configured the following fields depending on the DDR
	 * vendor/configuration:
	 *
	 * sdr.ctrlcfg.lowpwreq.selfrfshmask
	 * sdr.ctrlcfg.lowpwrtiming.clkdisablecycles
	 * sdr.ctrlcfg.dramtiming4.selfrfshexit
	 */

	.arch   armv7-a
	.text
	.align 3

	/*
	 * socfpga_sdram_self_refresh
	 *
	 *  r0 : sdr_ctl_base_addr
	 *  r1 : temp storage of return value
	 *  r2 : temp storage of register values
	 *  r3 : loop counter
	 *
	 *  return value: lower 16 bits: loop count going into self refresh
	 *                upper 16 bits: loop count exiting self refresh
	 */
ENTRY(socfpga_sdram_self_refresh)
	/* Enable dynamic clock gating in the Power Control Register. */
	mrc	p15, 0, r2, c15, c0, 0
	orr	r2, r2, #1
	mcr	p15, 0, r2, c15, c0, 0

	/* Enable self refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 1 */
	ldr	r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
	orr	r2, r2, #SELFRSHREQ_MASK
	str	r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]

	/* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 1 or hit max loops */
	mov	r3, #0
while_ack_0:
	ldr	r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
	and	r2, r2, #SELFRFSHACK_MASK
	cmp	r2, #SELFRFSHACK_MASK
	beq	ack_1

	add	r3, #1
	cmp	r3, #MAX_LOOP_COUNT
	bne	while_ack_0

ack_1:
	mov	r1, r3

	/*
	 * Execute an ISB instruction to ensure that all of the

Annotation

Implementation Notes