From: Domen Puncer <hidden> Date: 2007-03-15 10:40:02
Hi!
Some fixes, improvements from last time:
- saving/restoring of some registers inside sleep code
(so bestcomm and pic patches can be dropped, yay)
- improvements in FEC code for deep-sleep
- set up wakeup GPIO so Efika can wake too
- patch against latest u-boot (doh)
Patches are based on latest mainline git tree + fec patches:
Fec_MPC5200_eth_driver.patch
Copy_bestcomm_support_files_into_arch_powerpc.patch
Make_FEC_work_on_the_lite5200.patch
This patchset includes the following patches:
- [PATCH 1/5] mpc52xx suspend: UART
- [PATCH 2/5] mpc52xx suspend: FEC (ethernet)
- [PATCH 3/5] mpc52xx suspend: USB
- [PATCH 4/5] mpc52xx suspend: deep-sleep
- [PATCH] icecube/lite5200b: wakeup from low-power support
- [PATCH 5/5] lite5200b suspend: low-power mode
Domen
From: Domen Puncer <hidden> Date: 2007-03-15 10:41:16
MPC52xx uart power management.
Not sure how exactly this should be written, but this seems
to work, and works around a few seconds delay in resume.
Signed-off-by: Domen Puncer <redacted>
Index: grant.git/drivers/serial/mpc52xx_uart.c
===================================================================
@@ -418,6 +418,22 @@ mpc52xx_uart_verify_port(struct uart_porreturn0;}+/* just Reenable TX and RX */+staticvoidmpc52xx_uart_pm(structuart_port*port,unsignedintstate,unsignedintoldstate)+{+structmpc52xx_psc__iomem*psc=PSC(port);+unsignedlongflags;++/* Get the lock */+spin_lock_irqsave(&port->lock,flags);++/* Reenable TX & RX */+out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);+out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);++/* We're all set, release the lock */+spin_unlock_irqrestore(&port->lock,flags);+}staticstructuart_opsmpc52xx_uart_ops={.tx_empty=mpc52xx_uart_tx_empty,
From: Domen Puncer <hidden> Date: 2007-03-15 10:42:00
Suspend and resume for FEC on MPC52xx.
Note that resume is a bit different for lite5200b low-power mode.
Signed-off-by: Domen Puncer <redacted>
---
drivers/net/fec_mpc52xx/fec.c | 60 ++++++++++++++++++++++++++++++++++++--
drivers/net/fec_mpc52xx/fec_phy.c | 17 ++++++++++
drivers/net/fec_mpc52xx/fec_phy.h | 5 +++
3 files changed, 80 insertions(+), 2 deletions(-)
Index: grant.git/drivers/net/fec_mpc52xx/fec.c
===================================================================
From: Domen Puncer <hidden> Date: 2007-03-15 10:42:31
Trivial suspend and resume OF OHCI.
On MPC52xx turn off and on power to ports.
Signed-off-by: Domen Puncer <redacted>
Index: grant.git/drivers/usb/host/ohci-ppc-of.c
===================================================================
From: Domen Puncer <hidden> Date: 2007-03-15 10:43:10
Implement deep-sleep on MPC52xx.
SDRAM is put into self-refresh with help of SRAM code
(alternatives would be code in FLASH, I-cache).
Interrupt code must also not be in SDRAM, so put it
in I-cache.
MPC52xx core is static, so contents will remain intact even
with clocks turned off.
Signed-off-by: Domen Puncer <redacted>
---
arch/powerpc/platforms/52xx/Makefile | 2
arch/powerpc/platforms/52xx/mpc52xx_pm.c | 124 ++++++++++++
arch/powerpc/platforms/52xx/mpc52xx_sleep.S | 277 ++++++++++++++++++++++++++++
3 files changed, 403 insertions(+)
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -0,0 +1,124 @@+#include<linux/init.h>+#include<linux/pm.h>+#include<linux/io.h>+#include<asm/mpc52xx.h>+#include"bestcomm.h"+#include"mpc52xx_pic.h"++externvoidmpc52xx_deep_sleep(void*,void*);++staticvoid__iomem*mbar;++staticintmpc52xx_pm_valid(suspend_state_tstate)+{+switch(state){+casePM_SUSPEND_STANDBY:+return1;+default:+return0;+}+}++/* you will want to change this, to match your board gpios, rtc or whatever */+staticvoidmpc52xx_set_wakeup_mode(void)+{+structmpc52xx_gpio_wkup__iomem*gpiow;+structmpc52xx_intr__iomem*intr;+#ifdef CONFIG_PPC_LITE5200+intpin=1;/* GPIO_WKUP_1 (GPIO_PSC2_4) */+intlevel_low=1;/* wakeup on low level */+#elif defined CONFIG_PPC_EFIKA+intpin=4;/* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */+intlevel_low=0;/* wakeup on high level */+/* IOW. to wake it up, short pins 1 and 3 on IRDA connector */+#else+#warning "define how would you like your board to wake"+#endif+u16tmp;++gpiow=mbar+0xc00;+intr=mbar+0x500;++/* enable gpio */+out_8(&gpiow->wkup_gpioe,in_8(&gpiow->wkup_gpioe)|(1<<pin));+/* set as input */+out_8(&gpiow->wkup_ddr,in_8(&gpiow->wkup_ddr)&~(1<<pin));+/* enable deep sleep interrupt */+out_8(&gpiow->wkup_inten,in_8(&gpiow->wkup_inten)|(1<<pin));+/* low/high level creates wakeup interrupt */+tmp=in_be16(&gpiow->wkup_itype);+tmp&=(level_low+1)<<(pin*2);+tmp|=(level_low+1)<<(pin*2);+out_be16(&gpiow->wkup_itype,tmp);+/* master enable */+out_8(&gpiow->wkup_maste,1);++/* enable wakeup gpio interrupt in PIC */+out_be32(&intr->main_mask,in_be32(&intr->main_mask)&~(1<<8));+}++intmpc52xx_pm_prepare(suspend_state_tstate)+{+if(state!=PM_SUSPEND_STANDBY)+return-EINVAL;++/* map registers */+mbar=ioremap_nocache(0xf0000000,0x8000);+if(!mbar){+printk(KERN_ERR"%s:%i Error mapping registers\n",__func__,__LINE__);+return-ENOSYS;+}++mpc52xx_set_wakeup_mode();++return0;+}++charsaved_sram[0x4000];+intmpc52xx_pm_enter(suspend_state_tstate)+{+staticstructmpc52xx_cdm__iomem*cdm;+u32clk_enables;+cdm=mbar+0x200;++memcpy(saved_sram,sdma.sram,sdma.sram_size);++out_8(&cdm->ccs_sleep_enable,1);+out_8(&cdm->osc_sleep_enable,1);+out_8(&cdm->ccs_qreq_test,1);++/* disable all but SDRAM, bestcomm (SRAM) and timer clocks */+clk_enables=in_be32(&cdm->clk_enables);+out_be32(&cdm->clk_enables,clk_enables&0x00088002);++mpc52xx_deep_sleep(sdma.sram,mbar);++out_be32(&cdm->clk_enables,clk_enables);+out_8(&cdm->ccs_sleep_enable,0);+out_8(&cdm->osc_sleep_enable,0);++memcpy(sdma.sram,saved_sram,sdma.sram_size);++iounmap(mbar);+return0;+}++staticintmpc52xx_pm_finish(suspend_state_tstate)+{+return0;+}++staticstructpm_opsmpc52xx_pm_ops={+.valid=mpc52xx_pm_valid,+.prepare=mpc52xx_pm_prepare,+.enter=mpc52xx_pm_enter,+.finish=mpc52xx_pm_finish,+};++staticint__initmpc52xx_pm_init(void)+{+pm_set_ops(&mpc52xx_pm_ops);+return0;+}++arch_initcall(mpc52xx_pm_init);
From: Domen Puncer <hidden> Date: 2007-03-15 10:44:14
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
---
board/icecube/icecube.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
Index: u-boot.git/board/icecube/icecube.c
===================================================================
@@ -42,6 +42,54 @@#include"mt48lc16m16a2-75.h"# endif#endif++#ifdef CONFIG_LITE5200B+/* u-boot part of low-power mode implementation */+#define SAVED_ADDR (*(void **)0x00000000)+#define PSC2_4 0x02++voidlite5200b_wakeup(void)+{+unsignedcharwakeup_pin;+void(*linux_wakeup)(void);++/* check PSC2_4, if it's down "QT" is signaling we have a wakeup+*fromlowpowermode*/+*(vu_char*)MPC5XXX_WU_GPIO_ENABLE=PSC2_4;+__asm__volatile("sync");++wakeup_pin=*(vu_char*)MPC5XXX_WU_GPIO_DATA_I;+if(wakeup_pin&PSC2_4)+return;++/* acknowledge to "QT"+*byholdingpinat1for10uS*/+*(vu_char*)MPC5XXX_WU_GPIO_DIR=PSC2_4;+__asm__volatile("sync");+*(vu_char*)MPC5XXX_WU_GPIO_DATA_O=PSC2_4;+__asm__volatile("sync");+udelay(10);++/* put ram out of self-refresh */+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x80000000;// mode_en+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x50000000;// cke ref_en+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL&=~0x80000000;// !mode_en+__asm__volatile("sync");+udelay(10);/* wait a bit */++/* jump back to linux kernel code */+linux_wakeup=SAVED_ADDR;+printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",+linux_wakeup);+linux_wakeup();+}+#else+#define lite5200b_wakeup()+#endif++#ifndef CFG_RAMBOOTstaticvoidsdram_start(inthi_addr){
@@ -208,6 +256,8 @@ long int initdram (int board_type)__asm__volatile("sync");}+lite5200b_wakeup();+returndramsize+dramsize2;}
From: Domen Puncer <hidden> Date: 2007-03-15 10:44:51
Low-power mode implementation for Lite5200b.
Some I/O registers are also saved here.
A patch to U-Boot that wakes up SDRAM, and transfers control
to address saved at physical 0x0 is needed.
Signed-off-by: Domen Puncer <redacted>
---
arch/powerpc/platforms/52xx/Makefile | 3
arch/powerpc/platforms/52xx/lite5200_pm.c | 125 ++++++++
arch/powerpc/platforms/52xx/lite5200_sleep.S | 419 +++++++++++++++++++++++++++
3 files changed, 547 insertions(+)
Index: grant.git/arch/powerpc/platforms/52xx/lite5200_pm.c
===================================================================
@@ -0,0 +1,125 @@+#include<linux/init.h>+#include<linux/delay.h>+#include<linux/pm.h>+#include<asm/io.h>+#include<asm/mpc52xx.h>+#include"mpc52xx_pic.h"+#include"bestcomm.h"++externvoidlite5200_low_power(void*sram,void*mbar);+externintmpc52xx_pm_enter(suspend_state_t);+externintmpc52xx_pm_prepare(suspend_state_t);++staticvoid__iomem*mbar;++staticintlite5200_pm_valid(suspend_state_tstate)+{+switch(state){+casePM_SUSPEND_STANDBY:+casePM_SUSPEND_MEM:+return1;+default:+return0;+}+}++staticintlite5200_pm_prepare(suspend_state_tstate)+{+/* deep sleep? let mpc52xx code handle that */+if(state==PM_SUSPEND_STANDBY)+returnmpc52xx_pm_prepare(state);++if(state!=PM_SUSPEND_MEM)+return-EINVAL;++/* map registers */+mbar=ioremap_nocache(0xf0000000,0x8000);+if(!mbar){+printk(KERN_ERR"%s:%i Error mapping registers\n",__func__,__LINE__);+return-ENOSYS;+}++return0;+}++/* save and restore registers not bound to any real devices */+staticstructmpc52xx_cdm__iomem*cdm;+staticstructmpc52xx_cdmscdm;+staticstructmpc52xx_intr__iomem*pic;+staticstructmpc52xx_intrspic;+staticstructmpc52xx_sdma__iomem*bes;+staticstructmpc52xx_sdmasbes;+staticstructmpc52xx_xlb__iomem*xlb;+staticstructmpc52xx_xlbsxlb;+staticstructmpc52xx_gpio__iomem*gps;+staticstructmpc52xx_gpiosgps;+staticstructmpc52xx_gpio_wkup__iomem*gpw;+staticstructmpc52xx_gpio_wkupsgpw;+externcharsaved_sram[0x4000];++staticvoidlite5200_save_regs(void)+{+_memcpy_fromio(&sbes,bes,sizeof(*bes));+_memcpy_fromio(&spic,pic,sizeof(*pic));+_memcpy_fromio(&scdm,cdm,sizeof(*cdm));+_memcpy_fromio(&sxlb,xlb,sizeof(*xlb));+_memcpy_fromio(&sgps,gps,sizeof(*gps));+_memcpy_fromio(&sgpw,gpw,sizeof(*gpw));++memcpy(saved_sram,sdma.sram,sdma.sram_size);+}++staticvoidlite5200_restore_regs(void)+{+memcpy(sdma.sram,saved_sram,sdma.sram_size);++_memcpy_toio(gpw,&sgpw,sizeof(*gpw));+_memcpy_toio(gps,&sgps,sizeof(*gps));+_memcpy_toio(xlb,&sxlb,sizeof(*xlb));+_memcpy_toio(cdm,&scdm,sizeof(*cdm));+_memcpy_toio(pic,&spic,sizeof(*pic));+_memcpy_toio(bes,&sbes,sizeof(*bes));+}++staticintlite5200_pm_enter(suspend_state_tstate)+{+/* deep sleep? let mpc52xx code handle that */+if(state==PM_SUSPEND_STANDBY){+returnmpc52xx_pm_enter(state);+}++cdm=mbar+0x200;+pic=mbar+0x500;+gps=mbar+0xb00;+gpw=mbar+0xc00;+bes=mbar+0x1200;+xlb=mbar+0x1f00;+lite5200_save_regs();++lite5200_low_power(sdma.sram,mbar);++lite5200_restore_regs();++iounmap(mbar);+return0;+}++staticintlite5200_pm_finish(suspend_state_tstate)+{+return0;+}++staticstructpm_opslite5200_pm_ops={+.valid=lite5200_pm_valid,+.prepare=lite5200_pm_prepare,+.enter=lite5200_pm_enter,+.finish=lite5200_pm_finish,+};++staticint__initlite5200_pm_init(void)+{+pm_set_ops(&lite5200_pm_ops);+return0;+}++arch_initcall(lite5200_pm_init);
#ifdef blocks are a bad idea. It is now possible to boot one kernel
image on multiple platforms. Chip model should be determined ahead of
time from the device tree and choose the code path accordingly at
runtime.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Grant Likely <hidden> Date: 2007-03-15 13:35:12
On 3/15/07, Domen Puncer [off-list ref] wrote:
Suspend and resume for FEC on MPC52xx.
Note that resume is a bit different for lite5200b low-power mode.
Signed-off-by: Domen Puncer <redacted>
This of course cannot be applied until a mpc5200 ethernet driver is
actually in mainline. :-)
Haven't tested, but I don't see anything evil here, other than the
"ugly hack" :-)
g.
Hi:
I'm trying to bring up Linux on Xilinx ML403 reference board.
I took 2.6.19.2 kernel from DENX. EDK project for ML403 I took from
official Xilinx site.
I could bring up u-boot on the board, everything is working fine (see
ml403.h file attached). Then I compiled uImage for kernel and tried to
download it - I don't see any kernel's outputs:
TFTP from server 192.168.0.141; our IP address is 192.168.0.203
Filename 'LM200/rel/1.0.1d-403/uImage'.
Load address: 0x1000000
Loading: T
#################################################################
#################################################################
#######################################
done
Bytes transferred = 861735 (d2627 hex)
## Booting image at 01000000 ...
Image Name: Linux-2.6.19.2
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 861671 Bytes = 841.5 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
## Current stack ends at 0x03E676F0 => set upper limit to 0x00800000
## cmdline at 0x007FFF00 ... 0x007FFFF8
memstart = 0x00000000
memsize = 0x04000000
flashstart = 0x28000000
flashsize = 0x00800000
flashoffset = 0x00000000
sramstart = 0x00000000
sramsize = 0x00000000
bootflags = 0x0000003C
procfreq = 300 MHz
plb_busfreq = 100 MHz
ethaddr = 00:01:02:CB:CB:71
IP addr = 192.168.0.203
baudrate = 115200 bps
No initrd
## Transferring control to Linux (at address 00000000) ...
I have read a lot of posts and reviewed the source code and I think
these kernel trees I'm using are properly patched for using u-boot; I
only included asm/ppcboot.h into xilinx_403.h:
/* U-boot expects the bd_t to look like the one in ppcboot.h, not like
this. */
#ifdef NOT_USING_UBOOT
typedef struct board_info {
unsigned int bi_memsize; /* DRAM installed, in
bytes */
unsigned char bi_enetaddr[6]; /* Local Ethernet MAC
address */
unsigned int bi_intfreq; /* Processor speed, in
Hz */
unsigned int bi_busfreq; /* PLB Bus speed, in Hz
*/
unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz
*/
} bd_t;
/* Some 4xx parts use a different timebase frequency from the internal
clock.
*/
#define bi_tbfreq bi_intfreq
#else
#include <asm/ppcboot.h>
#endif /* UBOOT */
Anyway I tried to compile zImage.elf and download it directly to RAM
using XMD. Here I had partial success: first time after FPGA image
downloading I try it, I see the following (it doesn't happen if I try to
repeat downloading again without reloading FPGA image first):
====
loaded at: 00400000 004DA13C
board data at: 004D8124 004D813C
relocated to: 00404090 004040A8
zimage at: 00404E1D 004D7401
avail ram: 004DB000 04000000
Linux/PPC load: console=ttyS0,115200
Uncompressing Linux...done.
Now booting the kernel
[ 0.000000] Linux version 2.6.19.2 (root@mylinux.a-k-a.local) (gcc
version 4.0.0 (DENX ELDK 4.1 4.0.0)) #6 Thu Mar 15 05:46:09 PST 2007
[ 0.000000] Xilinx ML403 Reference System (Virtex-4 FX)
[ 0.000000] Zone PFN ranges:
[ 0.000000] DMA 0 -> 16384
[ 0.000000] Normal 16384 -> 16384
[ 0.000000] early_node_map[1] active PFN ranges
[ 0.000000] 0: 0 -> 16384
[ 0.000000] Built 1 zonelists. Total pages: 16256
[ 0.000000] Kernel command line: console=ttyS0,115200
[ 0.000000] Xilinx INTC #0 at 0xD1000FC0 mapped to 0xFDFFEFC0
[ 0.000000] PID hash table entries: 256 (order: 8, 1024 bytes)
[ 0.000188] Console: colour dummy device 80x25
[ 0.000701] Dentry cache hash table entries: 8192 (order: 3, 32768
bytes)
[ 0.001489] Inode-cache hash table entries: 4096 (order: 2, 16384
bytes)
[ 0.015326] Memory: 63104k available (1324k kernel code, 436k data,
92k init, 0k highmem)
[ 0.108476] Mount-cache hash table entries: 512
[ 0.114051] NET: Registered protocol family 16
[ 0.128395] NET: Registered protocol family 2
[ 0.168472] IP route cache hash table entries: 512 (order: -1, 2048
bytes)
[ 0.169340] TCP established hash table entries: 2048 (order: 1, 8192
bytes)
[ 0.169539] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.169648] TCP: Hash tables configured (established 2048 bind 1024)
[ 0.169679] TCP reno registered
[ 0.173555] io scheduler noop registered
[ 0.173600] io scheduler anticipatory registered (default)
[ 0.173630] io scheduler deadline registered
[ 0.173756] io scheduler cfq registered
[ 0.221629] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ
sharing disabled
[ 0.227023] serial8250.0: ttyS0 at MMIO 0xa0001003 (irq = 9) is a
16450
[ 0.398738] RAMDISK driver initialized: 16 RAM disks of 65536K size
1024 blocksize
[ 0.407941] tun: Universal TUN/TAP device driver, 1.6
[ 0.412993] tun: (C) 1999-2004 Max Krasnyansky [off-list ref]
[ 0.420583] mice: PS/2 mouse device common for all mice
[ 0.426040] TCP cubic registered
[ 0.429347] NET: Registered protocol family 1
[ 0.433727] NET: Registered protocol family 17
[ 0.439482] VFS: Cannot open root device "<NULL>" or
unknown-block(0,0)
[ 0.446095] Please append a correct "root=" boot option
[ 0.451282] Kernel panic - not syncing: VFS: Unable to mount root fs
on unknown-block(0,0)
[ 0.459492] <0>Rebooting in 180 seconds..
I don't care about kernel panic for now - it's to be expected since I
don't provide any filesystem.
So, kernel itself is workable, it looks like uImage doesn't pick up
correct board info parameters from u-boot. Where u-boot write them and
where Linux looks for them? What is the simplest way to sync between
u-boot and kernel?
Thanks,
Leonid.
From: Grant Likely <hidden> Date: 2007-03-15 15:11:59
On 3/15/07, Domen Puncer [off-list ref] wrote:
Low-power mode implementation for Lite5200b.
Some I/O registers are also saved here.
A patch to U-Boot that wakes up SDRAM, and transfers control
to address saved at physical 0x0 is needed.
I don't see any structural problems with this code, but I have a few
comments below. I'm also concerned about the blind register
save/restore by memcpy_to/fromio. I haven't looked at the chip
documentation, but it looks scary. Is it safe to restore those
registers in that manner?
Cheers,
g.
From: Domen Puncer <hidden> Date: 2007-03-15 16:36:52
On 15/03/07 08:09 -0600, Grant Likely wrote:
On 3/15/07, Domen Puncer [off-list ref] wrote:
quoted
Low-power mode implementation for Lite5200b.
Some I/O registers are also saved here.
A patch to U-Boot that wakes up SDRAM, and transfers control
to address saved at physical 0x0 is needed.
I don't see any structural problems with this code, but I have a few
comments below. I'm also concerned about the blind register
save/restore by memcpy_to/fromio. I haven't looked at the chip
documentation, but it looks scary. Is it safe to restore those
registers in that manner?
Well... the code is only applicable for Lite5200b/mpc5200
and numbers are from specs.
And it's shorter than mpc52xx_find_and_map() lines.
I guess I could rewrite it.
From: Andrei Konovalov <hidden> Date: 2007-03-16 08:10:51
Hello,
Haven't tried using u-boot with these boards, but here are couple earlier postings
to this list (sorry if you have look through them already):
-------- Original Message --------
Subject: Re: ML403 patch for UBOOT
Date: Mon, 25 Sep 2006 09:19:10 -0700
From: Peter Ryser <redacted>
To: Linuxppc-embedded@ozlabs.org
You might want to start with XAPP542
http://direct.xilinx.com/bvdocs/appnotes/xapp542.pdfhttp://direct.xilinx.com/bvdocs/appnotes/xapp542.zip
The zip file includes the U-Boot patch for Linux kernel 2.4.
- Peter
-------- End of Original Message --------
-------- Original Message --------
Subject: Re: Led astray? Xilinx ml410 + u-boot + Linux?
Date: Thu, 01 Feb 2007 06:57:50 -0800
From: Peter Ryser <redacted>
To: linuxppc-embedded@ozlabs.org
Joe,
please have a look at http://www.xilinx.com/ml410-p. The pages do
contain information, documentation, and examples on how to use U-Boot
and Linux 2.4 on the ML410.
<snip>
-------- End of Original Message --------
For me this sounds like
1) patching kernel is required to get the correct params from u-boot
2) Xilinx has the recipes for 2.4 kernel
3) there is no ready-to-use recipe for 2.6 kernel, but it should not
be too difficult to adapt the one for 2.4 kernel
Thanks,
Andrei
Leonid wrote:
Hi:
I'm trying to bring up Linux on Xilinx ML403 reference board.
I took 2.6.19.2 kernel from DENX. EDK project for ML403 I took from
official Xilinx site.
I could bring up u-boot on the board, everything is working fine (see
ml403.h file attached). Then I compiled uImage for kernel and tried to
download it - I don't see any kernel's outputs:
TFTP from server 192.168.0.141; our IP address is 192.168.0.203
Filename 'LM200/rel/1.0.1d-403/uImage'.
Load address: 0x1000000
Loading: T
#################################################################
#################################################################
#######################################
done
Bytes transferred = 861735 (d2627 hex)
## Booting image at 01000000 ...
Image Name: Linux-2.6.19.2
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 861671 Bytes = 841.5 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
## Current stack ends at 0x03E676F0 => set upper limit to 0x00800000
## cmdline at 0x007FFF00 ... 0x007FFFF8
memstart = 0x00000000
memsize = 0x04000000
flashstart = 0x28000000
flashsize = 0x00800000
flashoffset = 0x00000000
sramstart = 0x00000000
sramsize = 0x00000000
bootflags = 0x0000003C
procfreq = 300 MHz
plb_busfreq = 100 MHz
ethaddr = 00:01:02:CB:CB:71
IP addr = 192.168.0.203
baudrate = 115200 bps
No initrd
## Transferring control to Linux (at address 00000000) ...
I have read a lot of posts and reviewed the source code and I think
these kernel trees I'm using are properly patched for using u-boot; I
only included asm/ppcboot.h into xilinx_403.h:
/* U-boot expects the bd_t to look like the one in ppcboot.h, not like
this. */
#ifdef NOT_USING_UBOOT
typedef struct board_info {
unsigned int bi_memsize; /* DRAM installed, in
bytes */
unsigned char bi_enetaddr[6]; /* Local Ethernet MAC
address */
unsigned int bi_intfreq; /* Processor speed, in
Hz */
unsigned int bi_busfreq; /* PLB Bus speed, in Hz
*/
unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz
*/
} bd_t;
/* Some 4xx parts use a different timebase frequency from the internal
clock.
*/
#define bi_tbfreq bi_intfreq
#else
#include <asm/ppcboot.h>
#endif /* UBOOT */
Anyway I tried to compile zImage.elf and download it directly to RAM
using XMD. Here I had partial success: first time after FPGA image
downloading I try it, I see the following (it doesn't happen if I try to
repeat downloading again without reloading FPGA image first):
====
loaded at: 00400000 004DA13C
board data at: 004D8124 004D813C
relocated to: 00404090 004040A8
zimage at: 00404E1D 004D7401
avail ram: 004DB000 04000000
Linux/PPC load: console=ttyS0,115200
Uncompressing Linux...done.
Now booting the kernel
[ 0.000000] Linux version 2.6.19.2 (root@mylinux.a-k-a.local) (gcc
version 4.0.0 (DENX ELDK 4.1 4.0.0)) #6 Thu Mar 15 05:46:09 PST 2007
[ 0.000000] Xilinx ML403 Reference System (Virtex-4 FX)
[ 0.000000] Zone PFN ranges:
[ 0.000000] DMA 0 -> 16384
[ 0.000000] Normal 16384 -> 16384
[ 0.000000] early_node_map[1] active PFN ranges
[ 0.000000] 0: 0 -> 16384
[ 0.000000] Built 1 zonelists. Total pages: 16256
[ 0.000000] Kernel command line: console=ttyS0,115200
[ 0.000000] Xilinx INTC #0 at 0xD1000FC0 mapped to 0xFDFFEFC0
[ 0.000000] PID hash table entries: 256 (order: 8, 1024 bytes)
[ 0.000188] Console: colour dummy device 80x25
[ 0.000701] Dentry cache hash table entries: 8192 (order: 3, 32768
bytes)
[ 0.001489] Inode-cache hash table entries: 4096 (order: 2, 16384
bytes)
[ 0.015326] Memory: 63104k available (1324k kernel code, 436k data,
92k init, 0k highmem)
[ 0.108476] Mount-cache hash table entries: 512
[ 0.114051] NET: Registered protocol family 16
[ 0.128395] NET: Registered protocol family 2
[ 0.168472] IP route cache hash table entries: 512 (order: -1, 2048
bytes)
[ 0.169340] TCP established hash table entries: 2048 (order: 1, 8192
bytes)
[ 0.169539] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.169648] TCP: Hash tables configured (established 2048 bind 1024)
[ 0.169679] TCP reno registered
[ 0.173555] io scheduler noop registered
[ 0.173600] io scheduler anticipatory registered (default)
[ 0.173630] io scheduler deadline registered
[ 0.173756] io scheduler cfq registered
[ 0.221629] Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ
sharing disabled
[ 0.227023] serial8250.0: ttyS0 at MMIO 0xa0001003 (irq = 9) is a
16450
[ 0.398738] RAMDISK driver initialized: 16 RAM disks of 65536K size
1024 blocksize
[ 0.407941] tun: Universal TUN/TAP device driver, 1.6
[ 0.412993] tun: (C) 1999-2004 Max Krasnyansky [off-list ref]
[ 0.420583] mice: PS/2 mouse device common for all mice
[ 0.426040] TCP cubic registered
[ 0.429347] NET: Registered protocol family 1
[ 0.433727] NET: Registered protocol family 17
[ 0.439482] VFS: Cannot open root device "<NULL>" or
unknown-block(0,0)
[ 0.446095] Please append a correct "root=" boot option
[ 0.451282] Kernel panic - not syncing: VFS: Unable to mount root fs
on unknown-block(0,0)
[ 0.459492] <0>Rebooting in 180 seconds..
I don't care about kernel panic for now - it's to be expected since I
don't provide any filesystem.
So, kernel itself is workable, it looks like uImage doesn't pick up
correct board info parameters from u-boot. Where u-boot write them and
where Linux looks for them? What is the simplest way to sync between
u-boot and kernel?
Thanks,
Leonid.
------------------------------------------------------------------------
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Well... the code is only applicable for Lite5200b/mpc5200
and numbers are from specs.
And it's shorter than mpc52xx_find_and_map() lines.
I guess I could rewrite it.
In asm code I need access to SDRAM controller registers (MBAR+0x100).
Do I add an entry to dts, or do you have other suggestions?
Domen
From: Domen Puncer <hidden> Date: 2007-03-22 07:44:46
Trivial suspend and resume OF OHCI.
On MPC52xx turn off and on power to ports.
Signed-off-by: Domen Puncer <redacted>
---
drivers/usb/host/ohci-ppc-of.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
Index: grant.git/drivers/usb/host/ohci-ppc-of.c
===================================================================
Not good, what if you have a Ohci PCI card on a 5200 board ...
You somehow need to check the compatible list of the of_node associated
with the particular instance you're putting to sleep.
Sylvain
From: Grant Likely <hidden> Date: 2007-03-23 15:58:05
On 3/15/07, Domen Puncer [off-list ref] wrote:
Implement deep-sleep on MPC52xx.
SDRAM is put into self-refresh with help of SRAM code
(alternatives would be code in FLASH, I-cache).
Interrupt code must also not be in SDRAM, so put it
in I-cache.
MPC52xx core is static, so contents will remain intact even
with clocks turned off.
--- /dev/null+++ grant.git/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+/* you will want to change this, to match your board gpios, rtc or whatever */
+static void mpc52xx_set_wakeup_mode(void)
+{
+ struct mpc52xx_gpio_wkup __iomem *gpiow;
+ struct mpc52xx_intr __iomem *intr;
+#ifdef CONFIG_PPC_LITE5200
+ int pin = 1; /* GPIO_WKUP_1 (GPIO_PSC2_4) */
+ int level_low = 1; /* wakeup on low level */
+#elif defined CONFIG_PPC_EFIKA
+ int pin = 4; /* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */
+ int level_low = 0; /* wakeup on high level */
+ /* IOW. to wake it up, short pins 1 and 3 on IRDA connector */
+#else
+#warning "define how would you like your board to wake"
+#endif
The EFIKA and LITE5200 support needs to coexist. efika.c and
lite5200.c should each have their own set_wakeup_mode function. The
correct function pointer should be selected from *_setup_arch().
Adding a new arch_initcall is dangerous. It gets called on *all*
architectures if the 5200 support is compiled in. mp52xx_pm_init
should be called from the setup_arch hook; lite5200_setup_arch() &
efika_setup_arch()
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
Not good, what if you have a Ohci PCI card on a 5200 board ...
You somehow need to check the compatible list of the of_node associated
with the particular instance you're putting to sleep.
Also, I don't think the device tree should be queried at runtime
inside the suspend/resume functions. All device tree queries should
probably go into the probe() routine and the results cached.
However, I'm no longer convinced that this is the correct approach.
I've gone and looked at the 5200b usb documentation, and it looks to
me like the handling of port power is really a board/system specific
thing. For example, a new system might require port power to be
forced on when the processor is suspended.
I think this code should be moved to the board support code in
arch/powerpc/platforms/52xx.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
Well... the code is only applicable for Lite5200b/mpc5200
and numbers are from specs.
And it's shorter than mpc52xx_find_and_map() lines.
I guess I could rewrite it.
In asm code I need access to SDRAM controller registers (MBAR+0x100).
Do I add an entry to dts, or do you have other suggestions?
And on efika, the same problem + there is no CDM nor (wakeup)
gpio's in device tree. What to do there?
Domen
From: Grant Likely <hidden> Date: 2007-03-26 15:54:44
On 3/26/07, Domen Puncer [off-list ref] wrote:
On 22/03/07 08:41 +0100, Domen Puncer wrote:
quoted
On 15/03/07 17:36 +0100, Domen Puncer wrote:
quoted
Well... the code is only applicable for Lite5200b/mpc5200
and numbers are from specs.
And it's shorter than mpc52xx_find_and_map() lines.
I guess I could rewrite it.
In asm code I need access to SDRAM controller registers (MBAR+0x100).
Do I add an entry to dts, or do you have other suggestions?
Fair enough; this is chip-specific code after all; not device driver
code. MBAR must always be retrieved from the device tree, but these
offsets from MBAR will never move, so you don't need to pull them from
the device tree. At least comment it as to where the numbers came
from.
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
From: Grant Likely <hidden> Date: 2007-03-26 16:08:33
On 3/15/07, Domen Puncer [off-list ref] wrote:
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
This looks pretty straight forward.
My only comment is that psc2_4 is probably used as GPIO instead of
power control by some users (The lite5200 is an eval board after all).
Maybe wrap the code with #ifdef CONFIG_LITE5200B_PM (instead of
CONFIG_LITE5200B) so that it can be easily compiled out.
Also, '//' style comments should be changed to '/* */'
Otherwise;
Acked-by: Grant Likely <redacted>
g.
@@ -42,6 +42,54 @@#include"mt48lc16m16a2-75.h"# endif#endif++#ifdef CONFIG_LITE5200B+/* u-boot part of low-power mode implementation */+#define SAVED_ADDR (*(void **)0x00000000)+#define PSC2_4 0x02++voidlite5200b_wakeup(void)+{+unsignedcharwakeup_pin;+void(*linux_wakeup)(void);++/* check PSC2_4, if it's down "QT" is signaling we have a wakeup+*fromlowpowermode*/+*(vu_char*)MPC5XXX_WU_GPIO_ENABLE=PSC2_4;+__asm__volatile("sync");++wakeup_pin=*(vu_char*)MPC5XXX_WU_GPIO_DATA_I;+if(wakeup_pin&PSC2_4)+return;++/* acknowledge to "QT"+*byholdingpinat1for10uS*/+*(vu_char*)MPC5XXX_WU_GPIO_DIR=PSC2_4;+__asm__volatile("sync");+*(vu_char*)MPC5XXX_WU_GPIO_DATA_O=PSC2_4;+__asm__volatile("sync");+udelay(10);++/* put ram out of self-refresh */+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x80000000;// mode_en+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x50000000;// cke ref_en+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL&=~0x80000000;// !mode_en+__asm__volatile("sync");+udelay(10);/* wait a bit */++/* jump back to linux kernel code */+linux_wakeup=SAVED_ADDR;+printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",+linux_wakeup);+linux_wakeup();+}+#else+#define lite5200b_wakeup()+#endif++#ifndef CFG_RAMBOOTstaticvoidsdram_start(inthi_addr){
@@ -208,6 +256,8 @@ long int initdram (int board_type)__asm__volatile("sync");}+lite5200b_wakeup();+returndramsize+dramsize2;}
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
Hi Domen,
As I understand while waking up from the low-power mode the machine is
effectively powering on, similarly to the cold reset, so U-Boot runs
from the beginning as usual, but after the SDRAM controller has been
initialised we detect the wakeup and teleport to the saved DRAM address.
Since in case of a wakeup from the low-power mode we skip everything in
U-Boot that is happening past initdram(), please clarify the following:
- are you sure there are no steps beyond init_func_ram()/board_init_f()
that should be performed while waking up? For example:
- are all timers settings properly re-stored?
- wouldn't the host/PCI bridge need to be re-initialised and
re-configured as part of the wakeup process? Did you happen to test some
PCI devices and would they survive after wakeup from the the low-power
mode? (A similar question would apply to the USB controller)
Also, a more general question: isn't time base update required after the
wakeup, specially if it's been a long sleep?
kind regards,
Rafal
From: Domen Puncer <hidden> Date: 2007-03-31 18:38:52
On 31/03/07 19:20 +0200, Rafal Jaworowski wrote:
Domen Puncer wrote:
quoted
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
Hi Domen,
Hi!
As I understand while waking up from the low-power mode the machine is
effectively powering on, similarly to the cold reset, so U-Boot runs
from the beginning as usual, but after the SDRAM controller has been
initialised we detect the wakeup and teleport to the saved DRAM address.
Right.
Since in case of a wakeup from the low-power mode we skip everything in
U-Boot that is happening past initdram(), please clarify the following:
- are you sure there are no steps beyond init_func_ram()/board_init_f()
that should be performed while waking up? For example:
- are all timers settings properly re-stored?
Hmm... right, I forgot to restart watchdog... but that will be done in
Linux code.
- wouldn't the host/PCI bridge need to be re-initialised and
re-configured as part of the wakeup process? Did you happen to test some
PCI devices and would they survive after wakeup from the the low-power
mode? (A similar question would apply to the USB controller)
Honestly, I don't know for PCI. IIRC some time ago, kernel compiled
with CONFIG_PCI didn't boot for me.
USB controller/devices survived the wakeup last time I checked.
Also, a more general question: isn't time base update required after the
wakeup, specially if it's been a long sleep?
Lite5200b doesn't have an external time source.
Thanks!
Domen
From: Domen Puncer <hidden> Date: 2007-04-03 08:46:56
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
---
On 26/03/07 10:08 -0600, Grant Likely wrote:
On 3/15/07, Domen Puncer [off-list ref] wrote:
quoted
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
This looks pretty straight forward.
My only comment is that psc2_4 is probably used as GPIO instead of
power control by some users (The lite5200 is an eval board after all).
Maybe wrap the code with #ifdef CONFIG_LITE5200B_PM (instead of
CONFIG_LITE5200B) so that it can be easily compiled out.
Also, '//' style comments should be changed to '/* */'
Otherwise;
Acked-by: Grant Likely <redacted>
OK. This one should be better:
Makefile | 5 ++++
board/icecube/icecube.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
Index: u-boot.git/board/icecube/icecube.c
===================================================================
@@ -42,6 +42,53 @@#include"mt48lc16m16a2-75.h"# endif#endif++#ifdef CONFIG_LITE5200B_PM+/* u-boot part of low-power mode implementation */+#define SAVED_ADDR (*(void **)0x00000000)+#define PSC2_4 0x02++voidlite5200b_wakeup(void)+{+unsignedcharwakeup_pin;+void(*linux_wakeup)(void);++/* check PSC2_4, if it's down "QT" is signaling we have a wakeup+*fromlowpowermode*/+*(vu_char*)MPC5XXX_WU_GPIO_ENABLE=PSC2_4;+__asm__volatile("sync");++wakeup_pin=*(vu_char*)MPC5XXX_WU_GPIO_DATA_I;+if(wakeup_pin&PSC2_4)+return;++/* acknowledge to "QT"+*byholdingpinat1for10uS*/+*(vu_char*)MPC5XXX_WU_GPIO_DIR=PSC2_4;+__asm__volatile("sync");+*(vu_char*)MPC5XXX_WU_GPIO_DATA_O=PSC2_4;+__asm__volatile("sync");+udelay(10);++/* put ram out of self-refresh */+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x80000000;/* mode_en */+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x50000000;/* cke ref_en */+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL&=~0x80000000;/* !mode_en */+__asm__volatile("sync");+udelay(10);/* wait a bit */++/* jump back to linux kernel code */+linux_wakeup=SAVED_ADDR;+printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",+linux_wakeup);+linux_wakeup();+}+#else+#define lite5200b_wakeup()+#endif+#ifndef CFG_RAMBOOTstaticvoidsdram_start(inthi_addr){
@@ -208,6 +255,8 @@ long int initdram (int board_type)__asm__volatile("sync");}+lite5200b_wakeup();+returndramsize+dramsize2;}
From: Domen Puncer <hidden> Date: 2007-04-04 07:38:04
Hi!
How about something like the following.
Changes:
- lots of code moved from asm to C
- add compatible "mpc5200" to lite5200x soc (already is this
way on efika). And change Efika's soc device_type to "soc".
- add wakeup supported with RTC (1 to 24*60-1 minutes)
- each board now configures it's wakeup mode and possibly
board suspend and resume functions it needs to call (USB on lite)
This code survived > 70k suspend/resume cycles :-)
Comments?
Implement deep-sleep on MPC52xx.
SDRAM is put into self-refresh with help of SRAM code
(alternatives would be code in FLASH, I-cache).
Interrupt code must also not be in SDRAM, so put it
in I-cache.
MPC52xx core is static, so contents will remain intact even
with clocks turned off.
Signed-off-by: Domen Puncer <redacted>
---
arch/powerpc/boot/dts/lite5200.dts | 1
arch/powerpc/boot/dts/lite5200b.dts | 1
arch/powerpc/kernel/prom_init.c | 2
arch/powerpc/platforms/52xx/Makefile | 2
arch/powerpc/platforms/52xx/efika.c | 8
arch/powerpc/platforms/52xx/lite5200.c | 28 +++
arch/powerpc/platforms/52xx/mpc52xx_pm.c | 230 ++++++++++++++++++++++++++++
arch/powerpc/platforms/52xx/mpc52xx_sleep.S | 161 +++++++++++++++++++
include/asm-powerpc/mpc52xx.h | 63 +++++++
9 files changed, 495 insertions(+), 1 deletion(-)
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -0,0 +1,230 @@+#include<linux/init.h>+#include<linux/pm.h>+#include<linux/io.h>+#include<asm/time.h>+#include<asm/cacheflush.h>+#include<asm/mpc52xx.h>+#include"bestcomm.h"++#undef DEBUG /* define for 1s wakeups */+externvoidmpc52xx_deep_sleep(void*sram,void*,structmpc52xx_cdm*,structmpc52xx_intr*);++staticvoid__iomem*mbar;+staticvoid__iomem*sdram;+staticstructmpc52xx_cdm__iomem*cdm;+staticstructmpc52xx_intr__iomem*intr;+staticstructmpc52xx_rtc__iomem*rtc;+staticstructmpc52xx_gpio_wkup__iomem*gpiow;++structmpc52xx_wakeupmpc52xx_wakeup;++staticintmpc52xx_pm_valid(suspend_state_tstate)+{+switch(state){+casePM_SUSPEND_STANDBY:+return1;+default:+return0;+}+}++staticintmpc52xx_set_wakeup_gpio(u8pin,u8level)+{+u16tmp;++/* enable gpio */+out_8(&gpiow->wkup_gpioe,in_8(&gpiow->wkup_gpioe)|(1<<pin));+/* set as input */+out_8(&gpiow->wkup_ddr,in_8(&gpiow->wkup_ddr)&~(1<<pin));+/* enable deep sleep interrupt */+out_8(&gpiow->wkup_inten,in_8(&gpiow->wkup_inten)|(1<<pin));+/* low/high level creates wakeup interrupt */+tmp=in_be16(&gpiow->wkup_itype);+tmp&=~(0x3<<(pin*2));+tmp|=(!level+1)<<(pin*2);+out_be16(&gpiow->wkup_itype,tmp);+/* master enable */+out_8(&gpiow->wkup_maste,1);++/* enable wakeup gpio interrupt in PIC */+out_be32(&intr->main_mask,in_be32(&intr->main_mask)&~(1<<8));++return0;+}++staticintmpc52xx_set_wakeup_rtc(intdelay)+{+#ifndef DEBUG+u8hour;+u8minute;++if(delay<0)+return-EINVAL;+elseif(delay==0)+return0;++hour=in_8(&rtc->hour);+minute=in_8(&rtc->minute);++hour+=delay/60;+hour%=24;+minute+=delay%60+1;+if(minute>=60){+minute-=60;+hour++;+}++out_8(&rtc->alm_hour_set,hour);+out_8(&rtc->alm_min_set,minute);+out_8(&rtc->alm_enable,1);+#else+u8tmp=in_8(&rtc->int_enable);+out_8(&rtc->int_enable,(tmp&~0x8)|0x1);/* every second */+#endif++return0;+}++intmpc52xx_pm_prepare(suspend_state_tstate)+{+if(state!=PM_SUSPEND_STANDBY)+return-EINVAL;++/* map the whole register space */+mbar=mpc52xx_find_and_map("mpc5200");+if(!mbar){+printk(KERN_ERR"%s:%i Error mapping registers\n",__func__,__LINE__);+return-ENOSYS;+}+/* these offsets are from mpc5200 users manual */+sdram=mbar+0x100;+cdm=mbar+0x200;+intr=mbar+0x500;+rtc=mbar+0x800;+gpiow=mbar+0xc00;+++#ifdef DEBUG+mpc52xx_wakeup.mask|=WAKEUP_RTC;+#endif+if(mpc52xx_wakeup.mask==0){+printk(KERN_ALERT"%s: %i don't know how to wake up the board\n",+__func__,__LINE__);+gotoout_unmap;+}+if(mpc52xx_wakeup.mask&WAKEUP_GPIO){+if(mpc52xx_set_wakeup_gpio(mpc52xx_wakeup.pin,mpc52xx_wakeup.level))+gotoout_unmap;+}+if(mpc52xx_wakeup.mask&WAKEUP_RTC){+if(mpc52xx_set_wakeup_rtc(mpc52xx_wakeup.delay))+gotoout_unmap;+}+if(mpc52xx_wakeup.mask&WAKEUP_MSCAN){+/* TODO */+}++/* call board suspend code, if applicable */+if(mpc52xx_wakeup.board_suspend_prepare)+mpc52xx_wakeup.board_suspend_prepare(mbar);++return0;++out_unmap:+iounmap(mbar);+return-ENOSYS;+}++externvoidmpc52xx_ds_sram(void);+externconstlongmpc52xx_ds_sram_size;+externvoidmpc52xx_ds_cached(void);+externconstlongmpc52xx_ds_cached_size;++staticcharsaved_sram[0x4000];++intmpc52xx_pm_enter(suspend_state_tstate)+{+u32clk_enables;+u32msr,hid0;+void__iomem*irq_0x500=(void*)CONFIG_KERNEL_START+0x500;+unsignedlongirq_0x500_stop=(unsignedlong)irq_0x500+mpc52xx_ds_cached_size;+charsaved_0x500[mpc52xx_ds_cached_size];++/* don't let DEC expire any time soon */+mtspr(SPRN_DEC,0x7fffffff);++/* save SRAM */+memcpy(saved_sram,sdma.sram,sdma.sram_size);++/* copy low level suspend code to sram */+memcpy(sdma.sram,mpc52xx_ds_sram,mpc52xx_ds_sram_size);++out_8(&cdm->ccs_sleep_enable,1);+out_8(&cdm->osc_sleep_enable,1);+out_8(&cdm->ccs_qreq_test,1);++/* disable all but SDRAM and bestcomm (SRAM) clocks */+clk_enables=in_be32(&cdm->clk_enables);+out_be32(&cdm->clk_enables,clk_enables&0x00088000);++/* disable power management */+msr=mfmsr();+mtmsr(msr&~MSR_POW);++/* enable sleep mode, disable others */+hid0=mfspr(SPRN_HID0);+mtspr(SPRN_HID0,(hid0&~(HID0_DOZE|HID0_NAP|HID0_DPM))|HID0_SLEEP);++/* save original, copy our irq handler, flush from dcache and invalidate icache */+memcpy(saved_0x500,irq_0x500,mpc52xx_ds_cached_size);+memcpy(irq_0x500,mpc52xx_ds_cached,mpc52xx_ds_cached_size);+flush_icache_range((unsignedlong)irq_0x500,irq_0x500_stop);++/* call low-level sleep code */+mpc52xx_deep_sleep(sdma.sram,sdram,cdm,intr);++/* restore original irq handler */+memcpy(irq_0x500,saved_0x500,mpc52xx_ds_cached_size);+flush_icache_range((unsignedlong)irq_0x500,irq_0x500_stop);++/* restore old power mode */+mtmsr(msr&~MSR_POW);+mtspr(SPRN_HID0,hid0);+mtmsr(msr);++out_be32(&cdm->clk_enables,clk_enables);+out_8(&cdm->ccs_sleep_enable,0);+out_8(&cdm->osc_sleep_enable,0);++/* restore SRAM */+memcpy(sdma.sram,saved_sram,sdma.sram_size);++/* restart jiffies */+wakeup_decrementer();++return0;+}++staticintmpc52xx_pm_finish(suspend_state_tstate)+{+/* call board resume code */+if(mpc52xx_wakeup.board_resume_finish)+mpc52xx_wakeup.board_resume_finish(mbar);++iounmap(mbar);++return0;+}++staticstructpm_opsmpc52xx_pm_ops={+.valid=mpc52xx_pm_valid,+.prepare=mpc52xx_pm_prepare,+.enter=mpc52xx_pm_enter,+.finish=mpc52xx_pm_finish,+};++int__initmpc52xx_pm_init(void)+{+pm_set_ops(&mpc52xx_pm_ops);+return0;+}
@@ -200,6 +200,14 @@ static void __init efika_setup_arch(voidefika_pcisetup();+#ifdef CONFIG_PM+mpc52xx_wakeup.mask=WAKEUP_GPIO|WAKEUP_RTC;+mpc52xx_wakeup.pin=4;/* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */+mpc52xx_wakeup.level=1;/* wakeup on high level */+/* IOW. to wake it up, short pins 1 and 3 on IRDA connector */+mpc52xx_pm_init();+#endif+if(ppc_md.progress)ppc_md.progress("Linux/PPC "UTS_RELEASE" running on Efika ;-)\n",0x0);}
@@ -253,5 +298,23 @@ extern int __init mpc52xx_add_bridge(str#endif /* __ASSEMBLY__ */+#ifdef CONFIG_PM+#define WAKEUP_GPIO (1<<1)+#define WAKEUP_RTC (2<<1)+#define WAKEUP_MSCAN (3<<1)+structmpc52xx_wakeup{+u8mask;+u8pin;/* which wakeup GPIO */+u8level;/* transition to high or to low level */+u16delay;/* after how many minutes (RTC) */++void(*board_suspend_prepare)(void__iomem*mbar);+void(*board_resume_finish)(void__iomem*mbar);+};++externstructmpc52xx_wakeupmpc52xx_wakeup;+int__initmpc52xx_pm_init(void);+#endif /* CONFIG_PM */+#endif /* __ASM_POWERPC_MPC52xx_H__ */
From: Grant Likely <hidden> Date: 2007-04-16 04:45:07
On 4/3/07, Domen Puncer [off-list ref] wrote:
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
Looks good; almost there. Only one thing missing... you need to add
your "Signed-off-by" line. :-) See Documentation/SubmittingPatches
in the Linux source tree. (You can just reply to this message, and
whoever merges the patch will add the line to the commit message)
Acked-by: Grant Likely <redacted>
Stefan; since there is no 5200 custodian, can you please pick up this
patch once Domen sends a Signed-of-by replay?
Cheers,
g.
quoted hunk
---
On 26/03/07 10:08 -0600, Grant Likely wrote:
quoted
On 3/15/07, Domen Puncer [off-list ref] wrote:
quoted
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
This looks pretty straight forward.
My only comment is that psc2_4 is probably used as GPIO instead of
power control by some users (The lite5200 is an eval board after all).
Maybe wrap the code with #ifdef CONFIG_LITE5200B_PM (instead of
CONFIG_LITE5200B) so that it can be easily compiled out.
Also, '//' style comments should be changed to '/* */'
Otherwise;
Acked-by: Grant Likely <redacted>
OK. This one should be better:
Makefile | 5 ++++
board/icecube/icecube.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
Index: u-boot.git/board/icecube/icecube.c
===================================================================
@@ -42,6 +42,53 @@#include"mt48lc16m16a2-75.h"# endif#endif++#ifdef CONFIG_LITE5200B_PM+/* u-boot part of low-power mode implementation */+#define SAVED_ADDR (*(void **)0x00000000)+#define PSC2_4 0x02++voidlite5200b_wakeup(void)+{+unsignedcharwakeup_pin;+void(*linux_wakeup)(void);++/* check PSC2_4, if it's down "QT" is signaling we have a wakeup+*fromlowpowermode*/+*(vu_char*)MPC5XXX_WU_GPIO_ENABLE=PSC2_4;+__asm__volatile("sync");++wakeup_pin=*(vu_char*)MPC5XXX_WU_GPIO_DATA_I;+if(wakeup_pin&PSC2_4)+return;++/* acknowledge to "QT"+*byholdingpinat1for10uS*/+*(vu_char*)MPC5XXX_WU_GPIO_DIR=PSC2_4;+__asm__volatile("sync");+*(vu_char*)MPC5XXX_WU_GPIO_DATA_O=PSC2_4;+__asm__volatile("sync");+udelay(10);++/* put ram out of self-refresh */+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x80000000;/* mode_en */+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL|=0x50000000;/* cke ref_en */+__asm__volatile("sync");+*(vu_long*)MPC5XXX_SDRAM_CTRL&=~0x80000000;/* !mode_en */+__asm__volatile("sync");+udelay(10);/* wait a bit */++/* jump back to linux kernel code */+linux_wakeup=SAVED_ADDR;+printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",+linux_wakeup);+linux_wakeup();+}+#else+#define lite5200b_wakeup()+#endif+#ifndef CFG_RAMBOOTstaticvoidsdram_start(inthi_addr){
@@ -208,6 +255,8 @@ long int initdram (int board_type)__asm__volatile("sync");}+lite5200b_wakeup();+returndramsize+dramsize2;}
From: Grant Likely <hidden> Date: 2007-04-16 05:40:55
On 4/4/07, Domen Puncer [off-list ref] wrote:
Hi!
How about something like the following.
Changes:
- lots of code moved from asm to C
- add compatible "mpc5200" to lite5200x soc (already is this
way on efika). And change Efika's soc device_type to "soc".
- add wakeup supported with RTC (1 to 24*60-1 minutes)
- each board now configures it's wakeup mode and possibly
board suspend and resume functions it needs to call (USB on lite)
Sorry it took so long for me to review and get back to you on this
patch. I got wrapped up in other tasks.
I mostly like the approach that you're taking here to allow each board
to select it's own wakeup method, but I think it should be taken a
step farther. Instead of providing a set of stock
mpc52xx_set_wakeup_*() functions, I think it would make for simpler
and more flexible code if each board takes care of its own wakeup
configuration in the board_suspend_prepare hook. In fact, the
mpc52xx_set_wakeup_*() functions themselves make a lot of sense, and
are useful utility functions. But rather than trying to codify which
pins/rtc to configure for wakeup via the .mask, .level, .pin and
.delay items, those functions should be called directly by
lite5200_suspend_prepare() and efika_suspend_prepare(). Doing this
will drop 19 lines of common code in exchange for adding 2 lines to
each board port.
As an added bonus, doing it this way allows multiple pins to be used
for wakeup. :-)
This code survived > 70k suspend/resume cycles :-)
+extern void mpc52xx_ds_sram(void);
+extern const long mpc52xx_ds_sram_size;
+extern void mpc52xx_ds_cached(void);
+extern const long mpc52xx_ds_cached_size;
This *looks* like dangerous code (function prototypes not in a shared
header). You should add a big comment here to the fact that these are
assembly functions that are only ever referenced in this file.
===================================================================
From: Domen Puncer <hidden> Date: 2007-04-16 06:25:40
On 15/04/07 22:45 -0600, Grant Likely wrote:
On 4/3/07, Domen Puncer [off-list ref] wrote:
quoted
U-Boot part of Lite5200b low power mode support.
Puts SDRAM out of self-refresh and transfers control to
address saved at physical 0x0.
Looks good; almost there. Only one thing missing... you need to add
your "Signed-off-by" line. :-) See Documentation/SubmittingPatches
in the Linux source tree. (You can just reply to this message, and
whoever merges the patch will add the line to the commit message)
Acked-by: Grant Likely <redacted>
Stefan; since there is no 5200 custodian, can you please pick up this
patch once Domen sends a Signed-of-by replay?
I thought Signed-off-by's are Linux specific.
Signed-off-by: Domen Puncer <redacted>
Thanks!
Domen
From: Domen Puncer <hidden> Date: 2007-04-17 07:05:18
Implement deep-sleep on MPC52xx.
SDRAM is put into self-refresh with help of SRAM code
(alternatives would be code in FLASH, I-cache).
Interrupt code must also not be in SDRAM, so put it
in I-cache.
MPC52xx core is static, so contents will remain intact even
with clocks turned off.
Signed-off-by: Domen Puncer <redacted>
---
arch/powerpc/platforms/52xx/Makefile | 2
arch/powerpc/platforms/52xx/efika.c | 15 ++
arch/powerpc/platforms/52xx/lite5200.c | 28 ++++
arch/powerpc/platforms/52xx/mpc52xx_pm.c | 187 ++++++++++++++++++++++++++++
arch/powerpc/platforms/52xx/mpc52xx_sleep.S | 154 +++++++++++++++++++++++
include/asm-powerpc/mpc52xx.h | 11 +
6 files changed, 397 insertions(+)
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -0,0 +1,187 @@+#include<linux/init.h>+#include<linux/pm.h>+#include<linux/io.h>+#include<asm/time.h>+#include<asm/cacheflush.h>+#include<asm/mpc52xx.h>+#include"bestcomm.h"+++/* these are defined in mpc52xx_sleep.S, and only used here */+externvoidmpc52xx_deep_sleep(void*sram,void*sdram_regs,+structmpc52xx_cdm*,structmpc52xx_intr*);+externvoidmpc52xx_ds_sram(void);+externconstlongmpc52xx_ds_sram_size;+externvoidmpc52xx_ds_cached(void);+externconstlongmpc52xx_ds_cached_size;++staticvoid__iomem*mbar;+staticvoid__iomem*sdram;+staticstructmpc52xx_cdm__iomem*cdm;+staticstructmpc52xx_intr__iomem*intr;+staticstructmpc52xx_gpio_wkup__iomem*gpiow;++structmpc52xx_suspendmpc52xx_suspend;++staticintmpc52xx_pm_valid(suspend_state_tstate)+{+switch(state){+casePM_SUSPEND_STANDBY:+return1;+default:+return0;+}+}++intmpc52xx_set_wakeup_gpio(u8pin,u8level)+{+u16tmp;++/* enable gpio */+out_8(&gpiow->wkup_gpioe,in_8(&gpiow->wkup_gpioe)|(1<<pin));+/* set as input */+out_8(&gpiow->wkup_ddr,in_8(&gpiow->wkup_ddr)&~(1<<pin));+/* enable deep sleep interrupt */+out_8(&gpiow->wkup_inten,in_8(&gpiow->wkup_inten)|(1<<pin));+/* low/high level creates wakeup interrupt */+tmp=in_be16(&gpiow->wkup_itype);+tmp&=~(0x3<<(pin*2));+tmp|=(!level+1)<<(pin*2);+out_be16(&gpiow->wkup_itype,tmp);+/* master enable */+out_8(&gpiow->wkup_maste,1);++return0;+}++intmpc52xx_pm_prepare(suspend_state_tstate)+{+if(state!=PM_SUSPEND_STANDBY)+return-EINVAL;++/* map the whole register space */+mbar=mpc52xx_find_and_map("mpc5200");+if(!mbar){+printk(KERN_ERR"%s:%i Error mapping registers\n",__func__,__LINE__);+return-ENOSYS;+}+/* these offsets are from mpc5200 users manual */+sdram=mbar+0x100;+cdm=mbar+0x200;+intr=mbar+0x500;+gpiow=mbar+0xc00;+++/* call board suspend code, if applicable */+if(mpc52xx_suspend.board_suspend_prepare)+mpc52xx_suspend.board_suspend_prepare(mbar);+else{+printk(KERN_ALERT"%s: %i don't know how to wake up the board\n",+__func__,__LINE__);+gotoout_unmap;+}++return0;++out_unmap:+iounmap(mbar);+return-ENOSYS;+}+++charsaved_sram[0x4000];++intmpc52xx_pm_enter(suspend_state_tstate)+{+u32clk_enables;+u32msr,hid0;+u32intr_main_mask;+void__iomem*irq_0x500=(void*)CONFIG_KERNEL_START+0x500;+unsignedlongirq_0x500_stop=(unsignedlong)irq_0x500+mpc52xx_ds_cached_size;+charsaved_0x500[mpc52xx_ds_cached_size];++/* disable all interrupts in PIC */+intr_main_mask=in_be32(&intr->main_mask);+out_be32(&intr->main_mask,intr_main_mask|0x1ffff);++/* don't let DEC expire any time soon */+mtspr(SPRN_DEC,0x7fffffff);++/* save SRAM */+memcpy(saved_sram,sdma.sram,sdma.sram_size);++/* copy low level suspend code to sram */+memcpy(sdma.sram,mpc52xx_ds_sram,mpc52xx_ds_sram_size);++out_8(&cdm->ccs_sleep_enable,1);+out_8(&cdm->osc_sleep_enable,1);+out_8(&cdm->ccs_qreq_test,1);++/* disable all but SDRAM and bestcomm (SRAM) clocks */+clk_enables=in_be32(&cdm->clk_enables);+out_be32(&cdm->clk_enables,clk_enables&0x00088000);++/* disable power management */+msr=mfmsr();+mtmsr(msr&~MSR_POW);++/* enable sleep mode, disable others */+hid0=mfspr(SPRN_HID0);+mtspr(SPRN_HID0,(hid0&~(HID0_DOZE|HID0_NAP|HID0_DPM))|HID0_SLEEP);++/* save original, copy our irq handler, flush from dcache and invalidate icache */+memcpy(saved_0x500,irq_0x500,mpc52xx_ds_cached_size);+memcpy(irq_0x500,mpc52xx_ds_cached,mpc52xx_ds_cached_size);+flush_icache_range((unsignedlong)irq_0x500,irq_0x500_stop);++/* call low-level sleep code */+mpc52xx_deep_sleep(sdma.sram,sdram,cdm,intr);++/* restore original irq handler */+memcpy(irq_0x500,saved_0x500,mpc52xx_ds_cached_size);+flush_icache_range((unsignedlong)irq_0x500,irq_0x500_stop);++/* restore old power mode */+mtmsr(msr&~MSR_POW);+mtspr(SPRN_HID0,hid0);+mtmsr(msr);++out_be32(&cdm->clk_enables,clk_enables);+out_8(&cdm->ccs_sleep_enable,0);+out_8(&cdm->osc_sleep_enable,0);++/* restore SRAM */+memcpy(sdma.sram,saved_sram,sdma.sram_size);++/* restart jiffies */+wakeup_decrementer();++/* reenable interrupts in PIC */+out_be32(&intr->main_mask,intr_main_mask);++return0;+}++intmpc52xx_pm_finish(suspend_state_tstate)+{+/* call board resume code */+if(mpc52xx_suspend.board_resume_finish)+mpc52xx_suspend.board_resume_finish(mbar);++iounmap(mbar);++return0;+}++staticstructpm_opsmpc52xx_pm_ops={+.valid=mpc52xx_pm_valid,+.prepare=mpc52xx_pm_prepare,+.enter=mpc52xx_pm_enter,+.finish=mpc52xx_pm_finish,+};++int__initmpc52xx_pm_init(void)+{+pm_set_ops(&mpc52xx_pm_ops);+return0;+}
@@ -185,6 +185,16 @@ static void efika_show_cpuinfo(struct seof_node_put(root);}+#ifdef CONFIG_PM+staticvoidefika_suspend_prepare(void__iomem*mbar)+{+u8pin=4;/* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */+u8level=1;/* wakeup on high level */+/* IOW. to wake it up, short pins 1 and 3 on IRDA connector */+mpc52xx_set_wakeup_gpio(pin,level);+}+#endif+staticvoid__initefika_setup_arch(void){rtas_initialize();
From: Grant Likely <hidden> Date: 2007-04-17 07:10:23
On 4/17/07, Domen Puncer [off-list ref] wrote:
Implement deep-sleep on MPC52xx.
SDRAM is put into self-refresh with help of SRAM code
(alternatives would be code in FLASH, I-cache).
Interrupt code must also not be in SDRAM, so put it
in I-cache.
MPC52xx core is static, so contents will remain intact even
with clocks turned off.
Signed-off-by: Domen Puncer <redacted>
From: Domen Puncer <hidden> Date: 2007-04-17 07:11:52
Low-power mode implementation for Lite5200b. (Most of devices
on board, including the CPU, are powered down)
Some I/O registers are also saved here.
A patch to U-Boot that wakes up SDRAM, and transfers control
to address saved at physical 0x0 is needed, and is already
merged in git://www.denx.de/git/u-boot-ppc4xx.git tree.
Signed-off-by: Domen Puncer <redacted>
---
arch/powerpc/platforms/52xx/Makefile | 3
arch/powerpc/platforms/52xx/lite5200.c | 2
arch/powerpc/platforms/52xx/lite5200_pm.c | 210 +++++++++++++
arch/powerpc/platforms/52xx/lite5200_sleep.S | 413 +++++++++++++++++++++++++++
include/asm-powerpc/mpc52xx.h | 10
5 files changed, 637 insertions(+), 1 deletion(-)
Index: grant.git/arch/powerpc/platforms/52xx/lite5200_pm.c
===================================================================
@@ -0,0 +1,210 @@+#include<linux/init.h>+#include<linux/pm.h>+#include<asm/io.h>+#include<asm/time.h>+#include<asm/mpc52xx.h>+#include"bestcomm.h"++/* defined in lite5200_sleep.S and only used here */+externvoidlite5200_low_power(void*sram,void*mbar);++staticstructmpc52xx_cdm__iomem*cdm;+staticstructmpc52xx_intr__iomem*pic;+staticstructmpc52xx_sdma__iomem*bes;+staticstructmpc52xx_xlb__iomem*xlb;+staticstructmpc52xx_gpio__iomem*gps;+staticstructmpc52xx_gpio_wkup__iomem*gpw;+staticvoid__iomem*mbar;++staticintlite5200_pm_valid(suspend_state_tstate)+{+switch(state){+casePM_SUSPEND_STANDBY:+casePM_SUSPEND_MEM:+return1;+default:+return0;+}+}++staticintlite5200_pm_prepare(suspend_state_tstate)+{+/* deep sleep? let mpc52xx code handle that */+if(state==PM_SUSPEND_STANDBY)+returnmpc52xx_pm_prepare(state);++if(state!=PM_SUSPEND_MEM)+return-EINVAL;++/* map registers */+mbar=mpc52xx_find_and_map("mpc5200");+if(!mbar){+printk(KERN_ERR"%s:%i Error mapping registers\n",__func__,__LINE__);+return-ENOSYS;+}++cdm=mbar+0x200;+pic=mbar+0x500;+gps=mbar+0xb00;+gpw=mbar+0xc00;+bes=mbar+0x1200;+xlb=mbar+0x1f00;++return0;+}++/* save and restore registers not bound to any real devices */+staticstructmpc52xx_cdmscdm;+staticstructmpc52xx_intrspic;+staticstructmpc52xx_sdmasbes;+staticstructmpc52xx_xlbsxlb;+staticstructmpc52xx_gpiosgps;+staticstructmpc52xx_gpio_wkupsgpw;++staticvoidlite5200_save_regs(void)+{+_memcpy_fromio(&spic,pic,sizeof(*pic));+_memcpy_fromio(&sbes,bes,sizeof(*bes));+_memcpy_fromio(&scdm,cdm,sizeof(*cdm));+_memcpy_fromio(&sxlb,xlb,sizeof(*xlb));+_memcpy_fromio(&sgps,gps,sizeof(*gps));+_memcpy_fromio(&sgpw,gpw,sizeof(*gpw));++memcpy(saved_sram,sdma.sram,sdma.sram_size);+}++staticvoidlite5200_restore_regs(void)+{+inti;+memcpy(sdma.sram,saved_sram,sdma.sram_size);+++/*+*GPIOs.InterruptMasterEnablehashigheraddressthenother+*registers,sojustmemcpyisok.+*/+_memcpy_toio(gpw,&sgpw,sizeof(*gpw));+_memcpy_toio(gps,&sgps,sizeof(*gps));+++/* XLB Arbitrer */+out_be32(&xlb->snoop_window,sxlb.snoop_window);+out_be32(&xlb->master_priority,sxlb.master_priority);+out_be32(&xlb->master_pri_enable,sxlb.master_pri_enable);++/* enable */+out_be32(&xlb->int_enable,sxlb.int_enable);+out_be32(&xlb->config,sxlb.config);+++/* CDM - Clock Distribution Module */+out_8(&cdm->ipb_clk_sel,scdm.ipb_clk_sel);+out_8(&cdm->pci_clk_sel,scdm.pci_clk_sel);++out_8(&cdm->ext_48mhz_en,scdm.ext_48mhz_en);+out_8(&cdm->fd_enable,scdm.fd_enable);+out_be16(&cdm->fd_counters,scdm.fd_counters);++out_be32(&cdm->clk_enables,scdm.clk_enables);++out_8(&cdm->osc_disable,scdm.osc_disable);++out_be16(&cdm->mclken_div_psc1,scdm.mclken_div_psc1);+out_be16(&cdm->mclken_div_psc2,scdm.mclken_div_psc2);+out_be16(&cdm->mclken_div_psc3,scdm.mclken_div_psc3);+out_be16(&cdm->mclken_div_psc6,scdm.mclken_div_psc6);+++/* BESTCOMM */+out_be32(&bes->taskBar,sbes.taskBar);+out_be32(&bes->currentPointer,sbes.currentPointer);+out_be32(&bes->endPointer,sbes.endPointer);+out_be32(&bes->variablePointer,sbes.variablePointer);++out_8(&bes->IntVect1,sbes.IntVect1);+out_8(&bes->IntVect2,sbes.IntVect2);+out_be16(&bes->PtdCntrl,sbes.PtdCntrl);++for(i=0;i<32;i++)+out_8(&bes->ipr[i],sbes.ipr[i]);++out_be32(&bes->cReqSelect,sbes.cReqSelect);+out_be32(&bes->task_size0,sbes.task_size0);+out_be32(&bes->task_size1,sbes.task_size1);+out_be32(&bes->MDEDebug,sbes.MDEDebug);+out_be32(&bes->ADSDebug,sbes.ADSDebug);+out_be32(&bes->Value1,sbes.Value1);+out_be32(&bes->Value2,sbes.Value2);+out_be32(&bes->Control,sbes.Control);+out_be32(&bes->Status,sbes.Status);+out_be32(&bes->PTDDebug,sbes.PTDDebug);++/* restore tasks */+for(i=0;i<16;i++)+out_be16(&bes->tcr[i],sbes.tcr[i]);++/* enable interrupts */+out_be32(&bes->IntPend,sbes.IntPend);+out_be32(&bes->IntMask,sbes.IntMask);+++/* PIC */+out_be32(&pic->per_pri1,spic.per_pri1);+out_be32(&pic->per_pri2,spic.per_pri2);+out_be32(&pic->per_pri3,spic.per_pri3);++out_be32(&pic->main_pri1,spic.main_pri1);+out_be32(&pic->main_pri2,spic.main_pri2);++out_be32(&pic->enc_status,spic.enc_status);++/* unmask and enable interrupts */+out_be32(&pic->per_mask,spic.per_mask);+out_be32(&pic->main_mask,spic.main_mask);+out_be32(&pic->ctrl,spic.ctrl);+}++staticintlite5200_pm_enter(suspend_state_tstate)+{+/* deep sleep? let mpc52xx code handle that */+if(state==PM_SUSPEND_STANDBY){+returnmpc52xx_pm_enter(state);+}++lite5200_save_regs();++/* effectively save FP regs */+enable_kernel_fp();++lite5200_low_power(sdma.sram,mbar);++lite5200_restore_regs();++/* restart jiffies */+wakeup_decrementer();++iounmap(mbar);+return0;+}++staticintlite5200_pm_finish(suspend_state_tstate)+{+/* deep sleep? let mpc52xx code handle that */+if(state==PM_SUSPEND_STANDBY){+returnmpc52xx_pm_finish(state);+}+return0;+}++staticstructpm_opslite5200_pm_ops={+.valid=lite5200_pm_valid,+.prepare=lite5200_pm_prepare,+.enter=lite5200_pm_enter,+.finish=lite5200_pm_finish,+};++int__initlite5200_pm_init(void)+{+pm_set_ops(&lite5200_pm_ops);+return0;+}
From: Grant Likely <hidden> Date: 2007-04-17 07:25:32
On 4/17/07, Domen Puncer [off-list ref] wrote:
Low-power mode implementation for Lite5200b. (Most of devices
on board, including the CPU, are powered down)
Some I/O registers are also saved here.
A patch to U-Boot that wakes up SDRAM, and transfers control
to address saved at physical 0x0 is needed, and is already
merged in git://www.denx.de/git/u-boot-ppc4xx.git tree.
Signed-off-by: Domen Puncer <redacted>