aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/devices.c')
-rw-r--r--arch/arm/mach-omap2/devices.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 90af2ac469aa..9d7216ff6c9f 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -14,16 +14,19 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/clk.h>
17 18
18#include <mach/hardware.h> 19#include <mach/hardware.h>
19#include <asm/mach-types.h> 20#include <asm/mach-types.h>
20#include <asm/mach/map.h> 21#include <asm/mach/map.h>
21 22
23#include <mach/control.h>
22#include <mach/tc.h> 24#include <mach/tc.h>
23#include <mach/board.h> 25#include <mach/board.h>
24#include <mach/mux.h> 26#include <mach/mux.h>
25#include <mach/gpio.h> 27#include <mach/gpio.h>
26#include <mach/eac.h> 28#include <mach/eac.h>
29#include <mach/mmc.h>
27 30
28#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) 31#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
29#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) 32#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
@@ -295,6 +298,171 @@ static void omap_init_sha1_md5(void)
295static inline void omap_init_sha1_md5(void) { } 298static inline void omap_init_sha1_md5(void) { }
296#endif 299#endif
297 300
301/*-------------------------------------------------------------------------*/
302
303#ifdef CONFIG_ARCH_OMAP3
304
305#define MMCHS_SYSCONFIG 0x0010
306#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
307#define MMCHS_SYSSTATUS 0x0014
308#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
309
310static struct platform_device dummy_pdev = {
311 .dev = {
312 .bus = &platform_bus_type,
313 },
314};
315
316/**
317 * omap_hsmmc_reset() - Full reset of each HS-MMC controller
318 *
319 * Ensure that each MMC controller is fully reset. Controllers
320 * left in an unknown state (by bootloader) may prevent retention
321 * or OFF-mode. This is especially important in cases where the
322 * MMC driver is not enabled, _or_ built as a module.
323 *
324 * In order for reset to work, interface, functional and debounce
325 * clocks must be enabled. The debounce clock comes from func_32k_clk
326 * and is not under SW control, so we only enable i- and f-clocks.
327 **/
328static void __init omap_hsmmc_reset(void)
329{
330 u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
331 OMAP24XX_NR_MMC;
332
333 for (i = 0; i < nr_controllers; i++) {
334 u32 v, base = 0;
335 struct clk *iclk, *fclk;
336 struct device *dev = &dummy_pdev.dev;
337
338 switch (i) {
339 case 0:
340 base = OMAP2_MMC1_BASE;
341 break;
342 case 1:
343 base = OMAP2_MMC2_BASE;
344 break;
345 case 2:
346 base = OMAP3_MMC3_BASE;
347 break;
348 }
349
350 dummy_pdev.id = i;
351 iclk = clk_get(dev, "mmchs_ick");
352 if (iclk && clk_enable(iclk))
353 iclk = NULL;
354
355 fclk = clk_get(dev, "mmchs_fck");
356 if (fclk && clk_enable(fclk))
357 fclk = NULL;
358
359 if (!iclk || !fclk) {
360 printk(KERN_WARNING
361 "%s: Unable to enable clocks for MMC%d, "
362 "cannot reset.\n", __func__, i);
363 break;
364 }
365
366 omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
367 v = omap_readl(base + MMCHS_SYSSTATUS);
368 while (!(omap_readl(base + MMCHS_SYSSTATUS) &
369 MMCHS_SYSSTATUS_RESETDONE))
370 cpu_relax();
371
372 if (fclk) {
373 clk_disable(fclk);
374 clk_put(fclk);
375 }
376 if (iclk) {
377 clk_disable(iclk);
378 clk_put(iclk);
379 }
380 }
381}
382#else
383static inline void omap_hsmmc_reset(void) {}
384#endif
385
386#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
387 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
388
389static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
390 int controller_nr)
391{
392 if (cpu_is_omap2420() && controller_nr == 0) {
393 omap_cfg_reg(H18_24XX_MMC_CMD);
394 omap_cfg_reg(H15_24XX_MMC_CLKI);
395 omap_cfg_reg(G19_24XX_MMC_CLKO);
396 omap_cfg_reg(F20_24XX_MMC_DAT0);
397 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
398 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
399 if (mmc_controller->slots[0].wires == 4) {
400 omap_cfg_reg(H14_24XX_MMC_DAT1);
401 omap_cfg_reg(E19_24XX_MMC_DAT2);
402 omap_cfg_reg(D19_24XX_MMC_DAT3);
403 omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
404 omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
405 omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
406 }
407
408 /*
409 * Use internal loop-back in MMC/SDIO Module Input Clock
410 * selection
411 */
412 if (mmc_controller->slots[0].internal_clock) {
413 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
414 v |= (1 << 24);
415 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
416 }
417 }
418}
419
420void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
421 int nr_controllers)
422{
423 int i;
424
425 for (i = 0; i < nr_controllers; i++) {
426 unsigned long base, size;
427 unsigned int irq = 0;
428
429 if (!mmc_data[i])
430 continue;
431
432 omap2_mmc_mux(mmc_data[i], i);
433
434 switch (i) {
435 case 0:
436 base = OMAP2_MMC1_BASE;
437 irq = INT_24XX_MMC_IRQ;
438 break;
439 case 1:
440 base = OMAP2_MMC2_BASE;
441 irq = INT_24XX_MMC2_IRQ;
442 break;
443 case 2:
444 if (!cpu_is_omap34xx())
445 return;
446 base = OMAP3_MMC3_BASE;
447 irq = INT_34XX_MMC3_IRQ;
448 break;
449 default:
450 continue;
451 }
452
453 if (cpu_is_omap2420())
454 size = OMAP2420_MMC_SIZE;
455 else
456 size = HSMMC_SIZE;
457
458 omap_mmc_add(i, base, size, irq, mmc_data[i]);
459 };
460}
461
462#endif
463
464/*-------------------------------------------------------------------------*/
465
298#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) 466#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
299#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) 467#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
300#define OMAP_HDQ_BASE 0x480B2000 468#define OMAP_HDQ_BASE 0x480B2000
@@ -334,6 +502,7 @@ static int __init omap2_init_devices(void)
334 /* please keep these calls, and their implementations above, 502 /* please keep these calls, and their implementations above,
335 * in alphabetical order so they're easier to sort through. 503 * in alphabetical order so they're easier to sort through.
336 */ 504 */
505 omap_hsmmc_reset();
337 omap_init_mbox(); 506 omap_init_mbox();
338 omap_init_mcspi(); 507 omap_init_mcspi();
339 omap_hdq_init(); 508 omap_hdq_init();