1/* 2 * linux/arch/arm/mach-omap2/hsmmc.c 3 * 4 * Copyright (C) 2007-2008 Texas Instruments 5 * Copyright (C) 2008 Nokia Corporation 6 * Author: Texas Instruments 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12#include <linux/kernel.h> 13#include <linux/slab.h> 14#include <linux/string.h> 15#include <linux/delay.h> 16#include <mach/hardware.h> 17#include <plat/control.h> 18#include <plat/mmc.h> 19#include <plat/omap-pm.h> 20 21#include "hsmmc.h" 22 23#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) 24 25static u16 control_pbias_offset; 26static u16 control_devconf1_offset; 27static u16 control_mmc1; 28 29#define HSMMC_NAME_LEN 9 30 31static struct hsmmc_controller { 32 char name[HSMMC_NAME_LEN + 1]; 33} hsmmc[OMAP34XX_NR_MMC]; 34 35#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) 36 37static int hsmmc_get_context_loss(struct device *dev) 38{ 39 return omap_pm_get_dev_context_loss_count(dev); 40} 41 42#else 43#define hsmmc_get_context_loss NULL 44#endif 45 46static void omap_hsmmc1_before_set_reg(struct device *dev, int slot, 47 int power_on, int vdd) 48{ 49 u32 reg, prog_io; 50 struct omap_mmc_platform_data *mmc = dev->platform_data; 51 52 if (mmc->slots[0].remux) 53 mmc->slots[0].remux(dev, slot, power_on); 54 55 if (power_on) { 56 if (cpu_is_omap2430()) { 57 reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1); 58 if ((1 << vdd) >= MMC_VDD_30_31) 59 reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE; 60 else 61 reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE; 62 omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1); 63 } 64 65 if (mmc->slots[0].internal_clock) { 66 reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); 67 reg |= OMAP2_MMCSDIO1ADPCLKISEL; 68 omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0); 69 } 70 71 reg = omap_ctrl_readl(control_pbias_offset); 72 if (cpu_is_omap3630()) { 73 /* Set MMC I/O to 52Mhz */ 74 prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1); 75 prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL; 76 omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1); 77 } else { 78 reg |= OMAP2_PBIASSPEEDCTRL0; 79 } 80 reg &= ~OMAP2_PBIASLITEPWRDNZ0; 81 omap_ctrl_writel(reg, control_pbias_offset); 82 } else { 83 reg = omap_ctrl_readl(control_pbias_offset); 84 reg &= ~OMAP2_PBIASLITEPWRDNZ0; 85 omap_ctrl_writel(reg, control_pbias_offset); 86 } 87} 88 89static void omap_hsmmc1_after_set_reg(struct device *dev, int slot, 90 int power_on, int vdd) 91{ 92 u32 reg; 93 94 /* 100ms delay required for PBIAS configuration */ 95 msleep(100); 96 97 if (power_on) { 98 reg = omap_ctrl_readl(control_pbias_offset); 99 reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0); 100 if ((1 << vdd) <= MMC_VDD_165_195) 101 reg &= ~OMAP2_PBIASLITEVMODE0; 102 else 103 reg |= OMAP2_PBIASLITEVMODE0; 104 omap_ctrl_writel(reg, control_pbias_offset); 105 } else { 106 reg = omap_ctrl_readl(control_pbias_offset); 107 reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 | 108 OMAP2_PBIASLITEVMODE0); 109 omap_ctrl_writel(reg, control_pbias_offset); 110 } 111} 112 113static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot, 114 int power_on, int vdd) 115{ 116 u32 reg; 117 118 reg = omap_ctrl_readl(control_pbias_offset); 119 reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ | 120 OMAP4_USBC1_ICUSB_PWRDNZ); 121 omap_ctrl_writel(reg, control_pbias_offset); 122} 123 124static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, 125 int power_on, int vdd) 126{ 127 u32 reg; 128 129 if (power_on) { 130 reg = omap_ctrl_readl(control_pbias_offset); 131 reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ; 132 if ((1 << vdd) <= MMC_VDD_165_195) 133 reg &= ~OMAP4_MMC1_PBIASLITE_VMODE; 134 else 135 reg |= OMAP4_MMC1_PBIASLITE_VMODE; 136 reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ | 137 OMAP4_USBC1_ICUSB_PWRDNZ); 138 omap_ctrl_writel(reg, control_pbias_offset); 139 /* 4 microsec delay for comparator to generate an error*/ 140 udelay(4); 141 reg = omap_ctrl_readl(control_pbias_offset); 142 if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR) { 143 pr_err("Pbias Voltage is not same as LDO\n"); 144 /* Caution : On VMODE_ERROR Power Down MMC IO */ 145 reg &= ~(OMAP4_MMC1_PWRDNZ | OMAP4_USBC1_ICUSB_PWRDNZ); 146 omap_ctrl_writel(reg, control_pbias_offset); 147 } 148 } else { 149 reg = omap_ctrl_readl(control_pbias_offset); 150 reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | 151 OMAP4_MMC1_PBIASLITE_VMODE | OMAP4_MMC1_PWRDNZ | 152 OMAP4_USBC1_ICUSB_PWRDNZ); 153 omap_ctrl_writel(reg, control_pbias_offset); 154 } 155} 156 157static void hsmmc23_before_set_reg(struct device *dev, int slot, 158 int power_on, int vdd) 159{ 160 struct omap_mmc_platform_data *mmc = dev->platform_data; 161 162 if (mmc->slots[0].remux) 163 mmc->slots[0].remux(dev, slot, power_on); 164 165 if (power_on) { 166 /* Only MMC2 supports a CLKIN */ 167 if (mmc->slots[0].internal_clock) { 168 u32 reg; 169 170 reg = omap_ctrl_readl(control_devconf1_offset); 171 reg |= OMAP2_MMCSDIO2ADPCLKISEL; 172 omap_ctrl_writel(reg, control_devconf1_offset); 173 } 174 } 175} 176 177static int nop_mmc_set_power(struct device *dev, int slot, int power_on, 178 int vdd) 179{ 180 return 0; 181} 182 183static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; 184 185void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) 186{ 187 struct omap2_hsmmc_info *c; 188 int nr_hsmmc = ARRAY_SIZE(hsmmc_data); 189 int i; 190 u32 reg; 191 192 if (!cpu_is_omap44xx()) { 193 if (cpu_is_omap2430()) { 194 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; 195 control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; 196 } else { 197 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; 198 control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; 199 } 200 } else { 201 control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE; 202 control_mmc1 = OMAP44XX_CONTROL_MMC1; 203 reg = omap_ctrl_readl(control_mmc1); 204 reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 | 205 OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1); 206 reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 | 207 OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3); 208 reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL | 209 OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL | 210 OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL); 211 omap_ctrl_writel(reg, control_mmc1); 212 } 213 214 for (c = controllers; c->mmc; c++) { 215 struct hsmmc_controller *hc = hsmmc + c->mmc - 1; 216 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; 217 218 if (!c->mmc || c->mmc > nr_hsmmc) { 219 pr_debug("MMC%d: no such controller\n", c->mmc); 220 continue; 221 } 222 if (mmc) { 223 pr_debug("MMC%d: already configured\n", c->mmc); 224 continue; 225 } 226 227 mmc = kzalloc(sizeof(struct omap_mmc_platform_data), 228 GFP_KERNEL); 229 if (!mmc) { 230 pr_err("Cannot allocate memory for mmc device!\n"); 231 goto done; 232 } 233 234 if (c->name) 235 strncpy(hc->name, c->name, HSMMC_NAME_LEN); 236 else 237 snprintf(hc->name, ARRAY_SIZE(hc->name), 238 "mmc%islot%i", c->mmc, 1); 239 mmc->slots[0].name = hc->name; 240 mmc->nr_slots = 1; 241 mmc->slots[0].wires = c->wires; 242 mmc->slots[0].internal_clock = !c->ext_clock; 243 mmc->dma_mask = 0xffffffff; 244 245 mmc->get_context_loss_count = hsmmc_get_context_loss; 246 247 mmc->slots[0].switch_pin = c->gpio_cd; 248 mmc->slots[0].gpio_wp = c->gpio_wp; 249 250 mmc->slots[0].remux = c->remux; 251 mmc->slots[0].init_card = c->init_card; 252 253 if (c->cover_only) 254 mmc->slots[0].cover = 1; 255 256 if (c->nonremovable) 257 mmc->slots[0].nonremovable = 1; 258 259 if (c->power_saving) 260 mmc->slots[0].power_saving = 1; 261 262 if (c->no_off) 263 mmc->slots[0].no_off = 1; 264 265 if (c->vcc_aux_disable_is_sleep) 266 mmc->slots[0].vcc_aux_disable_is_sleep = 1; 267 268 /* NOTE: MMC slots should have a Vcc regulator set up. 269 * This may be from a TWL4030-family chip, another 270 * controllable regulator, or a fixed supply. 271 * 272 * temporary HACK: ocr_mask instead of fixed supply 273 */ 274 mmc->slots[0].ocr_mask = c->ocr_mask; 275 276 if (cpu_is_omap3517() || cpu_is_omap3505()) 277 mmc->slots[0].set_power = nop_mmc_set_power; 278 else 279 mmc->slots[0].features |= HSMMC_HAS_PBIAS; 280 281 switch (c->mmc) { 282 case 1: 283 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { 284 /* on-chip level shifting via PBIAS0/PBIAS1 */ 285 if (cpu_is_omap44xx()) { 286 mmc->slots[0].before_set_reg = 287 omap4_hsmmc1_before_set_reg; 288 mmc->slots[0].after_set_reg = 289 omap4_hsmmc1_after_set_reg; 290 } else { 291 mmc->slots[0].before_set_reg = 292 omap_hsmmc1_before_set_reg; 293 mmc->slots[0].after_set_reg = 294 omap_hsmmc1_after_set_reg; 295 } 296 } 297 298 /* Omap3630 HSMMC1 supports only 4-bit */ 299 if (cpu_is_omap3630() && c->wires > 4) { 300 c->wires = 4; 301 mmc->slots[0].wires = c->wires; 302 } 303 break; 304 case 2: 305 if (c->ext_clock) 306 c->transceiver = 1; 307 if (c->transceiver && c->wires > 4) 308 c->wires = 4; 309 /* FALLTHROUGH */ 310 case 3: 311 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { 312 /* off-chip level shifting, or none */ 313 mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; 314 mmc->slots[0].after_set_reg = NULL; 315 } 316 break; 317 default: 318 pr_err("MMC%d configuration not supported!\n", c->mmc); 319 kfree(mmc); 320 continue; 321 } 322 hsmmc_data[c->mmc - 1] = mmc; 323 } 324 325 omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); 326 327 /* pass the device nodes back to board setup code */ 328 for (c = controllers; c->mmc; c++) { 329 struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; 330 331 if (!c->mmc || c->mmc > nr_hsmmc) 332 continue; 333 c->dev = mmc->dev; 334 } 335 336done: 337 for (i = 0; i < nr_hsmmc; i++) 338 kfree(hsmmc_data[i]); 339} 340 341#endif 342