mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 15:43:59 +08:00
ff2516fbef
The OMAP watchdog timer IP blocks require a specific set of register writes to occur before they will be disabled[1], even if the device clocks appear to be disabled in the CM_*CLKEN registers. In the MPU watchdog case, failure to execute this reset sequence will eventually cause the watchdog to reset the OMAP unexpectedly. Previously, the code to disable this watchdog was manually called from mach-omap2/devices.c during device initialization. This causes the watchdog to be unconditionally disabled for a portion of kernel initialization. This should be controllable by the board-*.c files, since some system integrators will want full watchdog coverage of kernel initialization. Also, the watchdog disable code was not connected to the hwmod shutdown code. This means that calling omap_hwmod_shutdown() will not, in fact, disable the watchdog, and the goal of omap_hwmod_shutdown() is to be able to shutdown any on-chip OMAP device. To resolve the latter problem, populate the pre_shutdown pointer in the watchdog timer hwmod classes with a function that executes the watchdog shutdown sequence. This allows the hwmod code to fully disable the watchdog. Then, to allow some board files to support watchdog coverage throughout kernel initialization, add common code to mach-omap2/io.c to cause the MPU watchdog to be disabled on boot unless a board file specifically requests it to remain enabled. Board files can do this by changing the watchdog timer hwmod's postsetup state between the omap2_init_common_infrastructure() and omap2_init_common_devices() function calls. 1. OMAP34xx Multimedia Device Silicon Revision 3.1.x Rev. ZH [SWPU222H], Section 16.4.3.6, "Start/Stop Sequence for WDTs (Using WDTi.WSPR Register)" Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Benoît Cousson <b-cousson@ti.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Charulatha Varadarajan <charu@ti.com>
1015 lines
24 KiB
C
1015 lines
24 KiB
C
/*
|
|
* linux/arch/arm/mach-omap2/devices.c
|
|
*
|
|
* OMAP2 platform device setup/initialization
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/io.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/err.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <mach/irqs.h>
|
|
#include <asm/mach-types.h>
|
|
#include <asm/mach/map.h>
|
|
#include <asm/pmu.h>
|
|
|
|
#include <plat/tc.h>
|
|
#include <plat/board.h>
|
|
#include <plat/mcbsp.h>
|
|
#include <mach/gpio.h>
|
|
#include <plat/mmc.h>
|
|
#include <plat/dma.h>
|
|
#include <plat/omap_hwmod.h>
|
|
#include <plat/omap_device.h>
|
|
|
|
#include "mux.h"
|
|
#include "control.h"
|
|
|
|
#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
|
|
|
|
static struct resource cam_resources[] = {
|
|
{
|
|
.start = OMAP24XX_CAMERA_BASE,
|
|
.end = OMAP24XX_CAMERA_BASE + 0xfff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_CAM_IRQ,
|
|
.flags = IORESOURCE_IRQ,
|
|
}
|
|
};
|
|
|
|
static struct platform_device omap_cam_device = {
|
|
.name = "omap24xxcam",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(cam_resources),
|
|
.resource = cam_resources,
|
|
};
|
|
|
|
static inline void omap_init_camera(void)
|
|
{
|
|
platform_device_register(&omap_cam_device);
|
|
}
|
|
|
|
#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
|
|
|
|
static struct resource omap3isp_resources[] = {
|
|
{
|
|
.start = OMAP3430_ISP_BASE,
|
|
.end = OMAP3430_ISP_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_CBUFF_BASE,
|
|
.end = OMAP3430_ISP_CBUFF_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_CCP2_BASE,
|
|
.end = OMAP3430_ISP_CCP2_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_CCDC_BASE,
|
|
.end = OMAP3430_ISP_CCDC_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_HIST_BASE,
|
|
.end = OMAP3430_ISP_HIST_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_H3A_BASE,
|
|
.end = OMAP3430_ISP_H3A_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_PREV_BASE,
|
|
.end = OMAP3430_ISP_PREV_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_RESZ_BASE,
|
|
.end = OMAP3430_ISP_RESZ_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_SBL_BASE,
|
|
.end = OMAP3430_ISP_SBL_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_CSI2A_BASE,
|
|
.end = OMAP3430_ISP_CSI2A_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3430_ISP_CSI2PHY_BASE,
|
|
.end = OMAP3430_ISP_CSI2PHY_END,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_34XX_CAM_IRQ,
|
|
.flags = IORESOURCE_IRQ,
|
|
}
|
|
};
|
|
|
|
static struct platform_device omap3isp_device = {
|
|
.name = "omap3isp",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(omap3isp_resources),
|
|
.resource = omap3isp_resources,
|
|
};
|
|
|
|
static inline void omap_init_camera(void)
|
|
{
|
|
platform_device_register(&omap3isp_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_camera(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
|
|
|
|
#define MBOX_REG_SIZE 0x120
|
|
|
|
#ifdef CONFIG_ARCH_OMAP2
|
|
static struct resource omap2_mbox_resources[] = {
|
|
{
|
|
.start = OMAP24XX_MAILBOX_BASE,
|
|
.end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_MAIL_U0_MPU,
|
|
.flags = IORESOURCE_IRQ,
|
|
.name = "dsp",
|
|
},
|
|
{
|
|
.start = INT_24XX_MAIL_U3_MPU,
|
|
.flags = IORESOURCE_IRQ,
|
|
.name = "iva",
|
|
},
|
|
};
|
|
static int omap2_mbox_resources_sz = ARRAY_SIZE(omap2_mbox_resources);
|
|
#else
|
|
#define omap2_mbox_resources NULL
|
|
#define omap2_mbox_resources_sz 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_OMAP3
|
|
static struct resource omap3_mbox_resources[] = {
|
|
{
|
|
.start = OMAP34XX_MAILBOX_BASE,
|
|
.end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_MAIL_U0_MPU,
|
|
.flags = IORESOURCE_IRQ,
|
|
.name = "dsp",
|
|
},
|
|
};
|
|
static int omap3_mbox_resources_sz = ARRAY_SIZE(omap3_mbox_resources);
|
|
#else
|
|
#define omap3_mbox_resources NULL
|
|
#define omap3_mbox_resources_sz 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_OMAP4
|
|
|
|
#define OMAP4_MBOX_REG_SIZE 0x130
|
|
static struct resource omap4_mbox_resources[] = {
|
|
{
|
|
.start = OMAP44XX_MAILBOX_BASE,
|
|
.end = OMAP44XX_MAILBOX_BASE +
|
|
OMAP4_MBOX_REG_SIZE - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP44XX_IRQ_MAIL_U0,
|
|
.flags = IORESOURCE_IRQ,
|
|
.name = "mbox",
|
|
},
|
|
};
|
|
static int omap4_mbox_resources_sz = ARRAY_SIZE(omap4_mbox_resources);
|
|
#else
|
|
#define omap4_mbox_resources NULL
|
|
#define omap4_mbox_resources_sz 0
|
|
#endif
|
|
|
|
static struct platform_device mbox_device = {
|
|
.name = "omap-mailbox",
|
|
.id = -1,
|
|
};
|
|
|
|
static inline void omap_init_mbox(void)
|
|
{
|
|
if (cpu_is_omap24xx()) {
|
|
mbox_device.resource = omap2_mbox_resources;
|
|
mbox_device.num_resources = omap2_mbox_resources_sz;
|
|
} else if (cpu_is_omap34xx()) {
|
|
mbox_device.resource = omap3_mbox_resources;
|
|
mbox_device.num_resources = omap3_mbox_resources_sz;
|
|
} else if (cpu_is_omap44xx()) {
|
|
mbox_device.resource = omap4_mbox_resources;
|
|
mbox_device.num_resources = omap4_mbox_resources_sz;
|
|
} else {
|
|
pr_err("%s: platform not supported\n", __func__);
|
|
return;
|
|
}
|
|
platform_device_register(&mbox_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_mbox(void) { }
|
|
#endif /* CONFIG_OMAP_MBOX_FWK */
|
|
|
|
static inline void omap_init_sti(void) {}
|
|
|
|
#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
|
|
|
|
static struct platform_device omap_pcm = {
|
|
.name = "omap-pcm-audio",
|
|
.id = -1,
|
|
};
|
|
|
|
/*
|
|
* OMAP2420 has 2 McBSP ports
|
|
* OMAP2430 has 5 McBSP ports
|
|
* OMAP3 has 5 McBSP ports
|
|
* OMAP4 has 4 McBSP ports
|
|
*/
|
|
OMAP_MCBSP_PLATFORM_DEVICE(1);
|
|
OMAP_MCBSP_PLATFORM_DEVICE(2);
|
|
OMAP_MCBSP_PLATFORM_DEVICE(3);
|
|
OMAP_MCBSP_PLATFORM_DEVICE(4);
|
|
OMAP_MCBSP_PLATFORM_DEVICE(5);
|
|
|
|
static void omap_init_audio(void)
|
|
{
|
|
platform_device_register(&omap_mcbsp1);
|
|
platform_device_register(&omap_mcbsp2);
|
|
if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
|
|
platform_device_register(&omap_mcbsp3);
|
|
platform_device_register(&omap_mcbsp4);
|
|
}
|
|
if (cpu_is_omap243x() || cpu_is_omap34xx())
|
|
platform_device_register(&omap_mcbsp5);
|
|
|
|
platform_device_register(&omap_pcm);
|
|
}
|
|
|
|
#else
|
|
static inline void omap_init_audio(void) {}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
|
|
|
|
#include <plat/mcspi.h>
|
|
|
|
#define OMAP2_MCSPI1_BASE 0x48098000
|
|
#define OMAP2_MCSPI2_BASE 0x4809a000
|
|
#define OMAP2_MCSPI3_BASE 0x480b8000
|
|
#define OMAP2_MCSPI4_BASE 0x480ba000
|
|
|
|
#define OMAP4_MCSPI1_BASE 0x48098100
|
|
#define OMAP4_MCSPI2_BASE 0x4809a100
|
|
#define OMAP4_MCSPI3_BASE 0x480b8100
|
|
#define OMAP4_MCSPI4_BASE 0x480ba100
|
|
|
|
static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
|
|
.num_cs = 4,
|
|
};
|
|
|
|
static struct resource omap2_mcspi1_resources[] = {
|
|
{
|
|
.start = OMAP2_MCSPI1_BASE,
|
|
.end = OMAP2_MCSPI1_BASE + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
|
|
static struct platform_device omap2_mcspi1 = {
|
|
.name = "omap2_mcspi",
|
|
.id = 1,
|
|
.num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
|
|
.resource = omap2_mcspi1_resources,
|
|
.dev = {
|
|
.platform_data = &omap2_mcspi1_config,
|
|
},
|
|
};
|
|
|
|
static struct omap2_mcspi_platform_config omap2_mcspi2_config = {
|
|
.num_cs = 2,
|
|
};
|
|
|
|
static struct resource omap2_mcspi2_resources[] = {
|
|
{
|
|
.start = OMAP2_MCSPI2_BASE,
|
|
.end = OMAP2_MCSPI2_BASE + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
|
|
static struct platform_device omap2_mcspi2 = {
|
|
.name = "omap2_mcspi",
|
|
.id = 2,
|
|
.num_resources = ARRAY_SIZE(omap2_mcspi2_resources),
|
|
.resource = omap2_mcspi2_resources,
|
|
.dev = {
|
|
.platform_data = &omap2_mcspi2_config,
|
|
},
|
|
};
|
|
|
|
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
|
|
defined(CONFIG_ARCH_OMAP4)
|
|
static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
|
|
.num_cs = 2,
|
|
};
|
|
|
|
static struct resource omap2_mcspi3_resources[] = {
|
|
{
|
|
.start = OMAP2_MCSPI3_BASE,
|
|
.end = OMAP2_MCSPI3_BASE + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
|
|
static struct platform_device omap2_mcspi3 = {
|
|
.name = "omap2_mcspi",
|
|
.id = 3,
|
|
.num_resources = ARRAY_SIZE(omap2_mcspi3_resources),
|
|
.resource = omap2_mcspi3_resources,
|
|
.dev = {
|
|
.platform_data = &omap2_mcspi3_config,
|
|
},
|
|
};
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
|
static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
|
|
.num_cs = 1,
|
|
};
|
|
|
|
static struct resource omap2_mcspi4_resources[] = {
|
|
{
|
|
.start = OMAP2_MCSPI4_BASE,
|
|
.end = OMAP2_MCSPI4_BASE + 0xff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
|
|
static struct platform_device omap2_mcspi4 = {
|
|
.name = "omap2_mcspi",
|
|
.id = 4,
|
|
.num_resources = ARRAY_SIZE(omap2_mcspi4_resources),
|
|
.resource = omap2_mcspi4_resources,
|
|
.dev = {
|
|
.platform_data = &omap2_mcspi4_config,
|
|
},
|
|
};
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_OMAP4
|
|
static inline void omap4_mcspi_fixup(void)
|
|
{
|
|
omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE;
|
|
omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff;
|
|
omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE;
|
|
omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff;
|
|
omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE;
|
|
omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff;
|
|
omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE;
|
|
omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff;
|
|
}
|
|
#else
|
|
static inline void omap4_mcspi_fixup(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
|
|
defined(CONFIG_ARCH_OMAP4)
|
|
static inline void omap2_mcspi3_init(void)
|
|
{
|
|
platform_device_register(&omap2_mcspi3);
|
|
}
|
|
#else
|
|
static inline void omap2_mcspi3_init(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
|
static inline void omap2_mcspi4_init(void)
|
|
{
|
|
platform_device_register(&omap2_mcspi4);
|
|
}
|
|
#else
|
|
static inline void omap2_mcspi4_init(void)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
static void omap_init_mcspi(void)
|
|
{
|
|
if (cpu_is_omap44xx())
|
|
omap4_mcspi_fixup();
|
|
|
|
platform_device_register(&omap2_mcspi1);
|
|
platform_device_register(&omap2_mcspi2);
|
|
|
|
if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx())
|
|
omap2_mcspi3_init();
|
|
|
|
if (cpu_is_omap343x() || cpu_is_omap44xx())
|
|
omap2_mcspi4_init();
|
|
}
|
|
|
|
#else
|
|
static inline void omap_init_mcspi(void) {}
|
|
#endif
|
|
|
|
static struct resource omap2_pmu_resource = {
|
|
.start = 3,
|
|
.end = 3,
|
|
.flags = IORESOURCE_IRQ,
|
|
};
|
|
|
|
static struct resource omap3_pmu_resource = {
|
|
.start = INT_34XX_BENCH_MPU_EMUL,
|
|
.end = INT_34XX_BENCH_MPU_EMUL,
|
|
.flags = IORESOURCE_IRQ,
|
|
};
|
|
|
|
static struct platform_device omap_pmu_device = {
|
|
.name = "arm-pmu",
|
|
.id = ARM_PMU_DEVICE_CPU,
|
|
.num_resources = 1,
|
|
};
|
|
|
|
static void omap_init_pmu(void)
|
|
{
|
|
if (cpu_is_omap24xx())
|
|
omap_pmu_device.resource = &omap2_pmu_resource;
|
|
else if (cpu_is_omap34xx())
|
|
omap_pmu_device.resource = &omap3_pmu_resource;
|
|
else
|
|
return;
|
|
|
|
platform_device_register(&omap_pmu_device);
|
|
}
|
|
|
|
|
|
#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
|
|
|
|
#ifdef CONFIG_ARCH_OMAP2
|
|
static struct resource omap2_sham_resources[] = {
|
|
{
|
|
.start = OMAP24XX_SEC_SHA1MD5_BASE,
|
|
.end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_SHA1MD5,
|
|
.flags = IORESOURCE_IRQ,
|
|
}
|
|
};
|
|
static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources);
|
|
#else
|
|
#define omap2_sham_resources NULL
|
|
#define omap2_sham_resources_sz 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_OMAP3
|
|
static struct resource omap3_sham_resources[] = {
|
|
{
|
|
.start = OMAP34XX_SEC_SHA1MD5_BASE,
|
|
.end = OMAP34XX_SEC_SHA1MD5_BASE + 0x64,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_34XX_SHA1MD52_IRQ,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = OMAP34XX_DMA_SHA1MD5_RX,
|
|
.flags = IORESOURCE_DMA,
|
|
}
|
|
};
|
|
static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources);
|
|
#else
|
|
#define omap3_sham_resources NULL
|
|
#define omap3_sham_resources_sz 0
|
|
#endif
|
|
|
|
static struct platform_device sham_device = {
|
|
.name = "omap-sham",
|
|
.id = -1,
|
|
};
|
|
|
|
static void omap_init_sham(void)
|
|
{
|
|
if (cpu_is_omap24xx()) {
|
|
sham_device.resource = omap2_sham_resources;
|
|
sham_device.num_resources = omap2_sham_resources_sz;
|
|
} else if (cpu_is_omap34xx()) {
|
|
sham_device.resource = omap3_sham_resources;
|
|
sham_device.num_resources = omap3_sham_resources_sz;
|
|
} else {
|
|
pr_err("%s: platform not supported\n", __func__);
|
|
return;
|
|
}
|
|
platform_device_register(&sham_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_sham(void) { }
|
|
#endif
|
|
|
|
#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
|
|
|
|
#ifdef CONFIG_ARCH_OMAP2
|
|
static struct resource omap2_aes_resources[] = {
|
|
{
|
|
.start = OMAP24XX_SEC_AES_BASE,
|
|
.end = OMAP24XX_SEC_AES_BASE + 0x4C,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP24XX_DMA_AES_TX,
|
|
.flags = IORESOURCE_DMA,
|
|
},
|
|
{
|
|
.start = OMAP24XX_DMA_AES_RX,
|
|
.flags = IORESOURCE_DMA,
|
|
}
|
|
};
|
|
static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
|
|
#else
|
|
#define omap2_aes_resources NULL
|
|
#define omap2_aes_resources_sz 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_OMAP3
|
|
static struct resource omap3_aes_resources[] = {
|
|
{
|
|
.start = OMAP34XX_SEC_AES_BASE,
|
|
.end = OMAP34XX_SEC_AES_BASE + 0x4C,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP34XX_DMA_AES2_TX,
|
|
.flags = IORESOURCE_DMA,
|
|
},
|
|
{
|
|
.start = OMAP34XX_DMA_AES2_RX,
|
|
.flags = IORESOURCE_DMA,
|
|
}
|
|
};
|
|
static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
|
|
#else
|
|
#define omap3_aes_resources NULL
|
|
#define omap3_aes_resources_sz 0
|
|
#endif
|
|
|
|
static struct platform_device aes_device = {
|
|
.name = "omap-aes",
|
|
.id = -1,
|
|
};
|
|
|
|
static void omap_init_aes(void)
|
|
{
|
|
if (cpu_is_omap24xx()) {
|
|
aes_device.resource = omap2_aes_resources;
|
|
aes_device.num_resources = omap2_aes_resources_sz;
|
|
} else if (cpu_is_omap34xx()) {
|
|
aes_device.resource = omap3_aes_resources;
|
|
aes_device.num_resources = omap3_aes_resources_sz;
|
|
} else {
|
|
pr_err("%s: platform not supported\n", __func__);
|
|
return;
|
|
}
|
|
platform_device_register(&aes_device);
|
|
}
|
|
|
|
#else
|
|
static inline void omap_init_aes(void) { }
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
|
|
|
#define MMCHS_SYSCONFIG 0x0010
|
|
#define MMCHS_SYSCONFIG_SWRESET (1 << 1)
|
|
#define MMCHS_SYSSTATUS 0x0014
|
|
#define MMCHS_SYSSTATUS_RESETDONE (1 << 0)
|
|
|
|
static struct platform_device dummy_pdev = {
|
|
.dev = {
|
|
.bus = &platform_bus_type,
|
|
},
|
|
};
|
|
|
|
/**
|
|
* omap_hsmmc_reset() - Full reset of each HS-MMC controller
|
|
*
|
|
* Ensure that each MMC controller is fully reset. Controllers
|
|
* left in an unknown state (by bootloader) may prevent retention
|
|
* or OFF-mode. This is especially important in cases where the
|
|
* MMC driver is not enabled, _or_ built as a module.
|
|
*
|
|
* In order for reset to work, interface, functional and debounce
|
|
* clocks must be enabled. The debounce clock comes from func_32k_clk
|
|
* and is not under SW control, so we only enable i- and f-clocks.
|
|
**/
|
|
static void __init omap_hsmmc_reset(void)
|
|
{
|
|
u32 i, nr_controllers;
|
|
struct clk *iclk, *fclk;
|
|
|
|
if (cpu_is_omap242x())
|
|
return;
|
|
|
|
nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
|
|
(cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);
|
|
|
|
for (i = 0; i < nr_controllers; i++) {
|
|
u32 v, base = 0;
|
|
struct device *dev = &dummy_pdev.dev;
|
|
|
|
switch (i) {
|
|
case 0:
|
|
base = OMAP2_MMC1_BASE;
|
|
break;
|
|
case 1:
|
|
base = OMAP2_MMC2_BASE;
|
|
break;
|
|
case 2:
|
|
base = OMAP3_MMC3_BASE;
|
|
break;
|
|
case 3:
|
|
if (!cpu_is_omap44xx())
|
|
return;
|
|
base = OMAP4_MMC4_BASE;
|
|
break;
|
|
case 4:
|
|
if (!cpu_is_omap44xx())
|
|
return;
|
|
base = OMAP4_MMC5_BASE;
|
|
break;
|
|
}
|
|
|
|
if (cpu_is_omap44xx())
|
|
base += OMAP4_MMC_REG_OFFSET;
|
|
|
|
dummy_pdev.id = i;
|
|
dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
|
|
iclk = clk_get(dev, "ick");
|
|
if (IS_ERR(iclk))
|
|
goto err1;
|
|
if (clk_enable(iclk))
|
|
goto err2;
|
|
|
|
fclk = clk_get(dev, "fck");
|
|
if (IS_ERR(fclk))
|
|
goto err3;
|
|
if (clk_enable(fclk))
|
|
goto err4;
|
|
|
|
omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
|
|
v = omap_readl(base + MMCHS_SYSSTATUS);
|
|
while (!(omap_readl(base + MMCHS_SYSSTATUS) &
|
|
MMCHS_SYSSTATUS_RESETDONE))
|
|
cpu_relax();
|
|
|
|
clk_disable(fclk);
|
|
clk_put(fclk);
|
|
clk_disable(iclk);
|
|
clk_put(iclk);
|
|
}
|
|
return;
|
|
|
|
err4:
|
|
clk_put(fclk);
|
|
err3:
|
|
clk_disable(iclk);
|
|
err2:
|
|
clk_put(iclk);
|
|
err1:
|
|
printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, "
|
|
"cannot reset.\n", __func__, i);
|
|
}
|
|
#else
|
|
static inline void omap_hsmmc_reset(void) {}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
|
|
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
|
|
|
|
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
|
|
int controller_nr)
|
|
{
|
|
if ((mmc_controller->slots[0].switch_pin > 0) && \
|
|
(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 ((mmc_controller->slots[0].gpio_wp > 0) && \
|
|
(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_omap2420() && controller_nr == 0) {
|
|
omap_mux_init_signal("sdmmc_cmd", 0);
|
|
omap_mux_init_signal("sdmmc_clki", 0);
|
|
omap_mux_init_signal("sdmmc_clko", 0);
|
|
omap_mux_init_signal("sdmmc_dat0", 0);
|
|
omap_mux_init_signal("sdmmc_dat_dir0", 0);
|
|
omap_mux_init_signal("sdmmc_cmd_dir", 0);
|
|
if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
|
|
omap_mux_init_signal("sdmmc_dat1", 0);
|
|
omap_mux_init_signal("sdmmc_dat2", 0);
|
|
omap_mux_init_signal("sdmmc_dat3", 0);
|
|
omap_mux_init_signal("sdmmc_dat_dir1", 0);
|
|
omap_mux_init_signal("sdmmc_dat_dir2", 0);
|
|
omap_mux_init_signal("sdmmc_dat_dir3", 0);
|
|
}
|
|
|
|
/*
|
|
* Use internal loop-back in MMC/SDIO Module Input Clock
|
|
* selection
|
|
*/
|
|
if (mmc_controller->slots[0].internal_clock) {
|
|
u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
|
|
v |= (1 << 24);
|
|
omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
|
|
}
|
|
}
|
|
|
|
if (cpu_is_omap34xx()) {
|
|
if (controller_nr == 0) {
|
|
omap_mux_init_signal("sdmmc1_clk",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_cmd",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat0",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
if (mmc_controller->slots[0].caps &
|
|
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
|
|
omap_mux_init_signal("sdmmc1_dat1",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat2",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat3",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
}
|
|
if (mmc_controller->slots[0].caps &
|
|
MMC_CAP_8_BIT_DATA) {
|
|
omap_mux_init_signal("sdmmc1_dat4",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat5",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat6",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc1_dat7",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
}
|
|
}
|
|
if (controller_nr == 1) {
|
|
/* MMC2 */
|
|
omap_mux_init_signal("sdmmc2_clk",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_cmd",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat0",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
|
|
/*
|
|
* For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
|
|
* in the board-*.c files
|
|
*/
|
|
if (mmc_controller->slots[0].caps &
|
|
(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
|
|
omap_mux_init_signal("sdmmc2_dat1",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat2",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat3",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
}
|
|
if (mmc_controller->slots[0].caps &
|
|
MMC_CAP_8_BIT_DATA) {
|
|
omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
|
|
OMAP_PIN_INPUT_PULLUP);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* For MMC3 the pins need to be muxed in the board-*.c files
|
|
*/
|
|
}
|
|
}
|
|
|
|
void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
|
|
int nr_controllers)
|
|
{
|
|
int i;
|
|
char *name;
|
|
|
|
for (i = 0; i < nr_controllers; i++) {
|
|
unsigned long base, size;
|
|
unsigned int irq = 0;
|
|
|
|
if (!mmc_data[i])
|
|
continue;
|
|
|
|
omap2_mmc_mux(mmc_data[i], i);
|
|
|
|
switch (i) {
|
|
case 0:
|
|
base = OMAP2_MMC1_BASE;
|
|
irq = INT_24XX_MMC_IRQ;
|
|
break;
|
|
case 1:
|
|
base = OMAP2_MMC2_BASE;
|
|
irq = INT_24XX_MMC2_IRQ;
|
|
break;
|
|
case 2:
|
|
if (!cpu_is_omap44xx() && !cpu_is_omap34xx())
|
|
return;
|
|
base = OMAP3_MMC3_BASE;
|
|
irq = INT_34XX_MMC3_IRQ;
|
|
break;
|
|
case 3:
|
|
if (!cpu_is_omap44xx())
|
|
return;
|
|
base = OMAP4_MMC4_BASE;
|
|
irq = OMAP44XX_IRQ_MMC4;
|
|
break;
|
|
case 4:
|
|
if (!cpu_is_omap44xx())
|
|
return;
|
|
base = OMAP4_MMC5_BASE;
|
|
irq = OMAP44XX_IRQ_MMC5;
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
|
|
if (cpu_is_omap2420()) {
|
|
size = OMAP2420_MMC_SIZE;
|
|
name = "mmci-omap";
|
|
} else if (cpu_is_omap44xx()) {
|
|
if (i < 3)
|
|
irq += OMAP44XX_IRQ_GIC_START;
|
|
size = OMAP4_HSMMC_SIZE;
|
|
name = "mmci-omap-hs";
|
|
} else {
|
|
size = OMAP3_HSMMC_SIZE;
|
|
name = "mmci-omap-hs";
|
|
}
|
|
omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
|
|
};
|
|
}
|
|
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
|
|
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
|
|
#define OMAP_HDQ_BASE 0x480B2000
|
|
#endif
|
|
static struct resource omap_hdq_resources[] = {
|
|
{
|
|
.start = OMAP_HDQ_BASE,
|
|
.end = OMAP_HDQ_BASE + 0x1C,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_HDQ_IRQ,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
};
|
|
static struct platform_device omap_hdq_dev = {
|
|
.name = "omap_hdq",
|
|
.id = 0,
|
|
.dev = {
|
|
.platform_data = NULL,
|
|
},
|
|
.num_resources = ARRAY_SIZE(omap_hdq_resources),
|
|
.resource = omap_hdq_resources,
|
|
};
|
|
static inline void omap_hdq_init(void)
|
|
{
|
|
(void) platform_device_register(&omap_hdq_dev);
|
|
}
|
|
#else
|
|
static inline void omap_hdq_init(void) {}
|
|
#endif
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
|
|
defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
|
|
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
|
|
static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
|
|
};
|
|
#else
|
|
static struct resource omap_vout_resource[2] = {
|
|
};
|
|
#endif
|
|
|
|
static struct platform_device omap_vout_device = {
|
|
.name = "omap_vout",
|
|
.num_resources = ARRAY_SIZE(omap_vout_resource),
|
|
.resource = &omap_vout_resource[0],
|
|
.id = -1,
|
|
};
|
|
static void omap_init_vout(void)
|
|
{
|
|
if (platform_device_register(&omap_vout_device) < 0)
|
|
printk(KERN_ERR "Unable to register OMAP-VOUT device\n");
|
|
}
|
|
#else
|
|
static inline void omap_init_vout(void) {}
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static int __init omap2_init_devices(void)
|
|
{
|
|
/*
|
|
* please keep these calls, and their implementations above,
|
|
* in alphabetical order so they're easier to sort through.
|
|
*/
|
|
omap_hsmmc_reset();
|
|
omap_init_audio();
|
|
omap_init_camera();
|
|
omap_init_mbox();
|
|
omap_init_mcspi();
|
|
omap_init_pmu();
|
|
omap_hdq_init();
|
|
omap_init_sti();
|
|
omap_init_sham();
|
|
omap_init_aes();
|
|
omap_init_vout();
|
|
|
|
return 0;
|
|
}
|
|
arch_initcall(omap2_init_devices);
|
|
|
|
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
|
|
struct omap_device_pm_latency omap_wdt_latency[] = {
|
|
[0] = {
|
|
.deactivate_func = omap_device_idle_hwmods,
|
|
.activate_func = omap_device_enable_hwmods,
|
|
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
|
|
},
|
|
};
|
|
|
|
static int __init omap_init_wdt(void)
|
|
{
|
|
int id = -1;
|
|
struct omap_device *od;
|
|
struct omap_hwmod *oh;
|
|
char *oh_name = "wd_timer2";
|
|
char *dev_name = "omap_wdt";
|
|
|
|
if (!cpu_class_is_omap2())
|
|
return 0;
|
|
|
|
oh = omap_hwmod_lookup(oh_name);
|
|
if (!oh) {
|
|
pr_err("Could not look up wd_timer%d hwmod\n", id);
|
|
return -EINVAL;
|
|
}
|
|
|
|
od = omap_device_build(dev_name, id, oh, NULL, 0,
|
|
omap_wdt_latency,
|
|
ARRAY_SIZE(omap_wdt_latency), 0);
|
|
WARN(IS_ERR(od), "Cant build omap_device for %s:%s.\n",
|
|
dev_name, oh->name);
|
|
return 0;
|
|
}
|
|
subsys_initcall(omap_init_wdt);
|
|
#endif
|