|
@@ -322,3 +322,154 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
|
|
else
|
|
else
|
|
mmc->reg_offset = 0;
|
|
mmc->reg_offset = 0;
|
|
|
|
|
|
|
|
+ mmc->get_context_loss_count = hsmmc_get_context_loss;
|
|
|
|
+
|
|
|
|
+ mmc->slots[0].switch_pin = c->gpio_cd;
|
|
|
|
+ mmc->slots[0].gpio_wp = c->gpio_wp;
|
|
|
|
+
|
|
|
|
+ mmc->slots[0].remux = c->remux;
|
|
|
|
+ mmc->slots[0].init_card = c->init_card;
|
|
|
|
+
|
|
|
|
+ if (c->cover_only)
|
|
|
|
+ mmc->slots[0].cover = 1;
|
|
|
|
+
|
|
|
|
+ if (c->nonremovable)
|
|
|
|
+ mmc->slots[0].nonremovable = 1;
|
|
|
|
+
|
|
|
|
+ if (c->power_saving)
|
|
|
|
+ mmc->slots[0].power_saving = 1;
|
|
|
|
+
|
|
|
|
+ if (c->no_off)
|
|
|
|
+ mmc->slots[0].no_off = 1;
|
|
|
|
+
|
|
|
|
+ if (c->no_off_init)
|
|
|
|
+ mmc->slots[0].no_regulator_off_init = c->no_off_init;
|
|
|
|
+
|
|
|
|
+ if (c->vcc_aux_disable_is_sleep)
|
|
|
|
+ mmc->slots[0].vcc_aux_disable_is_sleep = 1;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * NOTE: MMC slots should have a Vcc regulator set up.
|
|
|
|
+ * This may be from a TWL4030-family chip, another
|
|
|
|
+ * controllable regulator, or a fixed supply.
|
|
|
|
+ *
|
|
|
|
+ * temporary HACK: ocr_mask instead of fixed supply
|
|
|
|
+ */
|
|
|
|
+ if (soc_is_am35xx())
|
|
|
|
+ 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 (!soc_is_am35xx())
|
|
|
|
+ mmc->slots[0].features |= HSMMC_HAS_PBIAS;
|
|
|
|
+
|
|
|
|
+ if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
|
|
|
|
+ mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
|
|
|
|
+
|
|
|
|
+ switch (c->mmc) {
|
|
|
|
+ case 1:
|
|
|
|
+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
|
|
|
|
+ /* on-chip level shifting via PBIAS0/PBIAS1 */
|
|
|
|
+ if (cpu_is_omap44xx()) {
|
|
|
|
+ mmc->slots[0].before_set_reg =
|
|
|
|
+ omap4_hsmmc1_before_set_reg;
|
|
|
|
+ mmc->slots[0].after_set_reg =
|
|
|
|
+ omap4_hsmmc1_after_set_reg;
|
|
|
|
+ } else {
|
|
|
|
+ mmc->slots[0].before_set_reg =
|
|
|
|
+ omap_hsmmc1_before_set_reg;
|
|
|
|
+ mmc->slots[0].after_set_reg =
|
|
|
|
+ omap_hsmmc1_after_set_reg;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (soc_is_am35xx())
|
|
|
|
+ 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)) {
|
|
|
|
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
|
|
|
|
+ c->caps |= MMC_CAP_4_BIT_DATA;
|
|
|
|
+ mmc->slots[0].caps = c->caps;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ if (soc_is_am35xx())
|
|
|
|
+ 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)) {
|
|
|
|
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
|
|
|
|
+ c->caps |= MMC_CAP_4_BIT_DATA;
|
|
|
|
+ }
|
|
|
|
+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
|
|
|
|
+ /* off-chip level shifting, or none */
|
|
|
|
+ mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
|
|
|
|
+ mmc->slots[0].after_set_reg = NULL;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ case 4:
|
|
|
|
+ case 5:
|
|
|
|
+ mmc->slots[0].before_set_reg = NULL;
|
|
|
|
+ mmc->slots[0].after_set_reg = NULL;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ pr_err("MMC%d configuration not supported!\n", c->mmc);
|
|
|
|
+ kfree(hc_name);
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int omap_hsmmc_done;
|
|
|
|
+
|
|
|
|
+void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
|
|
|
|
+{
|
|
|
|
+ struct platform_device *pdev;
|
|
|
|
+ struct omap_mmc_platform_data *mmc_pdata;
|
|
|
|
+ int res;
|
|
|
|
+
|
|
|
|
+ if (omap_hsmmc_done != 1)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ omap_hsmmc_done++;
|
|
|
|
+
|
|
|
|
+ for (; c->mmc; c++) {
|
|
|
|
+ if (!c->deferred)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ pdev = c->pdev;
|
|
|
|
+ if (!pdev)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ mmc_pdata = pdev->dev.platform_data;
|
|
|
|
+ if (!mmc_pdata)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ mmc_pdata->slots[0].switch_pin = c->gpio_cd;
|
|
|
|
+ mmc_pdata->slots[0].gpio_wp = c->gpio_wp;
|
|
|
|
+
|
|
|
|
+ res = omap_device_register(pdev);
|
|
|
|
+ if (res)
|
|
|
|
+ pr_err("Could not late init MMC %s\n",
|
|
|
|
+ c->name);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
|
|
|
|
+
|
|
|
|
+static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
|
|
|
|
+ int ctrl_nr)
|
|
|
|
+{
|
|
|
|
+ struct omap_hwmod *oh;
|
|
|
|
+ struct omap_hwmod *ohs[1];
|
|
|
|
+ struct omap_device *od;
|
|
|
|
+ struct platform_device *pdev;
|