U-boot adds power management commands

1. Specific implementation steps

①Create a new cmd_suspend.c in the ./common folder, and add the following content to this file

+#include <common.h>
+#include <command.h>
+#include <def.h>
+#include <nand.h>
+#include <s3c24x0.h>
+
+extern void s3c2440_cpu_suspend(void); / /Call external function, call the following function written in assembly
+
+static void delay(volatile int d)
+{
+ while(d--);
+}
+
+int do_suspend (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

+{

+//Query the seventh chapter of the 2440 chip manual to get the working mode setting of the 2440: Now we mainly set the sleep mode, and set the relevant registers according to the data sheet.

+ /* Sleep: */
+ + /* 1. Configure GPIO: For example, if you want to keep the LED on or off, the pin used to wake up the CPU should be set to interrupt function */ + /* For NAND boot: set EINT23,22 ,21 is the input pin */ There are macro definitions of pins in the S3c24x0.h file + rGPGCON &= ~((3<<30) | (3<<28) | (3<<26)); + + / * JZ2440 only S2/S3/S4 can be used as wake-up source, set their corresponding GPIO for interrupt mode*/ + rGPFCON &= ~((3<<0) | (3<<4)); + rGPFCON |= ((2<<0) | (2<<4)); + + rGPGCON &= ~(3<<6); + rGPGCON |= (2<<6); + + /* 2. Set INTMSK to block all Interrupt: In sleep mode, these pins are only used to wake up the system, when the CPU is running normally, INTMSK can be reset to make these pins used for interrupt functions */ + rINTMSK = ~0; + + /* 3. Configure wake-up source */ +















rEXTINT0 |= (6<<0) | (6<<8); /* EINT0,2 double edge trigger*/
+ rEXTINT1 |= (6<<12); /* EINT11 double edge trigger*/
+
+ /* 4. Set MISCCR[13:12]=11b, make the USB module go to sleep*/
+ rMISCCR |= (3<<12);
+
+ /* 5. Save some value in GSTATUS[4:3], they can be in Use when the system wakes up*/
+ //rGSTATUS3 = ​​; /* The address of the first function to be executed when the system wakes up*/
+ //rGSTATUS4 = ; /* */
+
+ /* 6. Set MISCCR[1:0] to enable Pull-up resistor for data bus */
+ rMISCCR &= ~(3);
+
+ /* 7. Clear LCDCON1.ENVID to stop LCD */
+ rLCDCON1 &= ~1;
+
+ /* 8~12 implemented using assembly , refer to the kernel source code:
+ * arch\arm\mach-s3c2410\sleep.S
+ */

+    //新建u-boot-1.1.6/cpu/arm920t/suspend.S文件

+suspend.s文件内容如下:

+#define S3C2440_REFRESH_SELF		(1<<22)
+#define S3C2440_MISCCR_SDSLEEP	    (7<<17)
+#define S3C2440_CLKCON_POWER	     (1<<3)
+		
+#define GSTATUS2       (0x560000B4)
+#define GSTATUS3       (0x560000B8)
+#define GSTATUS4       (0x560000BC)
+
+#define REFRESH        (0x48000024)
+#define MISCCR         (0x56000080)
+#define CLKCON         (0x4C00000C)
+
+.globl s3c2440_cpu_suspend //全局函数
+	@@ prepare cpu to sleep
+s3c2440_cpu_suspend:
+	stmdb	sp!, { r4-r12,lr }
+
+	/* GSTATUS3中存放唤醒时要执行的函数 */
+	ldr r0, =s3c2440_do_resume
+	ldr r1, =GSTATUS3
+	str r0, [r1]
+
+	ldr r1, =GSTATUS4
+	str sp, [r1]
+	
+	ldr	r4, =REFRESH
+	ldr	r5, =MISCCR
+	ldr	r6, =CLKCON
+	ldr	r7, [ r4 ]		@ get REFRESH 
+	ldr	r8, [ r5 ]		@ get MISCCR 
+	ldr	r9, [ r6 ]		@ get CLKCON 
+
+	orr	r7, r7, #S3C2440_REFRESH_SELF	@ SDRAM sleep command
+	orr	r8, r8, #S3C2440_MISCCR_SDSLEEP @ SDRAM power-down signals
+	orr	r9, r9, #S3C2440_CLKCON_POWER	@ power down command
+
+	teq	pc, #0			@ first as a trial-run to load cache
+	bl	s3c2440_do_sleep
+	teq	r0, r0			@ now do it for real
+	b	s3c2440_do_sleep	@
+
+	@@ align next bit of code to cache line
+	.align	5
+s3c2440_do_sleep:
+	streq	r7, [ r4 ]			@ SDRAM sleep command
+	streq	r8, [ r5 ]			@ SDRAM power-down config
+	streq	r9, [ r6 ]			@ CPU sleep
+1:	beq	1b
+	mov	pc, r14
+
+s3c2440_do_resume:
+	/* 返回到do_suspend函数 */
+	ldr r1, =GSTATUS4
+	ldr sp, [r1]
+	
+	ldmia	sp!, 	{ r4-r12,pc }
+ /* 8. 读这2个寄存器: rREFRESH and rCLKCON, 以便填充TLB
+ *    如果不使用MMU的话,这个目的可以忽略 
+ */
+
+ /* 9. 设置 REFRESH[22]=1b,让SDRAM进入self-refresh mode */
+
+ /* 10. 等待SDRAM成功进入self-refresh mode  */
+
+ /* 11.设置 MISCCR[19:17]=111b以保护SDRAM信号(SCLK0,SCLK1 and SCKE) */
+
+ /* 12. 设置CLKCON的SLEEP位让系统进入sleep mode */
+ printf("suspend ...");
+ delay(1000000);
+ s3c2440_cpu_suspend();  /* 执行到这里就不会返回,直到CPU被唤醒 */
+ ++++   //修改cpu\arm920t\start.s文件,唤醒的时候类似于nREST pin,所以修改start.s文件,实现唤醒功能
+ /* 恢复运行: 重新初始化硬件 */
+ serial_init();
+ printf("wake up\n");
+
+
+    return 0;
+}
+
+
+U_BOOT_CMD(
+ suspend, 1, 0, do_suspend, //1表示只要一个参数
+ "suspend - suspend the board\n",
+ " - suspend the board"

+);

②在./common/Makefile中添加:

COBJS-y += cmd_led.o

SOBJS = suspend.o

③在Linux环境下,重新编译u-boot,得到u-boot.bin,并下载到自己的开发板中测试,输入help就会发现led命令



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324868998&siteId=291194637