Skip to contentSkip to conversation

MPC5200 and Lite5200b low power modes

PATCH In review Domen Puncer 9 participants 41 messages Mar 15, 2007 – Apr 20, 2007

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

v2 cover MPC5200 and Lite5200b low power modes

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

#1 lore raw

PATCH v2 1/5 mpc52xx suspend: UART

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.

drivers/serial/mpc52xx_uart.c +20 -2
Index: grant.git/drivers/serial/mpc52xx_uart.c
===================================================================
@@ -418,6 +418,22 @@ mpc52xx_uart_verify_port(struct uart_por
 	return 0;
 }
 
+/* just Reenable TX and RX */
+static void mpc52xx_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
+{
+	struct mpc52xx_psc __iomem *psc = PSC(port);
+	unsigned long flags;
+
+	/* 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);
+}
 
 static struct uart_ops mpc52xx_uart_ops = {
 	.tx_empty	= mpc52xx_uart_tx_empty,
@@ -432,8 +448,10 @@ static struct uart_ops mpc52xx_uart_ops 
 	.startup	= mpc52xx_uart_startup,
 	.shutdown	= mpc52xx_uart_shutdown,
 	.set_termios	= mpc52xx_uart_set_termios,
-/*	.pm		= mpc52xx_uart_pm,		Not supported yet */
-/*	.set_wake	= mpc52xx_uart_set_wake,	Not supported yet */
+
+	.pm		= mpc52xx_uart_pm,
+/*	.set_wake	= mpc52xx_uart_set_wake,*/
+
 	.type		= mpc52xx_uart_type,
 	.release_port	= mpc52xx_uart_release_port,
 	.request_port	= mpc52xx_uart_request_port,
#2 lore raw

PATCH v2 2/5 mpc52xx suspend: FEC (ethernet)

In reply to Domen Puncer

Suspend and resume for FEC on MPC52xx.

Note that resume is a bit different for lite5200b low-power mode.

---
 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(-)
drivers/net/fec_mpc52xx/fec.c +58 -2
Index: grant.git/drivers/net/fec_mpc52xx/fec.c
===================================================================
@@ -801,6 +801,62 @@ mpc52xx_fec_remove(struct device *dev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int mpc52xx_fec_suspend(struct of_device *op, pm_message_t state)
+{
+	struct net_device *ndev = dev_get_drvdata(&op->dev);
+	struct fec_priv *priv = ndev->priv;
+	struct mpc52xx_fec *fec = priv->fec;
+
+	netif_device_detach(ndev);
+
+	/* Disable the rx and tx tasks. */
+	sdma_disable(priv->rx_sdma);
+	sdma_disable(priv->tx_sdma);
+
+	fec_free_rx_buffers(priv->rx_sdma);
+
+	/* Stop FEC */
+	out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~0x2);
+
+	fec_mii_suspend(ndev);
+
+	return 0;
+}
+
+int mpc52xx_fec_resume(struct of_device *op)
+{
+	struct net_device *ndev = dev_get_drvdata(&op->dev);
+	struct fec_priv *priv = ndev->priv;
+	struct mpc52xx_fec *fec = priv->fec;
+
+	/* XXX ugly hack */
+	/* not deep-sleep (but low-power), so re-init hw */
+	if (*(unsigned long *)CONFIG_KERNEL_START != 0x60000000) {
+		*(unsigned long *)CONFIG_KERNEL_START = 0x60000000; // restore
+		fec_mii_init(ndev);
+		fec_hw_init(ndev);
+	} else
+		fec_mii_resume(ndev);
+
+	/* Restart the DMA tasks */
+	sdma_fec_rx_init(priv->rx_sdma, priv->rx_fifo, FEC_RX_BUFFER_SIZE);
+	sdma_fec_tx_init(priv->tx_sdma, priv->tx_fifo);
+
+	/* Start FEC */
+	out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) | 0x2);
+
+	netif_device_attach(ndev);
+
+	if (priv->sequence_done) {		 /* redo the fec_open() */
+		fec_free_rx_buffers(priv->rx_sdma);
+		fec_open(ndev);
+	}
+
+	return 0;
+}
+#endif
+
 #if defined(CONFIG_PPC_MERGE)
 static struct of_device_id mpc52xx_fec_of_match[] = {
 	{ .compatible = "mpc5200-ethernet", },
@@ -815,8 +871,8 @@ static struct of_platform_driver mpc52xx
 	.probe = mpc52xx_fec_probe,
 	.remove = mpc52xx_fec_remove,
 #ifdef CONFIG_PM
-/*	.suspend = mpc52xx_fec_suspend, TODO */
-/*	.resume = mpc52xx_fec_resume, TODO */
+	.suspend = mpc52xx_fec_suspend,
+	.resume = mpc52xx_fec_resume,
 #endif
 	.driver = {
 		.name = DRIVER_NAME,
drivers/net/fec_mpc52xx/fec_phy.c +17 -0
Index: grant.git/drivers/net/fec_mpc52xx/fec_phy.c
===================================================================
@@ -527,6 +527,23 @@ int fec_mii_wait(struct net_device *dev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+phy_cmd_t phy_cmd_off[] = { { mk_mii_write(MII_BMCR, BMCR_PDOWN), NULL },
+			{ mk_mii_end, } };
+phy_cmd_t phy_cmd_on[] =  { { mk_mii_write(MII_BMCR, 0), NULL },
+			{ mk_mii_end, } };
+
+void fec_mii_suspend(struct net_device *dev)
+{
+	mii_do_cmd(dev, phy_cmd_off);
+}
+
+void fec_mii_resume(struct net_device *dev)
+{
+	mii_do_cmd(dev, phy_cmd_on);
+}
+#endif
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Dale Farnsworth");
 MODULE_DESCRIPTION("PHY driver for Motorola MPC52xx FEC");
drivers/net/fec_mpc52xx/fec_phy.h +5 -0
Index: grant.git/drivers/net/fec_mpc52xx/fec_phy.h
===================================================================
@@ -71,3 +71,8 @@ extern int fec_mii_wait(struct net_devic
 extern void fec_mii(struct net_device *dev);
 
 extern int fec_ioctl(struct net_device *, struct ifreq *rq, int cmd);
+
+#ifdef CONFIG_PM
+extern void fec_mii_suspend(struct net_device *dev);
+extern void fec_mii_resume(struct net_device *dev);
+#endif
#3 lore raw

Re: [PATCH 2/5] mpc52xx suspend: FEC (ethernet)

Quoted 6 lines · Domen Puncer

Suspend and resume for FEC on MPC52xx.

Note that resume is a bit different for lite5200b low-power mode.

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.

drivers/net/fec_mpc52xx/fec.c mpc52xx_fec_remove(struct device *dev) · line 836

Quoted 10 lines
drivers/net/fec_mpc52xx/fec.c +10 -0
+int mpc52xx_fec_resume(struct of_device *op)
+{
+       struct net_device *ndev = dev_get_drvdata(&op->dev);
+       struct fec_priv *priv = ndev->priv;
+       struct mpc52xx_fec *fec = priv->fec;
+
+       /* XXX ugly hack */
+       /* not deep-sleep (but low-power), so re-init hw */
+       if (*(unsigned long *)CONFIG_KERNEL_START != 0x60000000) {
+               *(unsigned long *)CONFIG_KERNEL_START = 0x60000000; // restore

Please avoid c++ style comments; even within ugly hacks. :-)

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#4 lore raw

PATCH v2 3/5 mpc52xx suspend: USB

In reply to Domen Puncer

Trivial suspend and resume OF OHCI.
On MPC52xx turn off and on power to ports.

drivers/usb/host/ohci-ppc-of.c +28 -2
Index: grant.git/drivers/usb/host/ohci-ppc-of.c
===================================================================
@@ -214,6 +214,32 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_
 #endif
 
 
+#ifdef CONFIG_PM
+static u32 descr_a;
+static int ohci_hcd_ppc_soc_drv_suspend(struct of_device *op,
+		pm_message_t state)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+#ifdef CONFIG_PPC_MPC52xx
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+	descr_a = in_be32(&ohci->regs->roothub.a);
+	out_be32(&ohci->regs->roothub.a, (descr_a & ~0x200) | 0x100);
+#endif
+	return 0;
+}
+static int ohci_hcd_ppc_soc_drv_resume(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+#ifdef CONFIG_PPC_MPC52xx
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+	out_be32(&ohci->regs->roothub.a, descr_a);
+#endif
+	return 0;
+}
+#endif
+
 static struct of_platform_driver ohci_hcd_ppc_of_driver = {
 	.name		= "ppc-of-ohci",
 	.match_table	= ohci_hcd_ppc_of_match,
@@ -221,8 +247,8 @@ static struct of_platform_driver ohci_hc
 	.remove		= ohci_hcd_ppc_of_remove,
 	.shutdown 	= ohci_hcd_ppc_of_shutdown,
 #ifdef CONFIG_PM
-	/*.suspend	= ohci_hcd_ppc_soc_drv_suspend,*/
-	/*.resume	= ohci_hcd_ppc_soc_drv_resume,*/
+	.suspend	= ohci_hcd_ppc_soc_drv_suspend,
+	.resume		= ohci_hcd_ppc_soc_drv_resume,
 #endif
 	.driver		= {
 		.name	= "ppc-of-ohci",
#5 lore raw

Re: [PATCH 3/5] mpc52xx suspend: USB

Quoted 5 lines · Domen Puncer

Trivial suspend and resume OF OHCI.
On MPC52xx turn off and on power to ports.

Nak; see below

Quoted 13 lines

Index: grant.git/drivers/usb/host/ohci-ppc-of.c
===================================================================

drivers/usb/host/ohci-ppc-of.c +4 -0
@@ -214,6 +214,32 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_
 #endif
 
 
+#ifdef CONFIG_PM
+static u32 descr_a;
+static int ohci_hcd_ppc_soc_drv_suspend(struct of_device *op,
+               pm_message_t state)

drivers/usb/host/ohci-ppc-of.c MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_ · line 230

Quoted 10 lines
drivers/usb/host/ohci-ppc-of.c +10 -0
+{
+       struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+#ifdef CONFIG_PPC_MPC52xx
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+       descr_a = in_be32(&ohci->regs->roothub.a);
+       out_be32(&ohci->regs->roothub.a, (descr_a & ~0x200) | 0x100);
+#endif
+       return 0;
+}

#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.

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#6 lore raw

Wrong board info for ML403.

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 ([email protected]) (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 <[email protected]>
[    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.

#7 lore raw

Re: Wrong board info for ML403.

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 <[email protected]>
To: [email protected]

You might want to start with XAPP542
http://direct.xilinx.com/bvdocs/appnotes/xapp542.pdf
http://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 <[email protected]>
To: [email protected]

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

Quoted 164 lines · Leonid

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 ([email protected]) (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 <[email protected]>
[    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
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

#8 lore raw

PATCH v2 3/5 mpc52xx suspend: USB

In reply to Grant Likely

Trivial suspend and resume OF OHCI.
On MPC52xx turn off and on power to ports.

---
 drivers/usb/host/ohci-ppc-of.c |   30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)
drivers/usb/host/ohci-ppc-of.c +28 -2
Index: grant.git/drivers/usb/host/ohci-ppc-of.c
===================================================================
@@ -214,6 +214,32 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_
 #endif
 
 
+#ifdef CONFIG_PM
+static u32 descr_a;
+static int ohci_hcd_ppc_soc_drv_suspend(struct of_device *op,
+		pm_message_t state)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+	if (machine_is_compatible("generic-mpc5200")) {
+		struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+		descr_a = in_be32(&ohci->regs->roothub.a);
+		out_be32(&ohci->regs->roothub.a, (descr_a & ~0x200) | 0x100);
+	}
+	return 0;
+}
+static int ohci_hcd_ppc_soc_drv_resume(struct of_device *op)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+	if (machine_is_compatible("generic-mpc5200")) {
+		struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+		out_be32(&ohci->regs->roothub.a, descr_a);
+	}
+	return 0;
+}
+#endif
+
 static struct of_platform_driver ohci_hcd_ppc_of_driver = {
 	.name		= "ppc-of-ohci",
 	.match_table	= ohci_hcd_ppc_of_match,
@@ -221,8 +247,8 @@ static struct of_platform_driver ohci_hc
 	.remove		= ohci_hcd_ppc_of_remove,
 	.shutdown 	= ohci_hcd_ppc_of_shutdown,
 #ifdef CONFIG_PM
-	/*.suspend	= ohci_hcd_ppc_soc_drv_suspend,*/
-	/*.resume	= ohci_hcd_ppc_soc_drv_resume,*/
+	.suspend	= ohci_hcd_ppc_soc_drv_suspend,
+	.resume		= ohci_hcd_ppc_soc_drv_resume,
 #endif
 	.driver		= {
 		.name	= "ppc-of-ohci",
#9 lore raw

Re: [PATCH 3/5 v2] mpc52xx suspend: USB

drivers/usb/host/ohci-ppc-of.c MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_ · line 224

Quoted 5 lines · Domen Puncer
drivers/usb/host/ohci-ppc-of.c +3 -0
+	struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+	if (machine_is_compatible("generic-mpc5200")) {
+		struct ohci_hcd *ohci = hcd_to_ohci(hcd);

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

#10 lore raw

Re: [PATCH 3/5 v2] mpc52xx suspend: USB

Quoted 10 lines · Sylvain Munaut

drivers/usb/host/ohci-ppc-of.c MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_ · line 224

Quoted 5 lines · Domen Puncer
drivers/usb/host/ohci-ppc-of.c +3 -0
+     struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+     if (machine_is_compatible("generic-mpc5200")) {
+             struct ohci_hcd *ohci = hcd_to_ohci(hcd);

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.

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#11 lore raw

PATCH v2 4/5 mpc52xx suspend: deep-sleep

In reply to Domen Puncer

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.

---
 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(+)
arch/powerpc/platforms/52xx/Makefile +2 -0
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -10,3 +10,5 @@ endif
 
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
+
+obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +124 -0

124 lines not on this page · raw message

arch/powerpc/platforms/52xx/mpc52xx_sleep.S new file +277 -0

277 lines not on this page · raw message

#12 lore raw

Re: [PATCH 4/5] mpc52xx suspend: deep-sleep

Quoted 7 lines · Domen Puncer

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.

Some more comments...

Quoted 9 lines

Index: grant.git/arch/powerpc/platforms/52xx/mpc52xx_pm.c
===================================================================

arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +5 -0
+/* 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;

arch/powerpc/platforms/52xx/mpc52xx_pm.c line 36

Quoted 10 lines
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +10 -0
+#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().

Quoted 4 lines
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +4 -0
+static struct pm_ops mpc52xx_pm_ops = {
+       .valid          = mpc52xx_pm_valid,
+       .prepare        = mpc52xx_pm_prepare,
+       .enter          = mpc52xx_pm_enter,

arch/powerpc/platforms/52xx/mpc52xx_pm.c line 124

Quoted 10 lines
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +10 -0
+       .finish         = mpc52xx_pm_finish,
+};
+
+static int __init mpc52xx_pm_init(void)
+{
+       pm_set_ops(&mpc52xx_pm_ops);
+       return 0;
+}
+
+arch_initcall(mpc52xx_pm_init);

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.

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#13 lore raw

Re: [PATCH 4/5] mpc52xx suspend: deep-sleep

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.

---
 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(-)
arch/powerpc/platforms/52xx/Makefile +2 -0
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -10,3 +10,5 @@ endif
 
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
+
+obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +230 -0

230 lines not on this page · raw message

arch/powerpc/platforms/52xx/mpc52xx_sleep.S new file +161 -0

161 lines not on this page · raw message

arch/powerpc/platforms/52xx/efika.c +8 -0
Index: grant.git/arch/powerpc/platforms/52xx/efika.c
===================================================================
@@ -200,6 +200,14 @@ static void __init efika_setup_arch(void
 
 	efika_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);
 }
arch/powerpc/platforms/52xx/lite5200.c +28 -0
Index: grant.git/arch/powerpc/platforms/52xx/lite5200.c
===================================================================
@@ -85,6 +85,24 @@ error:
 	iounmap(gpio);
 }
 
+#ifdef CONFIG_PM
+static u32 descr_a;
+static void lite5200_suspend_prepare(void __iomem *mbar)
+{
+	/*
+	 * power down usb port
+	 * this needs to be called before of-ohci suspend code
+	 */
+	descr_a = in_be32(mbar + 0x1048);
+	out_be32(mbar + 0x1048, (descr_a & ~0x200) | 0x100);
+}
+
+static void lite5200_resume_finish(void __iomem *mbar)
+{
+	out_be32(mbar + 0x1048, descr_a);
+}
+#endif
+
 static void __init lite5200_setup_arch(void)
 {
 	struct device_node *np;
@@ -107,6 +125,16 @@ static void __init lite5200_setup_arch(v
 	mpc52xx_setup_cpu();	/* Generic */
 	lite5200_setup_cpu();	/* Platorm specific */
 
+#ifdef CONFIG_PM
+	mpc52xx_wakeup.mask = WAKEUP_GPIO | WAKEUP_RTC;
+	mpc52xx_wakeup.pin = 1;		/* GPIO_WKUP_1 (GPIO_PSC2_4) */
+	mpc52xx_wakeup.level = 0;	/* wakeup on low level */
+	/* mpc52xx_wakeup.delay = 10;	 wake after 10 minutes (RTC) */
+	mpc52xx_wakeup.board_suspend_prepare = lite5200_suspend_prepare;
+	mpc52xx_wakeup.board_resume_finish = lite5200_resume_finish;
+	mpc52xx_pm_init();
+#endif
+
 #ifdef CONFIG_PCI
 	np = of_find_node_by_type(np, "pci");
 	if (np)
include/asm-powerpc/mpc52xx.h +63 -0

74 lines not on this page · raw message

arch/powerpc/boot/dts/lite5200.dts +1 -0
Index: grant.git/arch/powerpc/boot/dts/lite5200.dts
===================================================================
@@ -49,6 +49,7 @@
 
 	soc5200@f0000000 {
 		model = "fsl,mpc5200";
+		compatible = "mpc5200";
 		revision = ""			// from bootloader
 		#interrupt-cells = <3>;
 		device_type = "soc";
arch/powerpc/boot/dts/lite5200b.dts +1 -0
Index: grant.git/arch/powerpc/boot/dts/lite5200b.dts
===================================================================
@@ -49,6 +49,7 @@
 
 	soc5200@f0000000 {
 		model = "fsl,mpc5200b";
+		compatible = "mpc5200";
 		revision = "";			// from bootloader
 		#interrupt-cells = <3>;
 		device_type = "soc";
arch/powerpc/kernel/prom_init.c +1 -1
Index: grant.git/arch/powerpc/kernel/prom_init.c
===================================================================
@@ -2142,7 +2142,7 @@ static void __init fixup_device_tree_efi
 	                             3,12,0, 3,13,0, 3,14,0, 3,15,0 };
 	struct subst_entry efika_subst_table[] = {
 		{ "/",			"device_type",	prop_cstr("efika") },
-		{ "/builtin",		"compatible",	prop_cstr("soc") },
+		{ "/builtin",		"device_type",	prop_cstr("soc") },
 		{ "/builtin/ata",	"compatible",	prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
 		{ "/builtin/bestcomm",	"compatible",	prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
 		{ "/builtin/bestcomm",	"interrupts",	prop_bcomm_irq, sizeof(prop_bcomm_irq) },
#14 lore raw

Re: [PATCH 4/5] mpc52xx suspend: deep-sleep

Quoted 10 lines · Domen Puncer

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. :-)

Quoted 1 line

This code survived > 70k suspend/resume cycles :-)

That's pretty good evidence. :-)

Quoted 1 line

Comments?

A few more comments below

Quoted 2 lines
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +0 -0

<snip>

arch/powerpc/platforms/52xx/mpc52xx_pm.c line 141

Quoted 4 lines
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +4 -0
+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.

===================================================================

Quoted 15 lines
arch/powerpc/boot/dts/lite5200.dts +1 -0
@@ -49,6 +49,7 @@
 
        soc5200@f0000000 {
                model = "fsl,mpc5200";
+               compatible = "mpc5200";
                revision = ""                   // from bootloader
                #interrupt-cells = <3>;
                device_type = "soc";

Index: grant.git/arch/powerpc/boot/dts/lite5200b.dts
===================================================================

arch/powerpc/boot/dts/lite5200b.dts line 55

Quoted 7 lines
arch/powerpc/boot/dts/lite5200b.dts +1 -0
@@ -49,6 +49,7 @@
 
        soc5200@f0000000 {
                model = "fsl,mpc5200b";
+               compatible = "mpc5200";
                revision = "";                  // from bootloader
                #interrupt-cells = <3>;
                device_type = "soc";

Put these two changes in a seperate patch, and I'll ACK them right away

===================================================================

arch/powerpc/kernel/prom_init.c static void __init fixup_device_tree_efi · line 2148

Quoted 12 lines
arch/powerpc/kernel/prom_init.c +1 -1
@@ -2142,7 +2142,7 @@ static void __init fixup_device_tree_efi
                                     3,12,0, 3,13,0, 3,14,0, 3,15,0 };
        struct subst_entry efika_subst_table[] = {
                { "/",                  "device_type",  prop_cstr("efika") },
-               { "/builtin",           "compatible",   prop_cstr("soc") },
+               { "/builtin",           "device_type",  prop_cstr("soc") },
                { "/builtin/ata",       "compatible",   prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
                { "/builtin/bestcomm",  "compatible",   prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
                { "/builtin/bestcomm",  "interrupts",   prop_bcomm_irq, sizeof(prop_bcomm_irq) },

This should also be a seperate patch.

Cheers,
g.

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#15 lore raw

Re: [PATCH 4/5] mpc52xx suspend: deep-sleep

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.

---
 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(+)
arch/powerpc/platforms/52xx/Makefile +2 -0
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -10,3 +10,5 @@ endif
 
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
+
+obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
arch/powerpc/platforms/52xx/mpc52xx_pm.c new file +187 -0

187 lines not on this page · raw message

arch/powerpc/platforms/52xx/mpc52xx_sleep.S new file +154 -0

154 lines not on this page · raw message

arch/powerpc/platforms/52xx/efika.c +15 -0
Index: grant.git/arch/powerpc/platforms/52xx/efika.c
===================================================================
@@ -185,6 +185,16 @@ static void efika_show_cpuinfo(struct se
 	of_node_put(root);
 }
 
+#ifdef CONFIG_PM
+static void efika_suspend_prepare(void __iomem *mbar)
+{
+	u8 pin = 4;	/* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */
+	u8 level = 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
+
 static void __init efika_setup_arch(void)
 {
 	rtas_initialize();
@@ -200,6 +210,11 @@ static void __init efika_setup_arch(void
 
 	efika_pcisetup();
 
+#ifdef CONFIG_PM
+	mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare;
+	mpc52xx_pm_init();
+#endif
+
 	if (ppc_md.progress)
 		ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0);
 }
arch/powerpc/platforms/52xx/lite5200.c +28 -0
Index: grant.git/arch/powerpc/platforms/52xx/lite5200.c
===================================================================
@@ -85,6 +85,28 @@ error:
 	iounmap(gpio);
 }
 
+#ifdef CONFIG_PM
+static u32 descr_a;
+static void lite5200_suspend_prepare(void __iomem *mbar)
+{
+	u8 pin = 1;	/* GPIO_WKUP_1 (GPIO_PSC2_4) */
+	u8 level = 0;	/* wakeup on low level */
+	mpc52xx_set_wakeup_gpio(pin, level);
+
+	/*
+	 * power down usb port
+	 * this needs to be called before of-ohci suspend code
+	 */
+	descr_a = in_be32(mbar + 0x1048);
+	out_be32(mbar + 0x1048, (descr_a & ~0x200) | 0x100);
+}
+
+static void lite5200_resume_finish(void __iomem *mbar)
+{
+	out_be32(mbar + 0x1048, descr_a);
+}
+#endif
+
 static void __init lite5200_setup_arch(void)
 {
 	struct device_node *np;
@@ -107,6 +129,12 @@ static void __init lite5200_setup_arch(v
 	mpc52xx_setup_cpu();	/* Generic */
 	lite5200_setup_cpu();	/* Platorm specific */
 
+#ifdef CONFIG_PM
+	mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
+	mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
+	mpc52xx_pm_init();
+#endif
+
 #ifdef CONFIG_PCI
 	np = of_find_node_by_type(np, "pci");
 	if (np)
include/asm-powerpc/mpc52xx.h +11 -0
Index: grant.git/include/asm-powerpc/mpc52xx.h
===================================================================
@@ -253,5 +253,16 @@ extern int __init mpc52xx_add_bridge(str
 
 #endif /* __ASSEMBLY__ */
 
+#ifdef CONFIG_PM
+struct mpc52xx_suspend {
+	void (*board_suspend_prepare)(void __iomem *mbar);
+	void (*board_resume_finish)(void __iomem *mbar);
+};
+
+extern struct mpc52xx_suspend mpc52xx_suspend;
+extern int __init mpc52xx_pm_init(void);
+extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
+#endif /* CONFIG_PM */
+
 #endif /* __ASM_POWERPC_MPC52xx_H__ */
 
Acked-by
#16 lore raw

Re: [PATCH 4/5] mpc52xx suspend: deep-sleep

Quoted 10 lines · Domen Puncer

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.

#17 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

In reply to Domen Puncer

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(+)
board/icecube/icecube.c +50 -0
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
+
+void lite5200b_wakeup(void)
+{
+	unsigned char wakeup_pin;
+	void (*linux_wakeup)(void);
+
+	/* check PSC2_4, if it's down "QT" is signaling we have a wakeup
+	 * from low power mode */
+	*(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"
+	 * by holding pin at 1 for 10 uS */
+	*(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_RAMBOOT
 static void sdram_start (int hi_addr)
 {
@@ -208,6 +256,8 @@ long int initdram (int board_type)
 		__asm__ volatile ("sync");
 	}
 
+	lite5200b_wakeup();
+
 	return dramsize + dramsize2;
 }
 
Acked-by on v1 1/1
#18 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

Quoted 3 lines · Domen Puncer

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;

g.

Quoted 72 lines
---
 board/icecube/icecube.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

Index: u-boot.git/board/icecube/icecube.c
===================================================================

board/icecube/icecube.c +50 -0
@@ -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
+
+void lite5200b_wakeup(void)
+{
+       unsigned char wakeup_pin;
+       void (*linux_wakeup)(void);
+
+       /* check PSC2_4, if it's down "QT" is signaling we have a wakeup
+        * from low power mode */
+       *(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"
+        * by holding pin at 1 for 10 uS */
+       *(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_RAMBOOT
 static void sdram_start (int hi_addr)
 {
@@ -208,6 +256,8 @@ long int initdram (int board_type)
                __asm__ volatile ("sync");
        }
 
+       lite5200b_wakeup();
+
        return dramsize + dramsize2;
 }
#19 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

U-Boot part of Lite5200b low power mode support. Puts SDRAM out of self-refresh and transfers control to address saved at physical 0x0.

---

Quoted 12 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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.

Quoted 5 lines

Also, '//' style comments should be changed to '/* */'

Otherwise;

OK. This one should be better:

 Makefile                |    5 ++++
 board/icecube/icecube.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)
board/icecube/icecube.c +49 -0
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
+
+void lite5200b_wakeup(void)
+{
+	unsigned char wakeup_pin;
+	void (*linux_wakeup)(void);
+
+	/* check PSC2_4, if it's down "QT" is signaling we have a wakeup
+	 * from low power mode */
+	*(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"
+	 * by holding pin at 1 for 10 uS */
+	*(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_RAMBOOT
 static void sdram_start (int hi_addr)
 {
@@ -208,6 +255,8 @@ long int initdram (int board_type)
 		__asm__ volatile ("sync");
 	}
 
+	lite5200b_wakeup();
+
 	return dramsize + dramsize2;
 }
 
Makefile +5 -0
Index: u-boot.git/Makefile
===================================================================
@@ -430,6 +430,7 @@ inka4x0_config:	unconfig
 	@$(MKCONFIG) inka4x0 ppc mpc5xxx inka4x0
 
 lite5200b_config	\
+lite5200b_PM_config	\
 lite5200b_LOWBOOT_config:	unconfig
 	@mkdir -p $(obj)include
 	@mkdir -p $(obj)board/icecube
@@ -438,6 +439,10 @@ lite5200b_LOWBOOT_config:	unconfig
 	@ echo "... DDR memory revision"
 	@ echo "#define CONFIG_MPC5200"		>>$(obj)include/config.h
 	@ echo "#define CONFIG_LITE5200B"	>>$(obj)include/config.h
+	@[ -z "$(findstring _PM_,$@)" ] || \
+		{ echo "#define CONFIG_LITE5200B_PM"	>>$(obj)include/config.h ; \
+		  echo "... with power management (low-power mode) support" ; \
+		}
 	@[ -z "$(findstring LOWBOOT_,$@)" ] || \
 		{ echo "TEXT_BASE = 0xFF000000" >$(obj)board/icecube/config.tmp ; \
 		  echo "... with LOWBOOT configuration" ; \
Acked-by
#20 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

Quoted 3 lines · Domen Puncer

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)

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 119 lines

---

Quoted 12 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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.

Quoted 5 lines

Also, '//' style comments should be changed to '/* */'

Otherwise;

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
===================================================================

board/icecube/icecube.c +49 -0
@@ -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
+
+void lite5200b_wakeup(void)
+{
+       unsigned char wakeup_pin;
+       void (*linux_wakeup)(void);
+
+       /* check PSC2_4, if it's down "QT" is signaling we have a wakeup
+        * from low power mode */
+       *(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"
+        * by holding pin at 1 for 10 uS */
+       *(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_RAMBOOT
 static void sdram_start (int hi_addr)
 {
@@ -208,6 +255,8 @@ long int initdram (int board_type)
                __asm__ volatile ("sync");
        }
 
+       lite5200b_wakeup();
+
        return dramsize + dramsize2;
 }
 

Index: u-boot.git/Makefile
===================================================================

Makefile +5 -0
@@ -430,6 +430,7 @@ inka4x0_config:     unconfig
        @$(MKCONFIG) inka4x0 ppc mpc5xxx inka4x0
 
 lite5200b_config       \
+lite5200b_PM_config    \
 lite5200b_LOWBOOT_config:      unconfig
        @mkdir -p $(obj)include
        @mkdir -p $(obj)board/icecube
@@ -438,6 +439,10 @@ lite5200b_LOWBOOT_config:  unconfig
        @ echo "... DDR memory revision"
        @ echo "#define CONFIG_MPC5200"         >>$(obj)include/config.h
        @ echo "#define CONFIG_LITE5200B"       >>$(obj)include/config.h
+       @[ -z "$(findstring _PM_,$@)" ] || \
+               { echo "#define CONFIG_LITE5200B_PM"    >>$(obj)include/config.h ; \
+                 echo "... with power management (low-power mode) support" ; \
+               }
        @[ -z "$(findstring LOWBOOT_,$@)" ] || \
                { echo "TEXT_BASE = 0xFF000000" >$(obj)board/icecube/config.tmp ; \
                  echo "... with LOWBOOT configuration" ; \
Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely at secretlab.ca
(403) 399-0195
#21 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

Quoted 10 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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)

Quoted 4 lines

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.

Thanks!

Domen

#22 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

Quoted 2 lines · In message <[email protected]> you wrote:

I thought Signed-off-by's are Linux specific.

Please read the docs.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office:  Kirchenstr. 5,       D-82194 Groebenzell,            Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Systems programmers are the high priests of a low cult.
                                                       -- R.S. Barton
#23 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

In reply to Grant Likely
Quoted 10 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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)

Quoted 4 lines

Stefan; since there is no 5200 custodian, can you please pick up this patch once Domen sends a Signed-of-by replay?

Done.

But this brings me to a new idea: Why not create a 5200er custodian repository and perhaps we can find somebody (Stefan looks in Grants direction ;-)) to volunteer to maintain this 5200er repository?

Grant?

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
=====================================================================

#24 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

Quoted 11 lines · Stefan Roese
Quoted 10 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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)

Quoted 6 lines
Quoted 4 lines

Stefan; since there is no 5200 custodian, can you please pick up this patch once Domen sends a Signed-of-by replay?

Done.

Thanks!

While at it, can you also take care of (Grant already agreed with the change):

G2 core reference manual says decrementer and time base are decreasing/increasing once every 4 bus clock cycles. Lets fix it, so time in Linux won't run twice as fast

---
 include/configs/IceCube.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/IceCube.h +1 -1
Index: u-boot.git/include/configs/IceCube.h
===================================================================
@@ -182,7 +182,7 @@
 
 #define OF_CPU			"PowerPC,5200 at 0"
 #define OF_SOC			"soc5200 at f0000000"
-#define OF_TBCLK		(bd->bi_busfreq / 8)
+#define OF_TBCLK		(bd->bi_busfreq / 4)
 #define OF_STDOUT_PATH		"/soc5200 at f0000000/serial at 2000"
 
 /*
#25 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

Quoted 25 lines · Domen Puncer
Quoted 11 lines · Stefan Roese
Quoted 10 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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)

Quoted 6 lines
Quoted 4 lines

Stefan; since there is no 5200 custodian, can you please pick up this patch once Domen sends a Signed-of-by replay?

Done.

Thanks!

While at it, can you also take care of (Grant already agreed with the change):

Quoted 5 lines

G2 core reference manual says decrementer and time base are decreasing/increasing once every 4 bus clock cycles. Lets fix it, so time in Linux won't run twice as fast

Quoted 18 lines
---
 include/configs/IceCube.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: u-boot.git/include/configs/IceCube.h
===================================================================

include/configs/IceCube.h +1 -1
@@ -182,7 +182,7 @@
 
 #define OF_CPU                 "PowerPC,5200 at 0"
 #define OF_SOC                 "soc5200 at f0000000"
-#define OF_TBCLK               (bd->bi_busfreq / 8)
+#define OF_TBCLK               (bd->bi_busfreq / 4)
 #define OF_STDOUT_PATH         "/soc5200 at f0000000/serial at 2000"
 
 /*
Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely at secretlab.ca
(403) 399-0195
#26 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

In reply to Domen Puncer

Hi Domen,

Quoted 2 lines · Domen Puncer

While at it, can you also take care of (Grant already agreed with the change):

since we don't have a 52xx repository, I commited it into the u-boot-testing repository:

git://www.denx.de/git/u-boot-testing.git

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
=====================================================================

#27 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

Quoted 5 lines · In message <[email protected]> you wrote:

since we don't have a 52xx repository, I commited it into the u-boot-testing repository:

git://www.denx.de/git/u-boot-testing.git

Merged.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office:  Kirchenstr. 5,       D-82194 Groebenzell,            Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The first thing we do is kill all the lawyers.
(Shakespeare. II Henry VI, Act IV, scene ii)
#28 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

In reply to Stefan Roese

Hi Domen,

Quoted 11 lines · Stefan Roese
Quoted 10 lines · Grant Likely
Quoted 3 lines · Domen Puncer

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)

Quoted 6 lines
Quoted 4 lines

Stefan; since there is no 5200 custodian, can you please pick up this patch once Domen sends a Signed-of-by replay?

Done.

Rafal mentioned to me off-list that some documentation about this suspend/wakeup mechanism would be preferable. Here his notes:

"
- regarding the U-Boot piece I'd only like to see some explanation (as a comment or short readme file) of the overall concept and scenario as it is not intuitive at all and rather difficult to understand all the ramifications and constraints from looking at the code only "

So Domen, could you please either send a reworked patch with this documentation (preferable some file in doc/README.xxx) or just send a new patch with only this documentation?

Thanks.

BTW: Wolfgang reminded me, that putting this stuff into the u-boot-ppc4xx repository is not a good solution. I'll try to move this over to u-boot-testing.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
=====================================================================

#29 lore raw

PATCH 1/1 icecube/lite5200b: wakeup from low-power support

Dear Domen,

Quoted 10 lines · in message <[email protected]> Stefan Roese wrote:

- regarding the U-Boot piece I'd only like to see some explanation (as a comment or short readme file) of the overall concept and scenario as it is not intuitive at all and rather difficult to understand all the ramifications and constraints from looking at the code only "

So Domen, could you please either send a reworked patch with this documentation (preferable some file in doc/README.xxx) or just send a new patch with only this documentation?

The documentation should also include information which configu- rations have been tested, i. e. if PCI, IDE, USB, ... device have been attached to the system during these test cycles, and if these survived.

Best regards,

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk
Office:  Kirchenstr. 5,       D-82194 Groebenzell,            Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Marriage is the sole cause of divorce.
#30 lore raw

PATCH 1/1 icecube/lite5200b: document wakeup from low-power support

Document what Lite5200B low-power is about.

---
 doc/README.Lite5200B_low_power |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
doc/README.Lite5200B_low_power new file +22 -0
Index: u-boot.git/doc/README.Lite5200B_low_power
===================================================================
@@ -0,0 +1,22 @@
+Lite5200B wakeup from low-power mode (CONFIG_LITE5200B_PM)
+----------------------------------------------------------
+
+Low-power mode as described in Lite5200B User's Manual, means that
+with support of MC68HLC908QT1 microcontroller (refered to as QT),
+everything but the SDRAM can be powered down. This brings
+maximum power saving, while one can still restore previous state
+quickly.
+
+Quick overview where U-Boot comes into the picture:
+- OS saves device states
+- OS saves wakeup handler address to physical 0x0, puts SDRAM into
+  self-refresh and signals to QT, it should power down the board
+- / board is sleeping here /
+- someone presses SW4 (connected to QT)
+- U-Boot checks PSC2_4 pin, if QT drives it down, then we woke up,
+  so get SDRAM out of self-refresh and transfer control to OS
+  wakeup handler
+- OS restores device states
+
+This was tested on Linux with USB and Ethernet in use. Adding
+support for other devices is an OS issue.
#31 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

In reply to Domen Puncer
Quoted 4 lines · Domen Puncer

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

#32 lore raw

Re: [PATCH] icecube/lite5200b: wakeup from low-power support

[ Gah, saw it didn't make it to u-boot ML, resending ]

Quoted 7 lines · Rafal Jaworowski
Quoted 4 lines · Domen Puncer

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!

Quoted 5 lines

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.

Quoted 8 lines

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.

Quoted 5 lines

- 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.

Quoted 3 lines

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

#33 lore raw

PATCH v2 5/5 lite5200b suspend: low-power mode

In reply to Domen Puncer

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.

---
 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(+)
arch/powerpc/platforms/52xx/lite5200_pm.c new file +125 -0
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"
+
+extern void lite5200_low_power(void *sram, void *mbar);
+extern int mpc52xx_pm_enter(suspend_state_t);
+extern int mpc52xx_pm_prepare(suspend_state_t);
+
+static void __iomem *mbar;
+
+static int lite5200_pm_valid(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int lite5200_pm_prepare(suspend_state_t state)
+{
+	/* deep sleep? let mpc52xx code handle that */
+	if (state == PM_SUSPEND_STANDBY)
+		return mpc52xx_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;
+	}
+
+	return 0;
+}
+
+/* save and restore registers not bound to any real devices */
+static struct mpc52xx_cdm __iomem *cdm;
+static struct mpc52xx_cdm scdm;
+static struct mpc52xx_intr __iomem *pic;
+static struct mpc52xx_intr spic;
+static struct mpc52xx_sdma __iomem *bes;
+static struct mpc52xx_sdma sbes;
+static struct mpc52xx_xlb __iomem *xlb;
+static struct mpc52xx_xlb sxlb;
+static struct mpc52xx_gpio __iomem *gps;
+static struct mpc52xx_gpio sgps;
+static struct mpc52xx_gpio_wkup __iomem *gpw;
+static struct mpc52xx_gpio_wkup sgpw;
+extern char saved_sram[0x4000];
+
+static void lite5200_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);
+}
+
+static void lite5200_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));
+}
+
+static int lite5200_pm_enter(suspend_state_t state)
+{
+	/* deep sleep? let mpc52xx code handle that */
+	if (state == PM_SUSPEND_STANDBY) {
+		return mpc52xx_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);
+	return 0;
+}
+
+static int lite5200_pm_finish(suspend_state_t state)
+{
+	return 0;
+}
+
+static struct pm_ops lite5200_pm_ops = {
+	.valid		= lite5200_pm_valid,
+	.prepare	= lite5200_pm_prepare,
+	.enter		= lite5200_pm_enter,
+	.finish		= lite5200_pm_finish,
+};
+
+static int __init lite5200_pm_init(void)
+{
+	pm_set_ops(&lite5200_pm_ops);
+	return 0;
+}
+
+arch_initcall(lite5200_pm_init);
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +419 -0

419 lines not on this page · raw message

arch/powerpc/platforms/52xx/Makefile +3 -0
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -12,3 +12,6 @@ obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
 
 obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
+ifeq ($(CONFIG_PPC_LITE5200),y)
+	obj-$(CONFIG_PM)	+= lite5200_sleep.o lite5200_pm.o
+endif
#34 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 5 lines · Domen Puncer

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.

Quoted 15 lines
---
 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
===================================================================

arch/powerpc/platforms/52xx/lite5200_pm.c new file +0 -0
@@ -0,0 +1,125 @@

<snip>

arch/powerpc/platforms/52xx/lite5200_pm.c line 36

Quoted 11 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +11 -0
+static int lite5200_pm_prepare(suspend_state_t state)
+{
+       /* deep sleep? let mpc52xx code handle that */
+       if (state == PM_SUSPEND_STANDBY)
+               return mpc52xx_pm_prepare(state);
+
+       if (state != PM_SUSPEND_MEM)
+               return -EINVAL;
+
+       /* map registers */
+       mbar = ioremap_nocache(0xf0000000, 0x8000);

Magic numbers? Really? This should be retrieved from the device tree. There is always the possibility of mbar getting moved.

arch/powerpc/platforms/52xx/lite5200_pm.c line 67

Quoted 8 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +8 -0
+static void lite5200_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));

Hmmm. I have not dug into this deeply, but blind save/restore to blocks of registers scares me.

Quoted 19 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +19 -0
+
+       memcpy(saved_sram, sdma.sram, sdma.sram_size);
+}
+
+static void lite5200_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));
+}
+
+static int lite5200_pm_enter(suspend_state_t state)
+{
+       /* deep sleep? let mpc52xx code handle that */

arch/powerpc/platforms/52xx/lite5200_pm.c line 96

Quoted 10 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +10 -0
+       if (state == PM_SUSPEND_STANDBY) {
+               return mpc52xx_pm_enter(state);
+       }
+
+       cdm = mbar + 0x200;
+       pic = mbar + 0x500;
+       gps = mbar + 0xb00;
+       gpw = mbar + 0xc00;
+       bes = mbar + 0x1200;
+       xlb = mbar + 0x1f00;

Again, magic numbers

Quoted 21 lines

Index: grant.git/arch/powerpc/platforms/52xx/lite5200_sleep.S
===================================================================

arch/powerpc/platforms/52xx/lite5200_sleep.S new file +16 -0
@@ -0,0 +1,419 @@
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+
+#define SDRAM_MODE     0x100
+#define SDRAM_CTRL     0x104
+#define SC_MODE_EN     (1<<31)
+#define SC_CKE         (1<<30)
+#define SC_REF_EN      (1<<28)
+#define SC_SOFT_PRE    (1<<1)
+
+#define GPIOW_GPIOE    0xc00
+#define GPIOW_ODE      0xc04
+#define GPIOW_DDR      0xc08

arch/powerpc/platforms/52xx/lite5200_sleep.S line 26

Quoted 10 lines
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +10 -0
+#define GPIOW_DVO      0xc0c
+#define GPIOW_INTEN    0xc10
+
+#define CDM_CE         0x214
+#define CDM_SDRAM      (1<<3)
+
+
+// about 2000 cpu cycles for one sdram cycle here
+// just increase, to be on the safe side?
+#define TCK    5000

Please avoid c++ comments

arch/powerpc/platforms/52xx/lite5200_sleep.S line 29

Quoted 3 lines
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +3 -0
+
+
+#define DONT_DEBUG 1

Convention is to #define DEBUG to enable debugging (as opposed to #defining something to disable it)

arch/powerpc/platforms/52xx/lite5200_sleep.S line 347

Quoted 4 lines
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +4 -0
+restore_regs:
+       lis     r4, registers@h
+       ori     r4, r4, registers@l
+#ifdef DONT_DEBUG

should be #if !defined(DEBUG)

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#35 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 13 lines · Grant Likely
Quoted 5 lines · Domen Puncer

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?

...

Quoted 6 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 36

Quoted 2 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +2 -0
+       /* map registers */
+       mbar = ioremap_nocache(0xf0000000, 0x8000);

Magic numbers? Really? This should be retrieved from the device tree. There is always the possibility of mbar getting moved.

...

Quoted 5 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 96

Quoted 3 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +3 -0
+       gpw = mbar + 0xc00;
+       bes = mbar + 0x1200;
+       xlb = mbar + 0x1f00;

Again, magic numbers

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.

Quoted 7 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 67

Quoted 4 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +4 -0
+       _memcpy_fromio(&scdm, cdm, sizeof(*cdm));
+       _memcpy_fromio(&sxlb, xlb, sizeof(*xlb));
+       _memcpy_fromio(&sgps, gps, sizeof(*gps));
+       _memcpy_fromio(&sgpw, gpw, sizeof(*gpw));

Hmmm. I have not dug into this deeply, but blind save/restore to blocks of registers scares me.

Seems to work (tm), I'll look at datasheet.

Quoted 5 lines

arch/powerpc/platforms/52xx/lite5200_sleep.S line 26

Quoted 3 lines
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +3 -0
+// about 2000 cpu cycles for one sdram cycle here
+// just increase, to be on the safe side?
+#define TCK    5000

Please avoid c++ comments

// are in ANSI C99 too, but ok, I know kernel folks don't like them :-)

Quoted 4 lines
Quoted 1 line

+#define DONT_DEBUG 1

Convention is to #define DEBUG to enable debugging (as opposed to #defining something to disable it)

Yeah, makes sense.

Domen

#36 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 14 lines · Domen Puncer
Quoted 1 line · Grant Likely

On 3/15/07, Domen Puncer <[email protected]> wrote:

...

Quoted 6 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 36

Quoted 2 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +2 -0
+       /* map registers */
+       mbar = ioremap_nocache(0xf0000000, 0x8000);

Magic numbers? Really? This should be retrieved from the device tree. There is always the possibility of mbar getting moved.

...

Quoted 4 lines
Quoted 3 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +3 -0
+       gpw = mbar + 0xc00;
+       bes = mbar + 0x1200;
+       xlb = mbar + 0x1f00;
Quoted 6 lines
Quoted 1 line

Again, magic numbers

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

#37 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 17 lines · Domen Puncer
Quoted 16 lines · Domen Puncer
Quoted 1 line · Grant Likely

On 3/15/07, Domen Puncer <[email protected]> wrote:

...

Quoted 6 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 36

Quoted 2 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +2 -0
+       /* map registers */
+       mbar = ioremap_nocache(0xf0000000, 0x8000);

Magic numbers? Really? This should be retrieved from the device tree. There is always the possibility of mbar getting moved.

...

Quoted 5 lines

arch/powerpc/platforms/52xx/lite5200_pm.c line 96

Quoted 3 lines
arch/powerpc/platforms/52xx/lite5200_pm.c new file +3 -0
+       gpw = mbar + 0xc00;
+       bes = mbar + 0x1200;
+       xlb = mbar + 0x1f00;

Again, magic numbers

Quoted 7 lines
Quoted 4 lines

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

#38 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 9 lines · Domen Puncer
Quoted 8 lines · Domen Puncer
Quoted 4 lines · Domen Puncer

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.

Signature · 4 lines
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#39 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

In reply to Grant Likely

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.

---
 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(-)
arch/powerpc/platforms/52xx/lite5200_pm.c new file +210 -0
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 */
+extern void lite5200_low_power(void *sram, void *mbar);
+
+static struct mpc52xx_cdm __iomem *cdm;
+static struct mpc52xx_intr __iomem *pic;
+static struct mpc52xx_sdma __iomem *bes;
+static struct mpc52xx_xlb __iomem *xlb;
+static struct mpc52xx_gpio __iomem *gps;
+static struct mpc52xx_gpio_wkup __iomem *gpw;
+static void __iomem *mbar;
+
+static int lite5200_pm_valid(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int lite5200_pm_prepare(suspend_state_t state)
+{
+	/* deep sleep? let mpc52xx code handle that */
+	if (state == PM_SUSPEND_STANDBY)
+		return mpc52xx_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;
+
+	return 0;
+}
+
+/* save and restore registers not bound to any real devices */
+static struct mpc52xx_cdm scdm;
+static struct mpc52xx_intr spic;
+static struct mpc52xx_sdma sbes;
+static struct mpc52xx_xlb sxlb;
+static struct mpc52xx_gpio sgps;
+static struct mpc52xx_gpio_wkup sgpw;
+
+static void lite5200_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);
+}
+
+static void lite5200_restore_regs(void)
+{
+	int i;
+	memcpy(sdma.sram, saved_sram, sdma.sram_size);
+
+
+	/*
+	 * GPIOs. Interrupt Master Enable has higher address then other
+	 * registers, so just memcpy is ok.
+	 */
+	_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);
+}
+
+static int lite5200_pm_enter(suspend_state_t state)
+{
+	/* deep sleep? let mpc52xx code handle that */
+	if (state == PM_SUSPEND_STANDBY) {
+		return mpc52xx_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);
+	return 0;
+}
+
+static int lite5200_pm_finish(suspend_state_t state)
+{
+	/* deep sleep? let mpc52xx code handle that */
+	if (state == PM_SUSPEND_STANDBY) {
+		return mpc52xx_pm_finish(state);
+	}
+	return 0;
+}
+
+static struct pm_ops lite5200_pm_ops = {
+	.valid		= lite5200_pm_valid,
+	.prepare	= lite5200_pm_prepare,
+	.enter		= lite5200_pm_enter,
+	.finish		= lite5200_pm_finish,
+};
+
+int __init lite5200_pm_init(void)
+{
+	pm_set_ops(&lite5200_pm_ops);
+	return 0;
+}
arch/powerpc/platforms/52xx/lite5200_sleep.S new file +413 -0

413 lines not on this page · raw message

arch/powerpc/platforms/52xx/Makefile +3 -0
Index: grant.git/arch/powerpc/platforms/52xx/Makefile
===================================================================
@@ -12,3 +12,6 @@ obj-$(CONFIG_PPC_EFIKA)		+= efika.o
 obj-$(CONFIG_PPC_LITE5200)	+= lite5200.o
 
 obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc52xx_pm.o
+ifeq ($(CONFIG_PPC_LITE5200),y)
+	obj-$(CONFIG_PM)	+= lite5200_sleep.o lite5200_pm.o
+endif
arch/powerpc/platforms/52xx/lite5200.c +1 -1
Index: grant.git/arch/powerpc/platforms/52xx/lite5200.c
===================================================================
@@ -132,7 +132,7 @@ static void __init lite5200_setup_arch(v
 #ifdef CONFIG_PM
 	mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
 	mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
-	mpc52xx_pm_init();
+ 	lite5200_pm_init();
 #endif
 
 #ifdef CONFIG_PCI
include/asm-powerpc/mpc52xx.h +10 -0
Index: grant.git/include/asm-powerpc/mpc52xx.h
===================================================================
@@ -262,6 +262,16 @@ struct mpc52xx_suspend {
 extern struct mpc52xx_suspend mpc52xx_suspend;
 extern int __init mpc52xx_pm_init(void);
 extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
+
+#ifdef CONFIG_PPC_LITE5200
+extern int __init lite5200_pm_init(void);
+
+/* lite5200 calls mpc5200 suspend functions, so here they are */
+extern int mpc52xx_pm_prepare(suspend_state_t);
+extern int mpc52xx_pm_enter(suspend_state_t);
+extern int mpc52xx_pm_finish(suspend_state_t);
+extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */
+#endif
 #endif /* CONFIG_PM */
 
 #endif /* __ASM_POWERPC_MPC52xx_H__ */
Acked-by
#40 lore raw

Re: [PATCH 5/5] lite5200b suspend: low-power mode

Quoted 11 lines · Domen Puncer

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.