summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2014-01-27 13:44:56 +0800
committerYe.Li <B37916@freescale.com>2014-01-27 18:22:49 +0800
commit01f4ee9ab134a100c733eafdb84ffa233634b26a (patch)
treea7f2e17b2846ccef4bc193de58eb111b57ecb9da
parent86817422ce90ea2106ba9cce7c8ce1624ea286a0 (diff)
downloadu-boot-imx-01f4ee9ab134a100c733eafdb84ffa233634b26a.zip
u-boot-imx-01f4ee9ab134a100c733eafdb84ffa233634b26a.tar.gz
u-boot-imx-01f4ee9ab134a100c733eafdb84ffa233634b26a.tar.bz2
ENGR00293946 ARM:imx6 Add dynamical USDHC/ESDHC pads settings
Add a interface "board_mmc_io_switch" for ESDHC/USDHC to switch its pads settings. The BSP which supports this feature must implement this function. Add it for all imx6 series boards. Signed-off-by: Ye.Li <B37916@freescale.com> (cherry picked from commit 58e999dae8ac0156804ff77c10a7c5ca27d43b50)
-rw-r--r--board/freescale/mx6q_arm2/mx6q_arm2.c66
-rw-r--r--board/freescale/mx6q_hdmidongle/mx6q_hdmidongle.c65
-rw-r--r--board/freescale/mx6q_sabreauto/mx6q_sabreauto.c65
-rw-r--r--board/freescale/mx6q_sabrelite/mx6q_sabrelite.c57
-rw-r--r--board/freescale/mx6q_sabresd/mx6q_sabresd.c65
-rw-r--r--board/freescale/mx6sl_arm2/mx6sl_arm2.c61
-rw-r--r--board/freescale/mx6sl_evk/mx6sl_evk.c61
-rw-r--r--drivers/mmc/imx_esdhc.c15
8 files changed, 448 insertions, 7 deletions
diff --git a/board/freescale/mx6q_arm2/mx6q_arm2.c b/board/freescale/mx6q_arm2/mx6q_arm2.c
index d6d7257..f65572c 100644
--- a/board/freescale/mx6q_arm2/mx6q_arm2.c
+++ b/board/freescale/mx6q_arm2/mx6q_arm2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -734,6 +734,19 @@ iomux_v3_cfg_t usdhc4_pads[] = {
MX6DL_PAD_SD4_DAT7__USDHC4_DAT7,
};
#endif
+
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -770,6 +783,57 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ case 3:
+ count = sizeof(usdhc4_pads) / sizeof(usdhc4_pads[0]);
+ usdhc_switch_pad(usdhc4_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6q_hdmidongle/mx6q_hdmidongle.c b/board/freescale/mx6q_hdmidongle/mx6q_hdmidongle.c
index 6677ad4..f587d71 100644
--- a/board/freescale/mx6q_hdmidongle/mx6q_hdmidongle.c
+++ b/board/freescale/mx6q_hdmidongle/mx6q_hdmidongle.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -982,6 +982,18 @@ iomux_v3_cfg_t usdhc4_pads[] = {
};
#endif
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -1022,6 +1034,57 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ case 3:
+ count = sizeof(usdhc4_pads) / sizeof(usdhc4_pads[0]);
+ usdhc_switch_pad(usdhc4_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6q_sabreauto/mx6q_sabreauto.c b/board/freescale/mx6q_sabreauto/mx6q_sabreauto.c
index 00ef2ed..91be2a2 100644
--- a/board/freescale/mx6q_sabreauto/mx6q_sabreauto.c
+++ b/board/freescale/mx6q_sabreauto/mx6q_sabreauto.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -814,6 +814,18 @@ iomux_v3_cfg_t usdhc4_pads[] = {
};
#endif
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -850,6 +862,57 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ case 3:
+ count = sizeof(usdhc4_pads) / sizeof(usdhc4_pads[0]);
+ usdhc_switch_pad(usdhc4_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6q_sabrelite/mx6q_sabrelite.c b/board/freescale/mx6q_sabrelite/mx6q_sabrelite.c
index 1b0679d..879934c 100644
--- a/board/freescale/mx6q_sabrelite/mx6q_sabrelite.c
+++ b/board/freescale/mx6q_sabrelite/mx6q_sabrelite.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -354,6 +354,18 @@ iomux_v3_cfg_t mx6q_usdhc4_pads[] = {
MX6Q_PAD_SD4_DAT3__USDHC4_DAT3,
};
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -387,6 +399,49 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(mx6q_usdhc3_pads) / sizeof(mx6q_usdhc3_pads[0]);
+ usdhc_switch_pad(mx6q_usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(mx6q_usdhc4_pads) / sizeof(mx6q_usdhc4_pads[0]);
+ usdhc_switch_pad(mx6q_usdhc4_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6q_sabresd/mx6q_sabresd.c b/board/freescale/mx6q_sabresd/mx6q_sabresd.c
index 6f866aa..b1daa07 100644
--- a/board/freescale/mx6q_sabresd/mx6q_sabresd.c
+++ b/board/freescale/mx6q_sabresd/mx6q_sabresd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -1030,6 +1030,18 @@ iomux_v3_cfg_t usdhc4_pads[] = {
};
#endif
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -1070,6 +1082,57 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ case 3:
+ count = sizeof(usdhc4_pads) / sizeof(usdhc4_pads[0]);
+ usdhc_switch_pad(usdhc4_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6sl_arm2/mx6sl_arm2.c b/board/freescale/mx6sl_arm2/mx6sl_arm2.c
index 0e4027e..4bc9c14 100644
--- a/board/freescale/mx6sl_arm2/mx6sl_arm2.c
+++ b/board/freescale/mx6sl_arm2/mx6sl_arm2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -197,6 +197,18 @@ iomux_v3_cfg_t usdhc3_pads[] = {
MX6SL_PAD_SD3_DAT3__USDHC3_DAT3,
};
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -229,6 +241,53 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/board/freescale/mx6sl_evk/mx6sl_evk.c b/board/freescale/mx6sl_evk/mx6sl_evk.c
index 8af6b75..9d1d40a 100644
--- a/board/freescale/mx6sl_evk/mx6sl_evk.c
+++ b/board/freescale/mx6sl_evk/mx6sl_evk.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -191,6 +191,18 @@ iomux_v3_cfg_t usdhc3_pads[] = {
MX6SL_PAD_SD3_DAT3__USDHC3_DAT3,
};
+#define USDHC_PAD_CTRL_DEFAULT (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
int usdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
@@ -222,6 +234,53 @@ int usdhc_gpio_init(bd_t *bis)
return status;
}
+static void usdhc_switch_pad(iomux_v3_cfg_t *pad_list, unsigned count,
+ iomux_v3_cfg_t *new_pad_list, iomux_v3_cfg_t pad_val)
+{
+ u32 i;
+
+ for (i = 0; i < count; i++) {
+ new_pad_list[i] = pad_list[i] & (~MUX_PAD_CTRL_MASK);
+ new_pad_list[i] |= MUX_PAD_CTRL(pad_val);
+ }
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+{
+ iomux_v3_cfg_t new_pads[14];
+ u32 count;
+ iomux_v3_cfg_t pad_ctrl = USDHC_PAD_CTRL_DEFAULT;
+
+ if (clock >= 200000000)
+ pad_ctrl = USDHC_PAD_CTRL_200MHZ;
+ else if (clock == 100000000)
+ pad_ctrl = USDHC_PAD_CTRL_100MHZ;
+
+ switch (index) {
+ case 0:
+ count = sizeof(usdhc1_pads) / sizeof(usdhc1_pads[0]);
+ usdhc_switch_pad(usdhc1_pads, count, new_pads, pad_ctrl);
+ break;
+ case 1:
+ count = sizeof(usdhc2_pads) / sizeof(usdhc2_pads[0]);
+ usdhc_switch_pad(usdhc2_pads, count, new_pads, pad_ctrl);
+ break;
+ case 2:
+ count = sizeof(usdhc3_pads) / sizeof(usdhc3_pads[0]);
+ usdhc_switch_pad(usdhc3_pads, count, new_pads, pad_ctrl);
+ break;
+ default:
+ printf("Warning: you configured more USDHC controllers"
+ "(%d) then supported by the board (%d)\n",
+ index+1, CONFIG_SYS_FSL_USDHC_NUM);
+ return -1;
+ }
+
+ mxc_iomux_v3_setup_multiple_pads(new_pads, count);
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
if (!usdhc_gpio_init(bis))
diff --git a/drivers/mmc/imx_esdhc.c b/drivers/mmc/imx_esdhc.c
index fe1fb2f..a1c4d9b 100644
--- a/drivers/mmc/imx_esdhc.c
+++ b/drivers/mmc/imx_esdhc.c
@@ -537,12 +537,27 @@ static void esdhc_dll_setup(struct mmc *mmc)
}
}
+/*
+ * CPU and board-specific Ethernet initializations. Aliased function
+ * signals caller to move on
+ */
+static int __def_mmc_io_switch(u32 index, u32 clock)
+{
+ return -1;
+}
+
+int board_mmc_io_switch(u32 index, u32 clock)
+ __attribute__((weak, alias("__def_mmc_io_switch")));
+
static void esdhc_set_ios(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
u32 tmp;
+ /* Set the io pad*/
+ board_mmc_io_switch(mmc->block_dev.dev, mmc->clock);
+
/* Set the clock speed */
set_sysctl(mmc, mmc->clock);