* [PATCH v2 0/5] extra module resets to ensure full-chip idle
@ 2008-12-01 16:22 Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
2008-12-01 16:36 ` [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
0 siblings, 2 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
Various bootloaders have been known to leave modules in a state
which prevents full-chip retention. This series forces
MMC, IVA2 and D2D/modem into known reset/idle states so that
the OMAP3 can hit full-chip idle.
Tested on OMAP3 Beagle, and custom OMAP3 hardware.
NOTE: this is similar to the set I posted for the PM branch
but this series is rebased onto linux-omap and includes
the MMC reset.
Kevin Hilman (5):
OMAP3: PM: HSMMC: force MMC module reset on boot
OMAP3: PM: Force IVA2 into idle during bootup
OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init
OMAP3: PM: D2D clockdomain supports SW supervised transitions
OMAP3: PM: Ensure modem is reset during PRCM init
arch/arm/mach-omap2/clock34xx.h | 37 ++++++++++++-
arch/arm/mach-omap2/clockdomains.h | 2 +-
arch/arm/mach-omap2/cm-regbits-34xx.h | 14 +++++
arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++
arch/arm/mach-omap2/pm34xx.c | 65 ++++++++++++++++++++++-
arch/arm/plat-omap/include/mach/control.h | 5 ++
6 files changed, 204 insertions(+), 4 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot
2008-12-01 16:22 [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
@ 2008-12-01 16:22 ` Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
` (2 more replies)
2008-12-01 16:36 ` [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
1 sibling, 3 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
The bootloader may leave the MMC in a state which prevents hitting
retention. Even when MMC is not compiled in, each MMC module needs to
be forced into reset.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 241e418..423647e 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -358,6 +359,89 @@ static inline void omap_init_sha1_md5(void) { }
/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_ARCH_OMAP3
+
+#define MMCHS_SYSCONFIG 0x0010
+#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
+#define MMCHS_SYSSTATUS 0x0014
+#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
+
+static struct platform_device dummy_pdev = {
+ .dev = {
+ .bus = &platform_bus_type,
+ },
+};
+
+/**
+ * omap_hsmmc_reset() - Full reset of each HS-MMC controller
+ *
+ * Ensure that each MMC controller is fully reset. Controllers
+ * left in an unknown state (by bootloader) may prevent retention
+ * or OFF-mode. This is especially important in cases where the
+ * MMC driver is not enabled, _or_ built as a module.
+ *
+ * In order for reset to work, interface, functional and debounce
+ * clocks must be enabled. The debounce clock comes from func_32k_clk
+ * and is not under SW control, so we only enable i- and f-clocks.
+ **/
+static void __init omap_hsmmc_reset(void)
+{
+ u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
+ OMAP24XX_NR_MMC;
+
+ for (i = 0; i < nr_controllers; i++) {
+ u32 v, base = 0;
+ struct clk *iclk, *fclk;
+ struct device *dev = &dummy_pdev.dev;
+
+ switch (i) {
+ case 0:
+ base = OMAP2_MMC1_BASE;
+ break;
+ case 1:
+ base = OMAP2_MMC2_BASE;
+ break;
+ case 2:
+ base = OMAP3_MMC3_BASE;
+ break;
+ }
+
+ dummy_pdev.id = i;
+ iclk = clk_get(dev, "mmchs_ick");
+ if (iclk && clk_enable(iclk))
+ iclk = NULL;
+
+ fclk = clk_get(dev, "mmchs_fck");
+ if (fclk && clk_enable(fclk))
+ fclk = NULL;
+
+ if (!iclk || !fclk) {
+ printk(KERN_WARNING
+ "%s: Unable to enable clocks for MMC%d, "
+ "cannot reset.\n", __func__, i);
+ break;
+ }
+
+ omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
+ v = omap_readl(base + MMCHS_SYSSTATUS);
+ while (!(omap_readl(base + MMCHS_SYSSTATUS) &
+ MMCHS_SYSSTATUS_RESETDONE))
+ cpu_relax();
+
+ if (fclk) {
+ clk_disable(fclk);
+ clk_put(fclk);
+ }
+ if (iclk) {
+ clk_disable(iclk);
+ clk_put(iclk);
+ }
+ }
+}
+#else
+static inline void omap_hsmmc_reset(void) {}
+#endif
+
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
@@ -477,6 +561,7 @@ static int __init omap2_init_devices(void)
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
+ omap_hsmmc_reset();
omap_init_camera();
omap_init_mbox();
omap_init_mcspi();
--
1.6.0.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
@ 2008-12-01 16:22 ` Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Kevin Hilman
2008-12-06 6:23 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Paul Walmsley
2008-12-06 0:27 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Tony Lindgren
2008-12-06 6:28 ` Paul Walmsley
2 siblings, 2 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm34xx.c | 55 +++++++++++++++++++++++++++++
arch/arm/plat-omap/include/mach/control.h | 5 +++
2 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index bd74183..6ff6449 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -29,6 +29,7 @@
#include <mach/pm.h>
#include <mach/clockdomain.h>
#include <mach/powerdomain.h>
+#include <mach/control.h>
#include "cm.h"
#include "cm-regbits-34xx.h"
@@ -363,6 +364,58 @@ static struct platform_suspend_ops omap_pm_ops = {
.valid = suspend_valid_only_mem,
};
+
+/**
+ * omap3_iva_idle(): ensure IVA is in idle so it can be put into
+ * retention
+ *
+ * In cases where IVA2 is activated by bootcode, it may prevent
+ * full-chip retention or off-mode because it is not idle. This
+ * function forces the IVA2 into idle state so it can go
+ * into retention/off and thus allow full-chip retention/off.
+ *
+ **/
+static void __init omap3_iva_idle(void)
+{
+ struct clk *iva2_ck;
+
+ iva2_ck = clk_get(NULL, "iva2_fclk");
+ if (!iva2_ck) {
+ pr_err("Unable to get IVA2 fclk: cannot force idle.\n");
+ return;
+ }
+
+ /* Disable IVA2 clock */
+ clk_disable(iva2_ck);
+
+ /* Reset IVA2 */
+ prm_write_mod_reg(OMAP3430_RST1_IVA2 |
+ OMAP3430_RST2_IVA2 |
+ OMAP3430_RST3_IVA2,
+ OMAP3430_IVA2_MOD, RM_RSTCTRL);
+
+ /* Enable IVA2 clock */
+ clk_enable(iva2_ck);
+
+ /* Set IVA2 boot mode to 'idle' */
+ omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
+ OMAP343X_CONTROL_IVA2_BOOTMOD);
+
+ /* Un-reset IVA2 */
+ prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
+
+ /* Disable IVA2 clocks */
+ clk_disable(iva2_ck);
+
+ /* Reset IVA2 */
+ prm_write_mod_reg(OMAP3430_RST1_IVA2 |
+ OMAP3430_RST2_IVA2 |
+ OMAP3430_RST3_IVA2,
+ OMAP3430_IVA2_MOD, RM_RSTCTRL);
+
+ clk_put(iva2_ck);
+}
+
static void __init prcm_setup_regs(void)
{
/* XXX Reset all wkdeps. This should be done when initializing
@@ -514,6 +567,8 @@ static void __init prcm_setup_regs(void)
* it is selected to mpu wakeup goup */
prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
+
+ omap3_iva_idle();
}
static int __init pwrdms_setup(struct powerdomain *pwrdm)
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
index ee3c39e..b51f7fd 100644
--- a/arch/arm/plat-omap/include/mach/control.h
+++ b/arch/arm/plat-omap/include/mach/control.h
@@ -208,6 +208,11 @@
#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
#define OMAP2_PBIASLITEVMODE0 (1 << 0)
+/* CONTROL_IVA2_BOOTMOD bits */
+#define OMAP3_IVA2_BOOTMOD_SHIFT 0
+#define OMAP3_IVA2_BOOTMOD_MASK (0xf << 0)
+#define OMAP3_IVA2_BOOTMOD_IDLE (0x1 << 0)
+
#ifndef __ASSEMBLY__
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
extern void __iomem *omap_ctrl_base_get(void);
--
1.6.0.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
@ 2008-12-01 16:22 ` Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Kevin Hilman
2008-12-06 6:37 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Paul Walmsley
2008-12-06 6:23 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Paul Walmsley
1 sibling, 2 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
Add D2D clocks (modem_fck, sad2d_ick, mad2d_ick) to clock framework,
and also ensure that auto-idle bits are set for these clocks during
PRCM init.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/clock34xx.h | 37 +++++++++++++++++++++++++++++++-
arch/arm/mach-omap2/cm-regbits-34xx.h | 14 ++++++++++++
arch/arm/mach-omap2/pm34xx.c | 4 ++-
3 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 0b95fcb..78504ce 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -1330,6 +1330,38 @@ static struct clk d2d_26m_fck = {
.recalc = &followparent_recalc,
};
+static struct clk modem_fck = {
+ .name = "modem_fck",
+ .parent = &sys_ck,
+ .prcm_mod = CORE_MOD,
+ .enable_reg = CM_FCLKEN1,
+ .enable_bit = OMAP3430_EN_MODEM_SHIFT,
+ .flags = CLOCK_IN_OMAP343X,
+ .clkdm = { .name = "d2d_clkdm" },
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sad2d_ick = {
+ .name = "sad2d_ick",
+ .parent = &sys_ck,
+ .prcm_mod = CORE_MOD,
+ .enable_reg = CM_ICLKEN1,
+ .enable_bit = OMAP3430_EN_SAD2D_SHIFT,
+ .flags = CLOCK_IN_OMAP343X,
+ .clkdm = { .name = "d2d_clkdm" },
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mad2d_ick = {
+ .name = "mad2d_ick",
+ .parent = &sys_ck,
+ .prcm_mod = CORE_MOD,
+ .enable_reg = CM_ICLKEN3,
+ .enable_bit = OMAP3430_EN_MAD2D_SHIFT,
+ .flags = CLOCK_IN_OMAP343X,
+ .clkdm = { .name = "d2d_clkdm" },
+ .recalc = &followparent_recalc,
+};
static const struct clksel omap343x_gpt_clksel[] = {
{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
{ .parent = &sys_ck, .rates = gpt_sys_rates },
@@ -2241,8 +2273,6 @@ static struct clk usb_l4_ick = {
.recalc = &omap2_clksel_recalc,
};
-/* XXX MDM_INTC_ICK, SAD2D_ICK ?? */
-
/* SECURITY_L4_ICK2 based clocks */
static struct clk security_l4_ick2 = {
@@ -3460,6 +3490,9 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&sgx_fck,
&sgx_ick,
&d2d_26m_fck,
+ &modem_fck,
+ &sad2d_ick,
+ &mad2d_ick,
&gpt10_fck,
&gpt11_fck,
&cpefuse_fck,
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 6f3f5a3..6923deb 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -145,6 +145,8 @@
#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0)
/* CM_FCLKEN1_CORE specific bits */
+#define OMAP3430_EN_MODEM (1 << 31)
+#define OMAP3430_EN_MODEM_SHIFT 31
/* CM_ICLKEN1_CORE specific bits */
#define OMAP3430_EN_ICR (1 << 29)
@@ -161,6 +163,8 @@
#define OMAP3430_EN_MAILBOXES_SHIFT 7
#define OMAP3430_EN_OMAPCTRL (1 << 6)
#define OMAP3430_EN_OMAPCTRL_SHIFT 6
+#define OMAP3430_EN_SAD2D (1 << 3)
+#define OMAP3430_EN_SAD2D_SHIFT 3
#define OMAP3430_EN_SDRC (1 << 1)
#define OMAP3430_EN_SDRC_SHIFT 1
@@ -176,6 +180,10 @@
#define OMAP3430_EN_DES1 (1 << 0)
#define OMAP3430_EN_DES1_SHIFT 0
+/* CM_ICLKEN3_CORE */
+#define OMAP3430_EN_MAD2D_SHIFT 3
+#define OMAP3430_EN_MAD2D (1 << 3)
+
/* CM_FCLKEN3_CORE specific bits */
#define OMAP3430ES2_EN_TS_SHIFT 1
#define OMAP3430ES2_EN_TS_MASK (1 << 1)
@@ -231,6 +239,8 @@
#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0)
/* CM_AUTOIDLE1_CORE */
+#define OMAP3430_AUTO_MODEM (1 << 31)
+#define OMAP3430_AUTO_MODEM_SHIFT 31
#define OMAP3430ES2_AUTO_MMC3 (1 << 30)
#define OMAP3430ES2_AUTO_MMC3_SHIFT 30
#define OMAP3430ES2_AUTO_ICR (1 << 29)
@@ -287,6 +297,8 @@
#define OMAP3430_AUTO_HSOTGUSB_SHIFT 4
#define OMAP3430ES1_AUTO_D2D (1 << 3)
#define OMAP3430ES1_AUTO_D2D_SHIFT 3
+#define OMAP3430_AUTO_SAD2D (1 << 3)
+#define OMAP3430_AUTO_SAD2D_SHIFT 3
#define OMAP3430_AUTO_SSI (1 << 0)
#define OMAP3430_AUTO_SSI_SHIFT 0
@@ -308,6 +320,8 @@
#define OMAP3430ES2_AUTO_USBTLL (1 << 2)
#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2
#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2)
+#define OMAP3430_AUTO_MAD2D_SHIFT 3
+#define OMAP3430_AUTO_MAD2D (1 << 3)
/* CM_CLKSEL_CORE */
#define OMAP3430_CLKSEL_SSI_SHIFT 8
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 6ff6449..9a1933b 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -437,6 +437,7 @@ static void __init prcm_setup_regs(void)
* Note that in the long run this should be done by clockfw
*/
cm_write_mod_reg(
+ OMAP3430_AUTO_MODEM |
OMAP3430ES2_AUTO_MMC3 |
OMAP3430ES2_AUTO_ICR |
OMAP3430_AUTO_AES2 |
@@ -464,7 +465,7 @@ static void __init prcm_setup_regs(void)
OMAP3430_AUTO_OMAPCTRL |
OMAP3430ES1_AUTO_FSHOSTUSB |
OMAP3430_AUTO_HSOTGUSB |
- OMAP3430ES1_AUTO_D2D | /* This is es1 only */
+ OMAP3430_AUTO_SAD2D |
OMAP3430_AUTO_SSI,
CORE_MOD, CM_AUTOIDLE1);
@@ -478,6 +479,7 @@ static void __init prcm_setup_regs(void)
if (omap_rev() > OMAP3430_REV_ES1_0) {
cm_write_mod_reg(
+ OMAP3430_AUTO_MAD2D |
OMAP3430ES2_AUTO_USBTLL,
CORE_MOD, CM_AUTOIDLE3);
}
--
1.6.0.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions
2008-12-01 16:22 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Kevin Hilman
@ 2008-12-01 16:22 ` Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 5/5] OMAP3: PM: Ensure modem is reset during PRCM init Kevin Hilman
2008-12-06 6:38 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Paul Walmsley
2008-12-06 6:37 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Paul Walmsley
1 sibling, 2 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/clockdomains.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
index bafa650..49a5774 100644
--- a/arch/arm/mach-omap2/clockdomains.h
+++ b/arch/arm/mach-omap2/clockdomains.h
@@ -198,7 +198,7 @@ static struct clockdomain sgx_clkdm = {
static struct clockdomain d2d_clkdm = {
.name = "d2d_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
--
1.6.0.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 5/5] OMAP3: PM: Ensure modem is reset during PRCM init
2008-12-01 16:22 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Kevin Hilman
@ 2008-12-01 16:22 ` Kevin Hilman
2008-12-06 6:38 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:22 UTC (permalink / raw)
To: linux-omap; +Cc: Kevin Hilman
Rogue bootloaders may enable the modem and thus keep the
D2D power- and clock-domains from going into retention.
Reset modem on boot to be sure it is in known state.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm34xx.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9a1933b..db3a34d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -418,6 +418,12 @@ static void __init omap3_iva_idle(void)
static void __init prcm_setup_regs(void)
{
+ /* reset modem */
+ prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON |
+ OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST,
+ CORE_MOD, RM_RSTCTRL);
+ prm_write_mod_reg(0, CORE_MOD, RM_RSTCTRL);
+
/* XXX Reset all wkdeps. This should be done when initializing
* powerdomains */
prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
--
1.6.0.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/5] extra module resets to ensure full-chip idle
2008-12-01 16:22 [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
@ 2008-12-01 16:36 ` Kevin Hilman
1 sibling, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2008-12-01 16:36 UTC (permalink / raw)
To: linux-omap
Kevin Hilman <khilman@deeprootsystems.com> writes:
> Various bootloaders have been known to leave modules in a state
> which prevents full-chip retention. This series forces
> MMC, IVA2 and D2D/modem into known reset/idle states so that
> the OMAP3 can hit full-chip idle.
>
> Tested on OMAP3 Beagle, and custom OMAP3 hardware.
>
> NOTE: this is similar to the set I posted for the PM branch
> but this series is rebased onto linux-omap and includes
> the MMC reset.
I forgot (again) to mention that this series applies on top of today's
HEAD plus the "OMAP2/3 clock: fix DPLL rate calculation" patch posted
by Paul Walmsley earlier today.
Kevin
> Kevin Hilman (5):
> OMAP3: PM: HSMMC: force MMC module reset on boot
> OMAP3: PM: Force IVA2 into idle during bootup
> OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init
> OMAP3: PM: D2D clockdomain supports SW supervised transitions
> OMAP3: PM: Ensure modem is reset during PRCM init
>
> arch/arm/mach-omap2/clock34xx.h | 37 ++++++++++++-
> arch/arm/mach-omap2/clockdomains.h | 2 +-
> arch/arm/mach-omap2/cm-regbits-34xx.h | 14 +++++
> arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++
> arch/arm/mach-omap2/pm34xx.c | 65 ++++++++++++++++++++++-
> arch/arm/plat-omap/include/mach/control.h | 5 ++
> 6 files changed, 204 insertions(+), 4 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
@ 2008-12-06 0:27 ` Tony Lindgren
2008-12-06 6:28 ` Paul Walmsley
2 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-06 0:27 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap
* Kevin Hilman <khilman@deeprootsystems.com> [081201 08:23]:
> The bootloader may leave the MMC in a state which prevents hitting
> retention. Even when MMC is not compiled in, each MMC module needs to
> be forced into reset.
Pushing to l-o tree, and adding omap mmc queue for mainline.
Tony
>
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 85 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
> index 241e418..423647e 100644
> --- a/arch/arm/mach-omap2/devices.c
> +++ b/arch/arm/mach-omap2/devices.c
> @@ -14,6 +14,7 @@
> #include <linux/init.h>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/clk.h>
>
> #include <mach/hardware.h>
> #include <asm/mach-types.h>
> @@ -358,6 +359,89 @@ static inline void omap_init_sha1_md5(void) { }
>
> /*-------------------------------------------------------------------------*/
>
> +#ifdef CONFIG_ARCH_OMAP3
> +
> +#define MMCHS_SYSCONFIG 0x0010
> +#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
> +#define MMCHS_SYSSTATUS 0x0014
> +#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
> +
> +static struct platform_device dummy_pdev = {
> + .dev = {
> + .bus = &platform_bus_type,
> + },
> +};
> +
> +/**
> + * omap_hsmmc_reset() - Full reset of each HS-MMC controller
> + *
> + * Ensure that each MMC controller is fully reset. Controllers
> + * left in an unknown state (by bootloader) may prevent retention
> + * or OFF-mode. This is especially important in cases where the
> + * MMC driver is not enabled, _or_ built as a module.
> + *
> + * In order for reset to work, interface, functional and debounce
> + * clocks must be enabled. The debounce clock comes from func_32k_clk
> + * and is not under SW control, so we only enable i- and f-clocks.
> + **/
> +static void __init omap_hsmmc_reset(void)
> +{
> + u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
> + OMAP24XX_NR_MMC;
> +
> + for (i = 0; i < nr_controllers; i++) {
> + u32 v, base = 0;
> + struct clk *iclk, *fclk;
> + struct device *dev = &dummy_pdev.dev;
> +
> + switch (i) {
> + case 0:
> + base = OMAP2_MMC1_BASE;
> + break;
> + case 1:
> + base = OMAP2_MMC2_BASE;
> + break;
> + case 2:
> + base = OMAP3_MMC3_BASE;
> + break;
> + }
> +
> + dummy_pdev.id = i;
> + iclk = clk_get(dev, "mmchs_ick");
> + if (iclk && clk_enable(iclk))
> + iclk = NULL;
> +
> + fclk = clk_get(dev, "mmchs_fck");
> + if (fclk && clk_enable(fclk))
> + fclk = NULL;
> +
> + if (!iclk || !fclk) {
> + printk(KERN_WARNING
> + "%s: Unable to enable clocks for MMC%d, "
> + "cannot reset.\n", __func__, i);
> + break;
> + }
> +
> + omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
> + v = omap_readl(base + MMCHS_SYSSTATUS);
> + while (!(omap_readl(base + MMCHS_SYSSTATUS) &
> + MMCHS_SYSSTATUS_RESETDONE))
> + cpu_relax();
> +
> + if (fclk) {
> + clk_disable(fclk);
> + clk_put(fclk);
> + }
> + if (iclk) {
> + clk_disable(iclk);
> + clk_put(iclk);
> + }
> + }
> +}
> +#else
> +static inline void omap_hsmmc_reset(void) {}
> +#endif
> +
> #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
> defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
>
> @@ -477,6 +561,7 @@ static int __init omap2_init_devices(void)
> /* please keep these calls, and their implementations above,
> * in alphabetical order so they're easier to sort through.
> */
> + omap_hsmmc_reset();
> omap_init_camera();
> omap_init_mbox();
> omap_init_mcspi();
> --
> 1.6.0.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Kevin Hilman
@ 2008-12-06 6:23 ` Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2008-12-06 6:23 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap
Hi Kevin,
one quick comment.
On Mon, 1 Dec 2008, Kevin Hilman wrote:
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> arch/arm/mach-omap2/pm34xx.c | 55 +++++++++++++++++++++++++++++
> arch/arm/plat-omap/include/mach/control.h | 5 +++
> 2 files changed, 60 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index bd74183..6ff6449 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -29,6 +29,7 @@
> #include <mach/pm.h>
> #include <mach/clockdomain.h>
> #include <mach/powerdomain.h>
> +#include <mach/control.h>
>
> #include "cm.h"
> #include "cm-regbits-34xx.h"
> @@ -363,6 +364,58 @@ static struct platform_suspend_ops omap_pm_ops = {
> .valid = suspend_valid_only_mem,
> };
>
> +
> +/**
> + * omap3_iva_idle(): ensure IVA is in idle so it can be put into
> + * retention
> + *
> + * In cases where IVA2 is activated by bootcode, it may prevent
> + * full-chip retention or off-mode because it is not idle. This
> + * function forces the IVA2 into idle state so it can go
> + * into retention/off and thus allow full-chip retention/off.
> + *
> + **/
> +static void __init omap3_iva_idle(void)
> +{
> + struct clk *iva2_ck;
> +
> + iva2_ck = clk_get(NULL, "iva2_fclk");
This should be "iva2_fck", right?
> + if (!iva2_ck) {
> + pr_err("Unable to get IVA2 fclk: cannot force idle.\n");
> + return;
> + }
> +
> + /* Disable IVA2 clock */
> + clk_disable(iva2_ck);
> +
> + /* Reset IVA2 */
> + prm_write_mod_reg(OMAP3430_RST1_IVA2 |
> + OMAP3430_RST2_IVA2 |
> + OMAP3430_RST3_IVA2,
> + OMAP3430_IVA2_MOD, RM_RSTCTRL);
> +
> + /* Enable IVA2 clock */
> + clk_enable(iva2_ck);
> +
> + /* Set IVA2 boot mode to 'idle' */
> + omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
> + OMAP343X_CONTROL_IVA2_BOOTMOD);
> +
> + /* Un-reset IVA2 */
> + prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
> +
> + /* Disable IVA2 clocks */
> + clk_disable(iva2_ck);
> +
> + /* Reset IVA2 */
> + prm_write_mod_reg(OMAP3430_RST1_IVA2 |
> + OMAP3430_RST2_IVA2 |
> + OMAP3430_RST3_IVA2,
> + OMAP3430_IVA2_MOD, RM_RSTCTRL);
> +
> + clk_put(iva2_ck);
> +}
> +
> static void __init prcm_setup_regs(void)
> {
> /* XXX Reset all wkdeps. This should be done when initializing
> @@ -514,6 +567,8 @@ static void __init prcm_setup_regs(void)
> * it is selected to mpu wakeup goup */
> prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
> OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
> +
> + omap3_iva_idle();
> }
>
> static int __init pwrdms_setup(struct powerdomain *pwrdm)
> diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
> index ee3c39e..b51f7fd 100644
> --- a/arch/arm/plat-omap/include/mach/control.h
> +++ b/arch/arm/plat-omap/include/mach/control.h
> @@ -208,6 +208,11 @@
> #define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
> #define OMAP2_PBIASLITEVMODE0 (1 << 0)
>
> +/* CONTROL_IVA2_BOOTMOD bits */
> +#define OMAP3_IVA2_BOOTMOD_SHIFT 0
> +#define OMAP3_IVA2_BOOTMOD_MASK (0xf << 0)
> +#define OMAP3_IVA2_BOOTMOD_IDLE (0x1 << 0)
> +
> #ifndef __ASSEMBLY__
> #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
> extern void __iomem *omap_ctrl_base_get(void);
> --
> 1.6.0.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
2008-12-06 0:27 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Tony Lindgren
@ 2008-12-06 6:28 ` Paul Walmsley
2 siblings, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2008-12-06 6:28 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap
Hi Kevin,
another quick comment ...
On Mon, 1 Dec 2008, Kevin Hilman wrote:
> The bootloader may leave the MMC in a state which prevents hitting
> retention. Even when MMC is not compiled in, each MMC module needs to
> be forced into reset.
>
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> arch/arm/mach-omap2/devices.c | 85 +++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 85 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
> index 241e418..423647e 100644
> --- a/arch/arm/mach-omap2/devices.c
> +++ b/arch/arm/mach-omap2/devices.c
> @@ -14,6 +14,7 @@
> #include <linux/init.h>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/clk.h>
>
> #include <mach/hardware.h>
> #include <asm/mach-types.h>
> @@ -358,6 +359,89 @@ static inline void omap_init_sha1_md5(void) { }
>
> /*-------------------------------------------------------------------------*/
>
> +#ifdef CONFIG_ARCH_OMAP3
> +
> +#define MMCHS_SYSCONFIG 0x0010
> +#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
> +#define MMCHS_SYSSTATUS 0x0014
> +#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
> +
> +static struct platform_device dummy_pdev = {
> + .dev = {
> + .bus = &platform_bus_type,
> + },
> +};
> +
> +/**
> + * omap_hsmmc_reset() - Full reset of each HS-MMC controller
> + *
> + * Ensure that each MMC controller is fully reset. Controllers
> + * left in an unknown state (by bootloader) may prevent retention
> + * or OFF-mode. This is especially important in cases where the
> + * MMC driver is not enabled, _or_ built as a module.
> + *
> + * In order for reset to work, interface, functional and debounce
> + * clocks must be enabled. The debounce clock comes from func_32k_clk
> + * and is not under SW control, so we only enable i- and f-clocks.
> + **/
> +static void __init omap_hsmmc_reset(void)
> +{
> + u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
> + OMAP24XX_NR_MMC;
> +
> + for (i = 0; i < nr_controllers; i++) {
> + u32 v, base = 0;
> + struct clk *iclk, *fclk;
> + struct device *dev = &dummy_pdev.dev;
> +
> + switch (i) {
> + case 0:
> + base = OMAP2_MMC1_BASE;
> + break;
> + case 1:
> + base = OMAP2_MMC2_BASE;
> + break;
> + case 2:
> + base = OMAP3_MMC3_BASE;
> + break;
> + }
> +
> + dummy_pdev.id = i;
> + iclk = clk_get(dev, "mmchs_ick");
> + if (iclk && clk_enable(iclk))
> + iclk = NULL;
> +
> + fclk = clk_get(dev, "mmchs_fck");
> + if (fclk && clk_enable(fclk))
> + fclk = NULL;
> +
> + if (!iclk || !fclk) {
> + printk(KERN_WARNING
> + "%s: Unable to enable clocks for MMC%d, "
> + "cannot reset.\n", __func__, i);
> + break;
> + }
> +
> + omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
> + v = omap_readl(base + MMCHS_SYSSTATUS);
> + while (!(omap_readl(base + MMCHS_SYSSTATUS) &
> + MMCHS_SYSSTATUS_RESETDONE))
> + cpu_relax();
I think Tony is trying to banish omap_{read,write}*(); so these should
probably be __raw_{read,write}l() with IO_ADDRESS() or maybe ioremap().
> +
> + if (fclk) {
> + clk_disable(fclk);
> + clk_put(fclk);
> + }
> + if (iclk) {
> + clk_disable(iclk);
> + clk_put(iclk);
> + }
> + }
> +}
> +#else
> +static inline void omap_hsmmc_reset(void) {}
> +#endif
> +
> #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
> defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
>
> @@ -477,6 +561,7 @@ static int __init omap2_init_devices(void)
> /* please keep these calls, and their implementations above,
> * in alphabetical order so they're easier to sort through.
> */
> + omap_hsmmc_reset();
> omap_init_camera();
> omap_init_mbox();
> omap_init_mcspi();
> --
> 1.6.0.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init
2008-12-01 16:22 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Kevin Hilman
@ 2008-12-06 6:37 ` Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2008-12-06 6:37 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap
On Mon, 1 Dec 2008, Kevin Hilman wrote:
> Add D2D clocks (modem_fck, sad2d_ick, mad2d_ick) to clock framework,
> and also ensure that auto-idle bits are set for these clocks during
> PRCM init.
>
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Acked-by: Paul Walmsley <paul@pwsan.com>
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions
2008-12-01 16:22 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 5/5] OMAP3: PM: Ensure modem is reset during PRCM init Kevin Hilman
@ 2008-12-06 6:38 ` Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2008-12-06 6:38 UTC (permalink / raw)
To: Kevin Hilman; +Cc: linux-omap
On Mon, 1 Dec 2008, Kevin Hilman wrote:
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> arch/arm/mach-omap2/clockdomains.h | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
> index bafa650..49a5774 100644
> --- a/arch/arm/mach-omap2/clockdomains.h
> +++ b/arch/arm/mach-omap2/clockdomains.h
> @@ -198,7 +198,7 @@ static struct clockdomain sgx_clkdm = {
> static struct clockdomain d2d_clkdm = {
> .name = "d2d_clkdm",
> .pwrdm = { .name = "core_pwrdm" },
> - .flags = CLKDM_CAN_HWSUP,
> + .flags = CLKDM_CAN_HWSUP_SWSUP,
> .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
> .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
> };
Acked-by: Paul Walmsley <paul@pwsan.com>
might be nice to have a short commit msg.
- Paul
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-12-06 6:38 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-01 16:22 [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Kevin Hilman
2008-12-01 16:22 ` [PATCH v2 5/5] OMAP3: PM: Ensure modem is reset during PRCM init Kevin Hilman
2008-12-06 6:38 ` [PATCH v2 4/5] OMAP3: PM: D2D clockdomain supports SW supervised transitions Paul Walmsley
2008-12-06 6:37 ` [PATCH v2 3/5] OMAP3: PM: Add D2D clocks and auto-idle setup to PRCM init Paul Walmsley
2008-12-06 6:23 ` [PATCH v2 2/5] OMAP3: PM: Force IVA2 into idle during bootup Paul Walmsley
2008-12-06 0:27 ` [PATCH v2 1/5] OMAP3: PM: HSMMC: force MMC module reset on boot Tony Lindgren
2008-12-06 6:28 ` Paul Walmsley
2008-12-01 16:36 ` [PATCH v2 0/5] extra module resets to ensure full-chip idle Kevin Hilman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox