Re: [PATCH 5/8] omap_hsmmc: RX51: set padconfs to pull down when powering off eMMC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Some comments and a fix to the omap mux code below.

* Adrian Hunter <adrian.hunter@xxxxxxxxx> [100113 03:39]:
> From 060702bca6c60dd0f63f4e82e381ae1b8b112dec Mon Sep 17 00:00:00 2001
> From: Adrian Hunter <adrian.hunter@xxxxxxxxx>
> Date: Tue, 5 Jan 2010 13:46:57 +0200
> Subject: [PATCH] omap_hsmmc: RX51: set padconfs to pull down when powering off eMMC
> 
> It has been discovered that, when eMMC is powered off, current
> will flow from OMAP eMMC data pull-ups to the eMMC voltage supply.
> Configuring pads for off-mode does not help because eMMC is
> powered off independently of off-mode.  Hence the pads are now
> re-configured when eMMC is powered on or off.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
> ---
>  arch/arm/mach-omap2/board-rx51-peripherals.c |   27 +++++++++++++++++++++++++-
>  arch/arm/mach-omap2/hsmmc.c                  |    2 +
>  arch/arm/mach-omap2/hsmmc.h                  |    2 +
>  arch/arm/plat-omap/include/plat/control.h    |    6 +++++
>  arch/arm/plat-omap/include/plat/mmc.h        |    1 +
>  drivers/mmc/host/omap_hsmmc.c                |    8 +++++++
>  6 files changed, 45 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
> index b6318b1..4d9dbb4 100644
> --- a/arch/arm/mach-omap2/board-rx51-peripherals.c
> +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
> @@ -32,6 +32,7 @@
>  #include <plat/gpmc.h>
>  #include <plat/onenand.h>
>  #include <plat/gpmc-smc91x.h>
> +#include <plat/control.h>
>  
>  #include "mux.h"
>  #include "hsmmc.h"
> @@ -225,6 +226,29 @@ static void rx51_mmc_set_pm_constraints(struct device *dev, int on)
>  #define rx51_mmc_set_pm_constraints NULL
>  #endif
>  
> +/*
> + * Current flows to eMMC when eMMC is off and the data lines are pulled up,
> + * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
> + */
> +static void rx51_mmc_2_pad_conf(struct device *dev, int slot, int power_on)
> +{
> +	if (power_on) {
> +		/* Pull up */
> +		omap_ctrl_writew(    0x118, OMAP343X_PADCONF_MMC2_CMD);
> +		omap_ctrl_writel(0x1180118, OMAP343X_PADCONF_MMC2_DAT0);
> +		omap_ctrl_writel(0x1180118, OMAP343X_PADCONF_MMC2_DAT2);
> +		omap_ctrl_writel(0x1180118, OMAP343X_PADCONF_MMC2_DAT4);
> +		omap_ctrl_writel(0x1180118, OMAP343X_PADCONF_MMC2_DAT6);
> +	} else {
> +		/* Pull down */
> +		omap_ctrl_writew(    0x108, OMAP343X_PADCONF_MMC2_CMD);
> +		omap_ctrl_writel(0x1080108, OMAP343X_PADCONF_MMC2_DAT0);
> +		omap_ctrl_writel(0x1080108, OMAP343X_PADCONF_MMC2_DAT2);
> +		omap_ctrl_writel(0x1080108, OMAP343X_PADCONF_MMC2_DAT4);
> +		omap_ctrl_writel(0x1080108, OMAP343X_PADCONF_MMC2_DAT6);
> +	}
> +}
> +
>  static struct omap2_hsmmc_info mmc[] __initdata = {
>  	{
>  		.name		= "external",

We really want to do all the dynamic muxing using the mux code
instead of adding custom code. But as the mux signal names are dropped
during __init, we cannot use omap_mux_init_signal().

So could you please give the attached patch a try? With this patch
you should be able to do the dynamic remuxing like this:

/*
 * Enable input logic and pull all lines up when eMMC is on.
 *
 * REVISIT: Are the defaul values OK for omap off-idle, or is
 * OMAP_PIN_OFF_OUTPUT_LOW also needed to keep the pins down?
 */
static struct omap_board_mux mmc2_on_mux[] = {
	OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
	{ .reg_offset = OMAP_MUX_TERMINATOR },
};

/*
 * Disable input logic and pull all lines down when eMMC is off.
 *
 * REVISIT1: The input logic should not be needed here, just
 * OMAP_PULL_ENA to pull the lines down. If that does not work,
 * use OMAP_PIN_INPUT_PULLUP.
 *
 * REVISIT2: Are the default values OK for omap off-idle, or is
 * OMAP_PIN_OFF_OUTPUT_LOW also needed to keep the pins down?
 */
static struct omap_board_mux mmc2_off_mux[] = {
	OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0),
	{ .reg_offset = OMAP_MUX_TERMINATOR },
};

static void mmc2_remux(struct device *dev, int slot, int power_on)
{
	if (power_on)
		omap_mux_write_array(mmc2_on_mux);
	else
		omap_mux_write_array(mmc2_off_mux);
}

You might want to check what happens in omap off-idle mode in these cases
and see if enabling OMAP_PIN_OFF_INPUT_PULLDOWN makes any difference in
power consumption in off state. That probably does not matter unless the
floating lines cause the eMMC to do something on it's own :)

Note that I've used "remux" instead of "pad_conf" to make it easier to
grep all the code for muxing, so maybe use "remux" instead in your updated
patch too?

> --- a/arch/arm/plat-omap/include/plat/control.h
> +++ b/arch/arm/plat-omap/include/plat/control.h
> @@ -183,6 +183,12 @@
>  #define OMAP343X_PADCONF_ETK_D14	OMAP343X_PADCONF_ETK(16)
>  #define OMAP343X_PADCONF_ETK_D15	OMAP343X_PADCONF_ETK(17)
>  
> +#define OMAP343X_PADCONF_MMC2_CMD	(OMAP2_CONTROL_PADCONFS + 0x12A)
> +#define OMAP343X_PADCONF_MMC2_DAT0	(OMAP2_CONTROL_PADCONFS + 0x12C)
> +#define OMAP343X_PADCONF_MMC2_DAT2	(OMAP2_CONTROL_PADCONFS + 0x130)
> +#define OMAP343X_PADCONF_MMC2_DAT4	(OMAP2_CONTROL_PADCONFS + 0x134)
> +#define OMAP343X_PADCONF_MMC2_DAT6	(OMAP2_CONTROL_PADCONFS + 0x138)
> +
>  /* 34xx GENERAL_WKUP regist offsets */
>  #define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \
>  						0x008 + (i))

No need for these, they are all defined already in mux34xx.h, and
available via mux.h.

Regards,

Tony
>From bafb6a3d19149a4344e9e927f036df5411b9819a Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@xxxxxxxxxxx>
Date: Wed, 13 Jan 2010 10:27:17 -0800
Subject: [PATCH] omap: Add functions for dynamic remuxing of pins

Make the omap_mux_read and write available for board code,
and rename omap_mux_set_board_signals into omap_mux_write_array.

In some cases we want to change the signals dynamically,
mostly for power management.

Note that we cannot use the signal names as they are set
__init to save memory.

Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx>

diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 459ef23..28722a7 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -51,7 +51,7 @@ struct omap_mux_entry {
 static unsigned long mux_phys;
 static void __iomem *mux_base;
 
-static inline u16 omap_mux_read(u16 reg)
+u16 omap_mux_read(u16 reg)
 {
 	if (cpu_is_omap24xx())
 		return __raw_readb(mux_base + reg);
@@ -59,7 +59,7 @@ static inline u16 omap_mux_read(u16 reg)
 		return __raw_readw(mux_base + reg);
 }
 
-static inline void omap_mux_write(u16 val, u16 reg)
+void omap_mux_write(u16 val, u16 reg)
 {
 	if (cpu_is_omap24xx())
 		__raw_writeb(val, mux_base + reg);
@@ -67,6 +67,14 @@ static inline void omap_mux_write(u16 val, u16 reg)
 		__raw_writew(val, mux_base + reg);
 }
 
+void omap_mux_write_array(struct omap_board_mux *board_mux)
+{
+	while (board_mux->reg_offset !=  OMAP_MUX_TERMINATOR) {
+		omap_mux_write(board_mux->value, board_mux->reg_offset);
+		board_mux++;
+	}
+}
+
 #if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_OMAP_MUX)
 
 static struct omap_mux_cfg arch_mux_cfg;
@@ -833,14 +841,6 @@ static void __init omap_mux_set_cmdline_signals(void)
 	kfree(options);
 }
 
-static void __init omap_mux_set_board_signals(struct omap_board_mux *board_mux)
-{
-	while (board_mux->reg_offset !=  OMAP_MUX_TERMINATOR) {
-		omap_mux_write(board_mux->value, board_mux->reg_offset);
-		board_mux++;
-	}
-}
-
 static int __init omap_mux_copy_names(struct omap_mux *src,
 					struct omap_mux *dst)
 {
@@ -999,7 +999,7 @@ int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
 	if (package_balls)
 		omap_mux_package_init_balls(package_balls, superset);
 	omap_mux_set_cmdline_signals();
-	omap_mux_set_board_signals(board_mux);
+	omap_mux_write_array(board_mux);
 #endif
 
 	omap_mux_init_list(superset);
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index d8b4d5a..f8c2e7a 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -147,6 +147,30 @@ u16 omap_mux_get_gpio(int gpio);
 void omap_mux_set_gpio(u16 val, int gpio);
 
 /**
+ * omap_mux_read() - read mux register
+ * @mux_offset:		Offset of the mux register
+ *
+ */
+u16 omap_mux_read(u16 mux_offset);
+
+/**
+ * omap_mux_write() - write mux register
+ * @val:		New mux register value
+ * @mux_offset:		Offset of the mux register
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write(u16 val, u16 mux_offset);
+
+/**
+ * omap_mux_write_array() - write an array of mux registers
+ * @board_mux:		Array of mux registers terminated by MAP_MUX_TERMINATOR
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write_array(struct omap_board_mux *board_mux);
+
+/**
  * omap3_mux_init() - initialize mux system with board specific set
  * @board_mux:		Board specific mux table
  * @flags:		OMAP package type used for the board

[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux