aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-omap/devices.c123
1 files changed, 91 insertions, 32 deletions
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 187e3d8bfdfe..bc1cf30c83e0 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -21,6 +21,7 @@
21 21
22#include <mach/tc.h> 22#include <mach/tc.h>
23#include <mach/board.h> 23#include <mach/board.h>
24#include <mach/mmc.h>
24#include <mach/mux.h> 25#include <mach/mux.h>
25#include <mach/gpio.h> 26#include <mach/gpio.h>
26#include <mach/menelaus.h> 27#include <mach/menelaus.h>
@@ -194,25 +195,38 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
194 195
195/*-------------------------------------------------------------------------*/ 196/*-------------------------------------------------------------------------*/
196 197
197#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) 198#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
199 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
198 200
199#ifdef CONFIG_ARCH_OMAP24XX 201#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
200#define OMAP_MMC1_BASE 0x4809c000 202#define OMAP_MMC1_BASE 0x4809c000
201#define OMAP_MMC1_INT INT_24XX_MMC_IRQ 203#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x1fc)
204#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
205
206#define OMAP_MMC2_BASE 0x480b4000
207#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x1fc)
208#define OMAP_MMC2_INT INT_24XX_MMC2_IRQ
209
202#else 210#else
211
203#define OMAP_MMC1_BASE 0xfffb7800 212#define OMAP_MMC1_BASE 0xfffb7800
213#define OMAP_MMC1_END (OMAP_MMC1_BASE + 0x7f)
204#define OMAP_MMC1_INT INT_MMC 214#define OMAP_MMC1_INT INT_MMC
205#endif 215
206#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ 216#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
217#define OMAP_MMC2_END (OMAP_MMC2_BASE + 0x7f)
218#define OMAP_MMC2_INT INT_1610_MMC2
207 219
208static struct omap_mmc_conf mmc1_conf; 220#endif
221
222static struct omap_mmc_platform_data mmc1_data;
209 223
210static u64 mmc1_dmamask = 0xffffffff; 224static u64 mmc1_dmamask = 0xffffffff;
211 225
212static struct resource mmc1_resources[] = { 226static struct resource mmc1_resources[] = {
213 { 227 {
214 .start = OMAP_MMC1_BASE, 228 .start = OMAP_MMC1_BASE,
215 .end = OMAP_MMC1_BASE + 0x7f, 229 .end = OMAP_MMC1_END,
216 .flags = IORESOURCE_MEM, 230 .flags = IORESOURCE_MEM,
217 }, 231 },
218 { 232 {
@@ -226,26 +240,27 @@ static struct platform_device mmc_omap_device1 = {
226 .id = 1, 240 .id = 1,
227 .dev = { 241 .dev = {
228 .dma_mask = &mmc1_dmamask, 242 .dma_mask = &mmc1_dmamask,
229 .platform_data = &mmc1_conf, 243 .platform_data = &mmc1_data,
230 }, 244 },
231 .num_resources = ARRAY_SIZE(mmc1_resources), 245 .num_resources = ARRAY_SIZE(mmc1_resources),
232 .resource = mmc1_resources, 246 .resource = mmc1_resources,
233}; 247};
234 248
235#ifdef CONFIG_ARCH_OMAP16XX 249#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
250 defined(CONFIG_ARCH_OMAP34XX)
236 251
237static struct omap_mmc_conf mmc2_conf; 252static struct omap_mmc_platform_data mmc2_data;
238 253
239static u64 mmc2_dmamask = 0xffffffff; 254static u64 mmc2_dmamask = 0xffffffff;
240 255
241static struct resource mmc2_resources[] = { 256static struct resource mmc2_resources[] = {
242 { 257 {
243 .start = OMAP_MMC2_BASE, 258 .start = OMAP_MMC2_BASE,
244 .end = OMAP_MMC2_BASE + 0x7f, 259 .end = OMAP_MMC2_END,
245 .flags = IORESOURCE_MEM, 260 .flags = IORESOURCE_MEM,
246 }, 261 },
247 { 262 {
248 .start = INT_1610_MMC2, 263 .start = OMAP_MMC2_INT,
249 .flags = IORESOURCE_IRQ, 264 .flags = IORESOURCE_IRQ,
250 }, 265 },
251}; 266};
@@ -255,26 +270,19 @@ static struct platform_device mmc_omap_device2 = {
255 .id = 2, 270 .id = 2,
256 .dev = { 271 .dev = {
257 .dma_mask = &mmc2_dmamask, 272 .dma_mask = &mmc2_dmamask,
258 .platform_data = &mmc2_conf, 273 .platform_data = &mmc2_data,
259 }, 274 },
260 .num_resources = ARRAY_SIZE(mmc2_resources), 275 .num_resources = ARRAY_SIZE(mmc2_resources),
261 .resource = mmc2_resources, 276 .resource = mmc2_resources,
262}; 277};
263#endif 278#endif
264 279
265static void __init omap_init_mmc(void) 280static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
266{ 281{
267 const struct omap_mmc_config *mmc_conf; 282 if (cpu_is_omap2430() || cpu_is_omap34xx())
268 const struct omap_mmc_conf *mmc;
269
270 /* NOTE: assumes MMC was never (wrongly) enabled */
271 mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
272 if (!mmc_conf)
273 return; 283 return;
274 284
275 /* block 1 is always available and has just one pinout option */ 285 if (mmc_conf->mmc[0].enabled) {
276 mmc = &mmc_conf->mmc[0];
277 if (mmc->enabled) {
278 if (cpu_is_omap24xx()) { 286 if (cpu_is_omap24xx()) {
279 omap_cfg_reg(H18_24XX_MMC_CMD); 287 omap_cfg_reg(H18_24XX_MMC_CMD);
280 omap_cfg_reg(H15_24XX_MMC_CLKI); 288 omap_cfg_reg(H15_24XX_MMC_CLKI);
@@ -292,7 +300,7 @@ static void __init omap_init_mmc(void)
292 omap_cfg_reg(P20_1710_MMC_DATDIR0); 300 omap_cfg_reg(P20_1710_MMC_DATDIR0);
293 } 301 }
294 } 302 }
295 if (mmc->wire4) { 303 if (mmc_conf->mmc[0].wire4) {
296 if (cpu_is_omap24xx()) { 304 if (cpu_is_omap24xx()) {
297 omap_cfg_reg(H14_24XX_MMC_DAT1); 305 omap_cfg_reg(H14_24XX_MMC_DAT1);
298 omap_cfg_reg(E19_24XX_MMC_DAT2); 306 omap_cfg_reg(E19_24XX_MMC_DAT2);
@@ -303,25 +311,35 @@ static void __init omap_init_mmc(void)
303 } else { 311 } else {
304 omap_cfg_reg(MMC_DAT1); 312 omap_cfg_reg(MMC_DAT1);
305 /* NOTE: DAT2 can be on W10 (here) or M15 */ 313 /* NOTE: DAT2 can be on W10 (here) or M15 */
306 if (!mmc->nomux) 314 if (!mmc_conf->mmc[0].nomux)
307 omap_cfg_reg(MMC_DAT2); 315 omap_cfg_reg(MMC_DAT2);
308 omap_cfg_reg(MMC_DAT3); 316 omap_cfg_reg(MMC_DAT3);
309 } 317 }
310 } 318 }
311 mmc1_conf = *mmc; 319#if defined(CONFIG_ARCH_OMAP2420)
312 (void) platform_device_register(&mmc_omap_device1); 320 if (mmc_conf->mmc[0].internal_clock) {
321 /*
322 * Use internal loop-back in MMC/SDIO
323 * Module Input Clock selection
324 */
325 if (cpu_is_omap24xx()) {
326 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
327 v |= (1 << 24); /* not used in 243x */
328 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
329 }
330 }
331#endif
313 } 332 }
314 333
315#ifdef CONFIG_ARCH_OMAP16XX 334#ifdef CONFIG_ARCH_OMAP16XX
316 /* block 2 is on newer chips, and has many pinout options */ 335 /* block 2 is on newer chips, and has many pinout options */
317 mmc = &mmc_conf->mmc[1]; 336 if (mmc_conf->mmc[1].enabled) {
318 if (mmc->enabled) { 337 if (!mmc_conf->mmc[1].nomux) {
319 if (!mmc->nomux) {
320 omap_cfg_reg(Y8_1610_MMC2_CMD); 338 omap_cfg_reg(Y8_1610_MMC2_CMD);
321 omap_cfg_reg(Y10_1610_MMC2_CLK); 339 omap_cfg_reg(Y10_1610_MMC2_CLK);
322 omap_cfg_reg(R18_1610_MMC2_CLKIN); 340 omap_cfg_reg(R18_1610_MMC2_CLKIN);
323 omap_cfg_reg(W8_1610_MMC2_DAT0); 341 omap_cfg_reg(W8_1610_MMC2_DAT0);
324 if (mmc->wire4) { 342 if (mmc_conf->mmc[1].wire4) {
325 omap_cfg_reg(V8_1610_MMC2_DAT1); 343 omap_cfg_reg(V8_1610_MMC2_DAT1);
326 omap_cfg_reg(W15_1610_MMC2_DAT2); 344 omap_cfg_reg(W15_1610_MMC2_DAT2);
327 omap_cfg_reg(R10_1610_MMC2_DAT3); 345 omap_cfg_reg(R10_1610_MMC2_DAT3);
@@ -337,14 +355,55 @@ static void __init omap_init_mmc(void)
337 if (cpu_is_omap1710()) 355 if (cpu_is_omap1710())
338 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), 356 omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
339 MOD_CONF_CTRL_1); 357 MOD_CONF_CTRL_1);
340 mmc2_conf = *mmc; 358 }
359#endif
360}
361
362static void __init omap_init_mmc(void)
363{
364 const struct omap_mmc_config *mmc_conf;
365
366 /* NOTE: assumes MMC was never (wrongly) enabled */
367 mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
368 if (!mmc_conf)
369 return;
370
371 omap_init_mmc_conf(mmc_conf);
372
373 if (mmc_conf->mmc[0].enabled) {
374 mmc1_data.conf = mmc_conf->mmc[0];
375 (void) platform_device_register(&mmc_omap_device1);
376 }
377
378#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
379 defined(CONFIG_ARCH_OMAP34XX)
380 if (mmc_conf->mmc[1].enabled) {
381 mmc2_data.conf = mmc_conf->mmc[1];
341 (void) platform_device_register(&mmc_omap_device2); 382 (void) platform_device_register(&mmc_omap_device2);
342 } 383 }
343#endif 384#endif
344 return;
345} 385}
386
387void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
388{
389 switch (host) {
390 case 1:
391 mmc1_data = *info;
392 break;
393#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
394 defined(CONFIG_ARCH_OMAP34XX)
395 case 2:
396 mmc2_data = *info;
397 break;
398#endif
399 default:
400 BUG();
401 }
402}
403
346#else 404#else
347static inline void omap_init_mmc(void) {} 405static inline void omap_init_mmc(void) {}
406void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
348#endif 407#endif
349 408
350/*-------------------------------------------------------------------------*/ 409/*-------------------------------------------------------------------------*/