Commit d95ecbd6 authored by Ryan QIAN's avatar Ryan QIAN Committed by Jason Liu

ENGR00213944-02: mmc: sdhci: [MX6] support SD v3.0 memory cards.

- Add variable pad speed setting per SD clk freq.
- Add SD3.0 support on SD1, SD2, and SD3.
- Enhance drive strength on SD pad to improve its compatibility.
- change the definition of pad speed changing interface
- combine pad speed setting for different SD host controllers into one function.
Signed-off-by: default avatarRyan QIAN <b32804@freescale.com>
Acked-by: Lily Zhang
parent a4c1285d
......@@ -176,111 +176,84 @@ enum sd_pad_mode {
SD_PAD_MODE_HIGH_SPEED,
};
static int plt_sd3_pad_change(int clock)
static int plt_sd_pad_change(unsigned int index, int clock)
{
/* LOW speed is the default state of SD pads */
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
iomux_v3_cfg_t *sd3_pads_200mhz = NULL;
iomux_v3_cfg_t *sd3_pads_100mhz = NULL;
iomux_v3_cfg_t *sd3_pads_50mhz = NULL;
iomux_v3_cfg_t *sd_pads_200mhz;
iomux_v3_cfg_t *sd_pads_100mhz;
iomux_v3_cfg_t *sd_pads_50mhz;
u32 sd3_pads_200mhz_cnt;
u32 sd3_pads_100mhz_cnt;
u32 sd3_pads_50mhz_cnt;
u32 sd_pads_200mhz_cnt;
u32 sd_pads_100mhz_cnt;
u32 sd_pads_50mhz_cnt;
if (cpu_is_mx6q()) {
sd3_pads_200mhz = mx6q_sd3_200mhz;
sd3_pads_100mhz = mx6q_sd3_100mhz;
sd3_pads_50mhz = mx6q_sd3_50mhz;
sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
} else if (cpu_is_mx6dl()) {
sd3_pads_200mhz = mx6dl_sd3_200mhz;
sd3_pads_100mhz = mx6dl_sd3_100mhz;
sd3_pads_50mhz = mx6dl_sd3_50mhz;
sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
}
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
BUG_ON(!sd3_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_200mhz,
sd3_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
BUG_ON(!sd3_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_100mhz,
sd3_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
BUG_ON(!sd3_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_50mhz,
sd3_pads_50mhz_cnt);
}
}
static int plt_sd4_pad_change(int clock)
{
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
iomux_v3_cfg_t *sd4_pads_200mhz = NULL;
iomux_v3_cfg_t *sd4_pads_100mhz = NULL;
iomux_v3_cfg_t *sd4_pads_50mhz = NULL;
switch (index) {
case 2:
if (cpu_is_mx6q()) {
sd_pads_200mhz = mx6q_sd3_200mhz;
sd_pads_100mhz = mx6q_sd3_100mhz;
sd_pads_50mhz = mx6q_sd3_50mhz;
u32 sd4_pads_200mhz_cnt;
u32 sd4_pads_100mhz_cnt;
u32 sd4_pads_50mhz_cnt;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
} else if (cpu_is_mx6dl()) {
sd_pads_200mhz = mx6dl_sd3_200mhz;
sd_pads_100mhz = mx6dl_sd3_100mhz;
sd_pads_50mhz = mx6dl_sd3_50mhz;
if (cpu_is_mx6q()) {
sd4_pads_200mhz = mx6q_sd4_200mhz;
sd4_pads_100mhz = mx6q_sd4_100mhz;
sd4_pads_50mhz = mx6q_sd4_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
}
break;
case 3:
if (cpu_is_mx6q()) {
sd_pads_200mhz = mx6q_sd4_200mhz;
sd_pads_100mhz = mx6q_sd4_100mhz;
sd_pads_50mhz = mx6q_sd4_50mhz;
sd4_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
sd4_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
sd4_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
} else if (cpu_is_mx6dl()) {
sd4_pads_200mhz = mx6dl_sd4_200mhz;
sd4_pads_100mhz = mx6dl_sd4_100mhz;
sd4_pads_50mhz = mx6dl_sd4_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
} else if (cpu_is_mx6dl()) {
sd_pads_200mhz = mx6dl_sd4_200mhz;
sd_pads_100mhz = mx6dl_sd4_100mhz;
sd_pads_50mhz = mx6dl_sd4_50mhz;
sd4_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd4_200mhz);
sd4_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd4_100mhz);
sd4_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd4_50mhz);
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd4_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd4_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd4_50mhz);
}
break;
default:
printk(KERN_ERR "no such SD host controller index %d\n", index);
return -EINVAL;
}
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
BUG_ON(!sd_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd4_pads_200mhz,
sd4_pads_200mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
sd_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
BUG_ON(!sd_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd4_pads_100mhz,
sd4_pads_100mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
sd_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
BUG_ON(!sd_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd4_pads_50mhz,
sd4_pads_50mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
sd_pads_50mhz_cnt);
}
}
......@@ -291,7 +264,7 @@ static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
.support_8bit = 1,
.keep_power_at_suspend = 1,
.delay_line = 0,
.platform_pad_change = plt_sd3_pad_change,
.platform_pad_change = plt_sd_pad_change,
};
/* No card detect signal for SD4 on ARM2 board*/
......@@ -299,7 +272,7 @@ static const struct esdhc_platform_data mx6_arm2_sd4_data __initconst = {
.always_present = 1,
.support_8bit = 1,
.keep_power_at_suspend = 1,
.platform_pad_change = plt_sd4_pad_change,
.platform_pad_change = plt_sd_pad_change,
};
static int __init gpmi_nand_platform_init(void)
......
......@@ -208,57 +208,63 @@ static void __init imx6q_add_android_device_buttons(void)
static void __init imx6q_add_android_device_buttons(void) {}
#endif
static int plt_sd3_pad_change(int clock)
static int plt_sd_pad_change(unsigned int index, int clock)
{
/* LOW speed is the default state of SD pads */
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
iomux_v3_cfg_t *sd3_pads_200mhz = NULL;
iomux_v3_cfg_t *sd3_pads_100mhz = NULL;
iomux_v3_cfg_t *sd3_pads_50mhz = NULL;
iomux_v3_cfg_t *sd_pads_200mhz;
iomux_v3_cfg_t *sd_pads_100mhz;
iomux_v3_cfg_t *sd_pads_50mhz;
u32 sd3_pads_200mhz_cnt;
u32 sd3_pads_100mhz_cnt;
u32 sd3_pads_50mhz_cnt;
u32 sd_pads_200mhz_cnt;
u32 sd_pads_100mhz_cnt;
u32 sd_pads_50mhz_cnt;
if (index != 2) {
printk(KERN_ERR"no such SD host controller index %d\n", index);
return -EINVAL;
}
if (cpu_is_mx6q()) {
sd3_pads_200mhz = mx6q_sd3_200mhz;
sd3_pads_100mhz = mx6q_sd3_100mhz;
sd3_pads_50mhz = mx6q_sd3_50mhz;
sd_pads_200mhz = mx6q_sd3_200mhz;
sd_pads_100mhz = mx6q_sd3_100mhz;
sd_pads_50mhz = mx6q_sd3_50mhz;
sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
} else if (cpu_is_mx6dl()) {
sd3_pads_200mhz = mx6dl_sd3_200mhz;
sd3_pads_100mhz = mx6dl_sd3_100mhz;
sd3_pads_50mhz = mx6dl_sd3_50mhz;
sd_pads_200mhz = mx6dl_sd3_200mhz;
sd_pads_100mhz = mx6dl_sd3_100mhz;
sd_pads_50mhz = mx6dl_sd3_50mhz;
sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
}
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
BUG_ON(!sd3_pads_200mhz);
BUG_ON(!sd_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_200mhz,
sd3_pads_200mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
sd_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
BUG_ON(!sd3_pads_100mhz);
BUG_ON(!sd_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_100mhz,
sd3_pads_100mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
sd_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
BUG_ON(!sd3_pads_50mhz);
BUG_ON(!sd_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd3_pads_50mhz,
sd3_pads_50mhz_cnt);
return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
sd_pads_50mhz_cnt);
}
}
......@@ -269,7 +275,7 @@ static const struct esdhc_platform_data mx6q_sabreauto_sd3_data __initconst = {
.support_18v = 1,
.support_8bit = 1,
.delay_line = 0,
.platform_pad_change = plt_sd3_pad_change,
.platform_pad_change = plt_sd_pad_change,
};
static const struct esdhc_platform_data mx6q_sabreauto_sd1_data __initconst = {
......
......@@ -349,59 +349,64 @@ enum sd_pad_mode {
SD_PAD_MODE_HIGH_SPEED,
};
static int plt_sd3_pad_change(int clock)
static int plt_sd_pad_change(unsigned int index, int clock)
{
/* LOW speed is the default state of SD pads */
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_200mhz,
ARRAY_SIZE(mx6q_sd3_200mhz));
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_100mhz,
ARRAY_SIZE(mx6q_sd3_100mhz));
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_50mhz,
ARRAY_SIZE(mx6q_sd3_50mhz));
iomux_v3_cfg_t *sd_pads_200mhz;
iomux_v3_cfg_t *sd_pads_100mhz;
iomux_v3_cfg_t *sd_pads_50mhz;
u32 sd_pads_200mhz_cnt;
u32 sd_pads_100mhz_cnt;
u32 sd_pads_50mhz_cnt;
switch (index) {
case 2:
sd_pads_200mhz = mx6q_sd3_200mhz;
sd_pads_100mhz = mx6q_sd3_100mhz;
sd_pads_50mhz = mx6q_sd3_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
break;
case 3:
sd_pads_200mhz = mx6q_sd4_200mhz;
sd_pads_100mhz = mx6q_sd4_100mhz;
sd_pads_50mhz = mx6q_sd4_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
break;
default:
printk(KERN_ERR "no such SD host controller index %d\n", index);
return -EINVAL;
}
}
static int plt_sd4_pad_change(int clock)
{
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
BUG_ON(!sd_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_200mhz,
ARRAY_SIZE(mx6q_sd4_200mhz));
return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
sd_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
BUG_ON(!sd_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_100mhz,
ARRAY_SIZE(mx6q_sd4_100mhz));
return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
sd_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
BUG_ON(!sd_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_50mhz,
ARRAY_SIZE(mx6q_sd4_50mhz));
return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
sd_pads_50mhz_cnt);
}
}
......@@ -409,14 +414,14 @@ static const struct esdhc_platform_data mx6q_sabrelite_sd3_data __initconst = {
.cd_gpio = MX6Q_SABRELITE_SD3_CD,
.wp_gpio = MX6Q_SABRELITE_SD3_WP,
.keep_power_at_suspend = 1,
.platform_pad_change = plt_sd3_pad_change,
.platform_pad_change = plt_sd_pad_change,
};
static const struct esdhc_platform_data mx6q_sabrelite_sd4_data __initconst = {
.cd_gpio = MX6Q_SABRELITE_SD4_CD,
.wp_gpio = MX6Q_SABRELITE_SD4_WP,
.keep_power_at_suspend = 1,
.platform_pad_change = plt_sd4_pad_change,
.platform_pad_change = plt_sd_pad_change,
};
static const struct anatop_thermal_platform_data
......
......@@ -133,12 +133,91 @@ static int max17135_regulator_init(struct max17135 *max17135);
struct clk *extern_audio_root;
extern int __init mx6sl_arm2_init_pfuze100(u32 int_gpio);
enum sd_pad_mode {
SD_PAD_MODE_LOW_SPEED,
SD_PAD_MODE_MED_SPEED,
SD_PAD_MODE_HIGH_SPEED,
};
static int plt_sd_pad_change(unsigned int index, int clock)
{
/* LOW speed is the default state of SD pads */
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
iomux_v3_cfg_t *sd_pads_200mhz;
iomux_v3_cfg_t *sd_pads_100mhz;
iomux_v3_cfg_t *sd_pads_50mhz;
u32 sd_pads_200mhz_cnt;
u32 sd_pads_100mhz_cnt;
u32 sd_pads_50mhz_cnt;
switch (index) {
case 0:
sd_pads_200mhz = mx6sl_sd1_200mhz;
sd_pads_100mhz = mx6sl_sd1_100mhz;
sd_pads_50mhz = mx6sl_sd1_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz);
break;
case 1:
sd_pads_200mhz = mx6sl_sd2_200mhz;
sd_pads_100mhz = mx6sl_sd2_100mhz;
sd_pads_50mhz = mx6sl_sd2_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz);
break;
case 2:
sd_pads_200mhz = mx6sl_sd3_200mhz;
sd_pads_100mhz = mx6sl_sd3_100mhz;
sd_pads_50mhz = mx6sl_sd3_50mhz;
sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz);
sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz);
sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz);
break;
default:
printk(KERN_ERR "no such SD host controller index %d\n", index);
return -EINVAL;
}
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
BUG_ON(!sd_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
sd_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
BUG_ON(!sd_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
sd_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
BUG_ON(!sd_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
sd_pads_50mhz_cnt);
}
}
static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = {
.cd_gpio = MX6_ARM2_SD1_CD,
.wp_gpio = MX6_ARM2_SD1_WP,
.support_8bit = 1,
.support_18v = 1,
.keep_power_at_suspend = 1,
.delay_line = 0,
.platform_pad_change = plt_sd_pad_change,
};
static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = {
......@@ -146,12 +225,17 @@ static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = {
.wp_gpio = MX6_ARM2_SD2_WP,
.keep_power_at_suspend = 1,
.delay_line = 0,
.support_18v = 1,
.platform_pad_change = plt_sd_pad_change,
};
static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
.cd_gpio = MX6_ARM2_SD3_CD,
.wp_gpio = -1,
.keep_power_at_suspend = 1,
.delay_line = 0,
.support_18v = 1,
.platform_pad_change = plt_sd_pad_change,
};
#define mV_to_uV(mV) (mV * 1000)
......
......@@ -50,36 +50,36 @@ static iomux_v3_cfg_t mx6sl_arm2_pads[] = {
MX6SL_PAD_HSIC_DAT__USB_H_DATA,
/* SD1 */
MX6SL_PAD_SD1_CLK__USDHC1_CLK,
MX6SL_PAD_SD1_CMD__USDHC1_CMD,
MX6SL_PAD_SD1_DAT0__USDHC1_DAT0,
MX6SL_PAD_SD1_DAT1__USDHC1_DAT1,
MX6SL_PAD_SD1_DAT2__USDHC1_DAT2,
MX6SL_PAD_SD1_DAT3__USDHC1_DAT3,
MX6SL_PAD_SD1_DAT4__USDHC1_DAT4,
MX6SL_PAD_SD1_DAT5__USDHC1_DAT5,
MX6SL_PAD_SD1_DAT6__USDHC1_DAT6,
MX6SL_PAD_SD1_DAT7__USDHC1_DAT7,
MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ,
MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ,
MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ,
MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ,
MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ,
MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ,
MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ,
MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ,
MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ,
MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ,
/* SD1 CD & WP */
MX6SL_PAD_KEY_ROW7__GPIO_4_7,
MX6SL_PAD_KEY_COL7__GPIO_4_6,
/* SD2 */
MX6SL_PAD_SD2_CLK__USDHC2_CLK,
MX6SL_PAD_SD2_CMD__USDHC2_CMD,
MX6SL_PAD_SD2_DAT0__USDHC2_DAT0,
MX6SL_PAD_SD2_DAT1__USDHC2_DAT1,
MX6SL_PAD_SD2_DAT2__USDHC2_DAT2,
MX6SL_PAD_SD2_DAT3__USDHC2_DAT3,
MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ,
MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ,
MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ,
MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ,
MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ,
MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ,
/* SD2 CD & WP */
MX6SL_PAD_SD2_DAT7__GPIO_5_0,
MX6SL_PAD_SD2_DAT6__GPIO_4_29,
/* SD3 */
MX6SL_PAD_SD3_CLK__USDHC3_CLK,
MX6SL_PAD_SD3_CMD__USDHC3_CMD,
MX6SL_PAD_SD3_DAT0__USDHC3_DAT0,
MX6SL_PAD_SD3_DAT1__USDHC3_DAT1,
MX6SL_PAD_SD3_DAT2__USDHC3_DAT2,
MX6SL_PAD_SD3_DAT3__USDHC3_DAT3,
MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
/* SD3 CD */
MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
......@@ -318,4 +318,38 @@ static iomux_v3_cfg_t mx6sl_arm2_elan_pads[] = {
MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */
};
#define MX6SL_USDHC_8BIT_PAD_SETTING(id, speed) \
mx6sl_sd##id##_##speed##mhz[] = { \
MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
}
#define MX6SL_USDHC_4BIT_PAD_SETTING(id, speed) \
mx6sl_sd##id##_##speed##mhz[] = { \
MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
}
static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 50);
static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 100);
static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 200);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 50);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 100);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 200);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 50);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 100);
static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 200);
#endif
......@@ -35,6 +35,6 @@ struct esdhc_platform_data {
unsigned int support_8bit;
unsigned int keep_power_at_suspend;
unsigned int delay_line;
int (*platform_pad_change)(int clock);
int (*platform_pad_change)(unsigned int index, int clock);
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */
......@@ -37,15 +37,15 @@
#define MX6SL_USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define MX6SL_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)
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_34ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define MX6SL_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)
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_HIGH | \
PAD_CTL_DSE_34ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define MX6SL_ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
......@@ -2425,8 +2425,12 @@
#define MX6SL_PAD_RESET_IN_B__SRC_RESET_B \
IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_CLK__USDHC1_CLK \
#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ \
IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_100MHZ \
IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_200MHZ \
IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
#define MX6SL_PAD_SD1_CLK__FEC_MDIO \
IOMUX_PAD(0x0534, 0x022C, 1, 0x06F4, 2, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_CLK__KPP_COL_0 \
......@@ -2442,8 +2446,12 @@
#define MX6SL_PAD_SD1_CLK__PL301_SIM_MX6SL_PER1_HADDR_25 \
IOMUX_PAD(0x0534, 0x022C, 7, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_CMD__USDHC1_CMD \
#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ \
IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_100MHZ \
IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_200MHZ \
IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
#define MX6SL_PAD_SD1_CMD__FEC_TX_CLK \
IOMUX_PAD(0x0538, 0x0230, 1, 0x070C, 2, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_CMD__KPP_ROW_0 \
......@@ -2459,8 +2467,12 @@
#define MX6SL_PAD_SD1_CMD__PL301_SIM_MX6SL_PER1_HADDR_26 \
IOMUX_PAD(0x0538, 0x0230, 7, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0 \
#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ \
IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_100MHZ \
IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_200MHZ \
IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
#define MX6SL_PAD_SD1_DAT0__FEC_RX_ER \
IOMUX_PAD(0x053C, 0x0234, 1, 0x0708, 2, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT0__KPP_COL_1 \
......@@ -2476,8 +2488,12 @@
#define MX6SL_PAD_SD1_DAT0__PL301_SIM_MX6SL_PER1_HADDR_27 \
IOMUX_PAD(0x053C, 0x0234, 7, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1 \
#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ \
IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_100MHZ \
IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_200MHZ \
IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
#define MX6SL_PAD_SD1_DAT1__FEC_RX_DV \
IOMUX_PAD(0x0540, 0x0238, 1, 0x0704, 2, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT1__KPP_ROW_1 \
......@@ -2493,8 +2509,12 @@
#define MX6SL_PAD_SD1_DAT1__PL301_SIM_MX6SL_PER1_HADDR_28 \
IOMUX_PAD(0x0540, 0x0238, 7, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2 \
#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ \
IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_100MHZ \
IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_200MHZ \
IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
#define MX6SL_PAD_SD1_DAT2__FEC_RDATA_1 \
IOMUX_PAD(0x0544, 0x023C, 1, 0x06FC, 2, NO_PAD_CTRL)
#define MX6SL_PAD_SD1_DAT2__KPP_COL_2 \
......@@ -2510,8 +2530,12 @@
#define MX6SL_PAD_SD1_DAT2__PL301_SIM_MX6SL_PER1_HADDR_29 \
IOMUX_PAD(0x0544, 0x023C, 7, 0x0000, 0, NO_PAD_CTRL)