Message ID | 20090827173021.GD739@oksana.dev.rtsoft.ru (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Kumar Gala |
Headers | show |
On Aug 27, 2009, at 12:30 PM, Anton Vorontsov wrote: > This patch adds suspend/resume support for MPC8540-compatible and > MPC8569 CPUs. > > MPC8540-compatible PMCs are trivial: we just write SLP bit into PM > control and status register. > > MPC8569 is a bit trickier, QE turns off during suspend and so on > resume we must reload QE microcode firmware and reset QE. > > So far we don't support Deep Sleep mode as found in newer MPC85xx > CPUs (i.e. MPC8536). It can be relatively easy implemented though, > and for it we reserve 'mem' suspend type. > > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> > --- > arch/powerpc/Kconfig | 2 +- > arch/powerpc/platforms/85xx/Makefile | 1 + > arch/powerpc/platforms/85xx/suspend.c | 115 ++++++++++++++++++++++++ > +++++++++ > 3 files changed, 117 insertions(+), 1 deletions(-) > create mode 100644 arch/powerpc/platforms/85xx/suspend.c How did you test this? I'd also like to get Scott's Ack on this and the device tree patches before accepting them. - k
On Fri, Aug 28, 2009 at 12:38:51AM -0500, Kumar Gala wrote: > > On Aug 27, 2009, at 12:30 PM, Anton Vorontsov wrote: > > >This patch adds suspend/resume support for MPC8540-compatible and > >MPC8569 CPUs. > > > >MPC8540-compatible PMCs are trivial: we just write SLP bit into PM > >control and status register. > > > >MPC8569 is a bit trickier, QE turns off during suspend and so on > >resume we must reload QE microcode firmware and reset QE. > > > >So far we don't support Deep Sleep mode as found in newer MPC85xx > >CPUs (i.e. MPC8536). It can be relatively easy implemented though, > >and for it we reserve 'mem' suspend type. > > > >Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> > >--- > >arch/powerpc/Kconfig | 2 +- > >arch/powerpc/platforms/85xx/Makefile | 1 + > >arch/powerpc/platforms/85xx/suspend.c | 115 > >+++++++++++++++++++++++++++++++++ > >3 files changed, 117 insertions(+), 1 deletions(-) > >create mode 100644 arch/powerpc/platforms/85xx/suspend.c > > How did you test this? --- Prerequisites: 1. Following patches should be applied in addition: rtc: Set wakeup capability for I2C and SPI RTC drivers [5/5] ucc_geth: Implement suspend/resume and Wake-On-LAN support [4/5] ucc_geth: Remove UGETH_MAGIC_PACKET Kconfig symbol and code [3/5] ucc_geth: Factor out MAC initialization steps into a call [2/5] powerpc/qe: Implement qe_alive_during_sleep() helper function [1/5] ucc_geth: Fix NULL pointer dereference in uec_get_ethtool_stats() 2. QE microcode should be placed into /lib/firmware/, i.e. wget http://opensource.freescale.com/firmware/fsl_qe_ucode_8569_10.zip unzip fsl_qe_ucode_8569_10.zip cp fsl_qe_ucode_8569_10.bin /<nfsroot>/lib/firmware/fsl_qe_ucode_8569.bin --- Wakeup on RTC alarm: # cd /sys/class/rtc/rtc0/ # echo $(( `cat since_epoch` + 10 )) > wakealarm # echo standby > /sys/power/state mpc85xx-pmc e00e0080.power: firmware: requesting fsl_qe_ucode_8569.bin PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.02 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. The board is now suspended, CPU asserted ASLEEP signal that is reflected by the ASLEEP LED on the board (the LED is near UEC2 port). 10 seconds later the board will wakeup: qe-firmware: firmware 'MPC8569 QE Microcode Rel_B6900155' for 8569 V1.0 qe-firmware: uploading microcode 'MPC8569 QE Microcode Rel_B69001' version 1.0.0 pci 0000:00:00.0: enabling device (0106 -> 0107) Restarting tasks ... done. PHY: mdio@e0082120:07 - Link is Up - 100/Full --- Wakeup on PHY/link changes (no magic packet support in MPC8569, as QE turns off during sleep): # ethtool -s eth0 wol p # echo standby > /sys/power/state PM: Syncing filesystems ... done. Freezing user space processes ... (elapsed 0.00 seconds) done. Freezing remaining freezable tasks ... (elapsed 0.00 seconds) done. To wakeup, trigger the PHY interrupt (e.g. pull out the ethernet cable from eth0): qe-firmware: firmware 'MPC8569 QE Microcode Rel_B6900155' for 8569 V1.0 qe-firmware: uploading microcode 'MPC8569 QE Microcode Rel_B69001' version 1.0.0 pci 0000:00:00.0: enabling device (0106 -> 0107) Restarting tasks ... done. UCC magic packet detection was tested on MPC8360E-MDS boards (ethtool -s eth0 wol g), I'll send power management support patches for 83xx QE boards soon. Thanks,
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d00131c..46ebfe6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -212,7 +212,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y - depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx + depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || PPC_85xx config PPC_DCR_NATIVE bool diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 835733f..cd1ad6e 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o diff --git a/arch/powerpc/platforms/85xx/suspend.c b/arch/powerpc/platforms/85xx/suspend.c new file mode 100644 index 0000000..d4ca5e2 --- /dev/null +++ b/arch/powerpc/platforms/85xx/suspend.c @@ -0,0 +1,115 @@ +/* + * Suspend/resume support + * + * Copyright © 2009 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/types.h> +#include <linux/suspend.h> +#include <linux/device.h> +#include <linux/of_platform.h> +#include <linux/firmware.h> +#include <asm/qe.h> + +struct pmc_regs { + __be32 pmcsr; +#define PMCSR_SLP (1 << 17) +}; + +struct pmc_data { + unsigned int flags; +#define PMC_NEED_QE_RELOAD (1 << 0) + + const char *fw_name; +}; + +static struct device *pmc_dev; +static struct pmc_regs __iomem *pmc_regs; +static const struct pmc_data *pmc_data; +static struct qe_firmware *pmc_qefw; + +static int pmc_suspend_enter(suspend_state_t state) +{ + out_be32(&pmc_regs->pmcsr, PMCSR_SLP); + + if (pmc_qefw) { + int ret; + + ret = qe_upload_firmware(pmc_qefw); + if (ret) + dev_err(pmc_dev, "could not upload firmware\n"); + + qe_reset(); + } + return 0; +} + +static int pmc_suspend_valid(suspend_state_t state) +{ + if (state != PM_SUSPEND_STANDBY) + return 0; + + if (pmc_data && pmc_data->flags & PMC_NEED_QE_RELOAD && !pmc_qefw) { + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, pmc_data->fw_name, pmc_dev); + if (ret) { + dev_err(pmc_dev, "could not request firmware %s\n", + pmc_data->fw_name); + return 0; + } + + pmc_qefw = (struct qe_firmware *)fw->data; + } + + return 1; +} + +static struct platform_suspend_ops pmc_suspend_ops = { + .valid = pmc_suspend_valid, + .enter = pmc_suspend_enter, +}; + +static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) +{ + pmc_regs = of_iomap(ofdev->node, 0); + if (!pmc_regs) + return -ENOMEM; + + pmc_dev = &ofdev->dev; + pmc_data = id->data; + suspend_set_ops(&pmc_suspend_ops); + return 0; +} + +static struct pmc_data mpc8569_pmc_data = { + .flags = PMC_NEED_QE_RELOAD, + .fw_name = "fsl_qe_ucode_8569.bin", +}; + +static const struct of_device_id pmc_ids[] = { + { .compatible = "fsl,mpc8569-pmc", .data = &mpc8569_pmc_data, }, + { .compatible = "fsl,mpc8548-pmc", }, + { }, +}; + +static struct of_platform_driver pmc_driver = { + .driver.name = "mpc85xx-pmc", + .match_table = pmc_ids, + .probe = pmc_probe, +}; + +static int pmc_init(void) +{ + return of_register_platform_driver(&pmc_driver); +} +device_initcall(pmc_init);
This patch adds suspend/resume support for MPC8540-compatible and MPC8569 CPUs. MPC8540-compatible PMCs are trivial: we just write SLP bit into PM control and status register. MPC8569 is a bit trickier, QE turns off during suspend and so on resume we must reload QE microcode firmware and reset QE. So far we don't support Deep Sleep mode as found in newer MPC85xx CPUs (i.e. MPC8536). It can be relatively easy implemented though, and for it we reserve 'mem' suspend type. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- arch/powerpc/Kconfig | 2 +- arch/powerpc/platforms/85xx/Makefile | 1 + arch/powerpc/platforms/85xx/suspend.c | 115 +++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/platforms/85xx/suspend.c