]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/blobdiff - arch/arm/mach-omap2/hsmmc.c
arm:omap:am33xx: Register HSMMC Platform on AM335x EVM
[sitara-epos/sitara-epos-kernel.git] / arch / arm / mach-omap2 / hsmmc.c
index 77085847e4e7dafc893a2d255bee5dbac90d4d55..7c12ca34ad32144e8f0e8a74b18f049b74ab4ae3 100644 (file)
@@ -129,15 +129,11 @@ static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
         * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
         * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
         * 1.8V and 3.0V modes, controlled by the PBIAS register.
-        *
-        * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
-        * is most naturally TWL VSIM; those pins also use PBIAS.
-        *
-        * FIXME handle VMMC1A as needed ...
         */
        reg = omap4_ctrl_pad_readl(control_pbias_offset);
        reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-               OMAP4_MMC1_PWRDNZ_MASK);
+               OMAP4_MMC1_PWRDNZ_MASK |
+               OMAP4_MMC1_PBIASLITE_VMODE_MASK);
        omap4_ctrl_pad_writel(reg, control_pbias_offset);
 }
 
@@ -172,12 +168,17 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
                        reg &= ~(OMAP4_MMC1_PWRDNZ_MASK);
                        omap4_ctrl_pad_writel(reg, control_pbias_offset);
                }
-       } else {
-               reg = omap4_ctrl_pad_readl(control_pbias_offset);
-               reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-                       OMAP4_MMC1_PWRDNZ_MASK |
-                       OMAP4_MMC1_PBIASLITE_VMODE_MASK);
-               omap4_ctrl_pad_writel(reg, control_pbias_offset);
+       }
+}
+
+static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
+{
+       u32 reg;
+
+       if (mmc->slots[0].internal_clock) {
+               reg = omap_ctrl_readl(control_devconf1_offset);
+               reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+               omap_ctrl_writel(reg, control_devconf1_offset);
        }
 }
 
@@ -189,16 +190,19 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot,
        if (mmc->slots[0].remux)
                mmc->slots[0].remux(dev, slot, power_on);
 
-       if (power_on) {
-               /* Only MMC2 supports a CLKIN */
-               if (mmc->slots[0].internal_clock) {
-                       u32 reg;
+       if (power_on)
+               hsmmc2_select_input_clk_src(mmc);
+}
 
-                       reg = omap_ctrl_readl(control_devconf1_offset);
-                       reg |= OMAP2_MMCSDIO2ADPCLKISEL;
-                       omap_ctrl_writel(reg, control_devconf1_offset);
-               }
-       }
+static int am35x_hsmmc2_set_power(struct device *dev, int slot,
+                                 int power_on, int vdd)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       if (power_on)
+               hsmmc2_select_input_clk_src(mmc);
+
+       return 0;
 }
 
 static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
@@ -210,10 +214,12 @@ static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
 static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
                        int controller_nr)
 {
-       if (gpio_is_valid(mmc_controller->slots[0].switch_pin))
+       if (gpio_is_valid(mmc_controller->slots[0].switch_pin) &&
+               (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
                omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
                                        OMAP_PIN_INPUT_PULLUP);
-       if (gpio_is_valid(mmc_controller->slots[0].gpio_wp))
+       if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) &&
+               (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
                omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
                                        OMAP_PIN_INPUT_PULLUP);
        if (cpu_is_omap34xx()) {
@@ -298,6 +304,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
                return -ENOMEM;
        }
 
+       if (cpu_is_am33xx())
+               mmc->version = MMC_CTRL_VERSION_2;
+
        if (c->name)
                strncpy(hc_name, c->name, HSMMC_NAME_LEN);
        else
@@ -306,6 +315,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
        mmc->slots[0].name = hc_name;
        mmc->nr_slots = 1;
        mmc->slots[0].caps = c->caps;
+       mmc->slots[0].pm_caps = c->pm_caps;
        mmc->slots[0].internal_clock = !c->ext_clock;
        mmc->dma_mask = 0xffffffff;
        if (cpu_is_omap44xx())
@@ -346,14 +356,21 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
         *
         * temporary HACK: ocr_mask instead of fixed supply
         */
-       mmc->slots[0].ocr_mask = c->ocr_mask;
-
-       if (cpu_is_omap3517() || cpu_is_omap3505())
-               mmc->slots[0].set_power = nop_mmc_set_power;
+       if (cpu_is_omap3505() || cpu_is_omap3517())
+               mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
+                                        MMC_VDD_26_27 |
+                                        MMC_VDD_27_28 |
+                                        MMC_VDD_29_30 |
+                                        MMC_VDD_30_31 |
+                                        MMC_VDD_31_32;
        else
+               mmc->slots[0].ocr_mask = c->ocr_mask;
+
+       if (!cpu_is_omap3517() && !cpu_is_omap3505() && !cpu_is_am33xx())
                mmc->slots[0].features |= HSMMC_HAS_PBIAS;
 
-       if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
+       if ((cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) ||
+                                                               cpu_is_am33xx())
                mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
 
        switch (c->mmc) {
@@ -373,6 +390,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
                        }
                }
 
+               if (cpu_is_omap3517() || cpu_is_omap3505() || cpu_is_am33xx())
+                       mmc->slots[0].set_power = nop_mmc_set_power;
+
                /* OMAP3630 HSMMC1 supports only 4-bit */
                if (cpu_is_omap3630() &&
                                (c->caps & MMC_CAP_8_BIT_DATA)) {
@@ -382,6 +402,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
                }
                break;
        case 2:
+               if (cpu_is_omap3517() || cpu_is_omap3505())
+                       mmc->slots[0].set_power = am35x_hsmmc2_set_power;
+
                if (c->ext_clock)
                        c->transceiver = 1;
                if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
@@ -431,7 +454,9 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
                pr_err("%s fails!\n", __func__);
                goto done;
        }
-       omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+
+       if (!cpu_is_am33xx())
+               omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
 
        name = "omap_hsmmc";
 
@@ -489,7 +514,7 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
                        OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK);
                reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK |
                        OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK);
-               reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK|
+               reg |= (OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK |
                        OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK |
                        OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK);
                omap4_ctrl_pad_writel(reg, control_mmc1);