mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 11:36:40 +07:00
d88746652b
This will simplify the MMC low-level init, and make it more flexible to add support for a newer MMC controller in the following patches. The patch rearranges platform data and gets rid of slot vs controller confusion in the old data structures. Also fix device id numbering in the clock code. Some code snippets are based on an earlier patch by Russell King <linux@arm.linux.org.uk>. Cc: Pierre Ossman <drzeus-mmc@drzeus.cx> Signed-off-by: Tony Lindgren <tony@atomide.com>
429 lines
9.3 KiB
C
429 lines
9.3 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/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/io.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <asm/mach-types.h>
|
|
#include <asm/mach/map.h>
|
|
|
|
#include <mach/tc.h>
|
|
#include <mach/board.h>
|
|
#include <mach/mux.h>
|
|
#include <mach/gpio.h>
|
|
#include <mach/eac.h>
|
|
#include <mach/mmc.h>
|
|
|
|
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
|
|
#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
|
|
|
|
static struct resource mbox_resources[] = {
|
|
{
|
|
.start = OMAP2_MBOX_BASE,
|
|
.end = OMAP2_MBOX_BASE + 0x11f,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_MAIL_U0_MPU,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
{
|
|
.start = INT_24XX_MAIL_U3_MPU,
|
|
.flags = IORESOURCE_IRQ,
|
|
},
|
|
};
|
|
|
|
static struct platform_device mbox_device = {
|
|
.name = "mailbox",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(mbox_resources),
|
|
.resource = mbox_resources,
|
|
};
|
|
|
|
static inline void omap_init_mbox(void)
|
|
{
|
|
platform_device_register(&mbox_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_mbox(void) { }
|
|
#endif
|
|
|
|
#if defined(CONFIG_OMAP_STI)
|
|
|
|
#if defined(CONFIG_ARCH_OMAP2)
|
|
|
|
#define OMAP2_STI_BASE 0x48068000
|
|
#define OMAP2_STI_CHANNEL_BASE 0x54000000
|
|
#define OMAP2_STI_IRQ 4
|
|
|
|
static struct resource sti_resources[] = {
|
|
{
|
|
.start = OMAP2_STI_BASE,
|
|
.end = OMAP2_STI_BASE + 0x7ff,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP2_STI_CHANNEL_BASE,
|
|
.end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP2_STI_IRQ,
|
|
.flags = IORESOURCE_IRQ,
|
|
}
|
|
};
|
|
#elif defined(CONFIG_ARCH_OMAP3)
|
|
|
|
#define OMAP3_SDTI_BASE 0x54500000
|
|
#define OMAP3_SDTI_CHANNEL_BASE 0x54600000
|
|
|
|
static struct resource sti_resources[] = {
|
|
{
|
|
.start = OMAP3_SDTI_BASE,
|
|
.end = OMAP3_SDTI_BASE + 0xFFF,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = OMAP3_SDTI_CHANNEL_BASE,
|
|
.end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1,
|
|
.flags = IORESOURCE_MEM,
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
static struct platform_device sti_device = {
|
|
.name = "sti",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(sti_resources),
|
|
.resource = sti_resources,
|
|
};
|
|
|
|
static inline void omap_init_sti(void)
|
|
{
|
|
platform_device_register(&sti_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_sti(void) {}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
|
|
|
|
#include <mach/mcspi.h>
|
|
|
|
#define OMAP2_MCSPI1_BASE 0x48098000
|
|
#define OMAP2_MCSPI2_BASE 0x4809a000
|
|
#define OMAP2_MCSPI3_BASE 0x480b8000
|
|
#define OMAP2_MCSPI4_BASE 0x480ba000
|
|
|
|
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)
|
|
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
|
|
|
|
#ifdef CONFIG_ARCH_OMAP3
|
|
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
|
|
|
|
static void omap_init_mcspi(void)
|
|
{
|
|
platform_device_register(&omap2_mcspi1);
|
|
platform_device_register(&omap2_mcspi2);
|
|
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
|
|
platform_device_register(&omap2_mcspi3);
|
|
#endif
|
|
#ifdef CONFIG_ARCH_OMAP3
|
|
platform_device_register(&omap2_mcspi4);
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
static inline void omap_init_mcspi(void) {}
|
|
#endif
|
|
|
|
#ifdef CONFIG_SND_OMAP24XX_EAC
|
|
|
|
#define OMAP2_EAC_BASE 0x48090000
|
|
|
|
static struct resource omap2_eac_resources[] = {
|
|
{
|
|
.start = OMAP2_EAC_BASE,
|
|
.end = OMAP2_EAC_BASE + 0x109,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
};
|
|
|
|
static struct platform_device omap2_eac_device = {
|
|
.name = "omap24xx-eac",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(omap2_eac_resources),
|
|
.resource = omap2_eac_resources,
|
|
.dev = {
|
|
.platform_data = NULL,
|
|
},
|
|
};
|
|
|
|
void omap_init_eac(struct eac_platform_data *pdata)
|
|
{
|
|
omap2_eac_device.dev.platform_data = pdata;
|
|
platform_device_register(&omap2_eac_device);
|
|
}
|
|
|
|
#else
|
|
void omap_init_eac(struct eac_platform_data *pdata) {}
|
|
#endif
|
|
|
|
#ifdef CONFIG_OMAP_SHA1_MD5
|
|
static struct resource sha1_md5_resources[] = {
|
|
{
|
|
.start = OMAP24XX_SEC_SHA1MD5_BASE,
|
|
.end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
|
|
.flags = IORESOURCE_MEM,
|
|
},
|
|
{
|
|
.start = INT_24XX_SHA1MD5,
|
|
.flags = IORESOURCE_IRQ,
|
|
}
|
|
};
|
|
|
|
static struct platform_device sha1_md5_device = {
|
|
.name = "OMAP SHA1/MD5",
|
|
.id = -1,
|
|
.num_resources = ARRAY_SIZE(sha1_md5_resources),
|
|
.resource = sha1_md5_resources,
|
|
};
|
|
|
|
static void omap_init_sha1_md5(void)
|
|
{
|
|
platform_device_register(&sha1_md5_device);
|
|
}
|
|
#else
|
|
static inline void omap_init_sha1_md5(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 (cpu_is_omap2420() && controller_nr == 0) {
|
|
omap_cfg_reg(H18_24XX_MMC_CMD);
|
|
omap_cfg_reg(H15_24XX_MMC_CLKI);
|
|
omap_cfg_reg(G19_24XX_MMC_CLKO);
|
|
omap_cfg_reg(F20_24XX_MMC_DAT0);
|
|
omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
|
|
omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
|
|
if (mmc_controller->slots[0].wire4) {
|
|
omap_cfg_reg(H14_24XX_MMC_DAT1);
|
|
omap_cfg_reg(E19_24XX_MMC_DAT2);
|
|
omap_cfg_reg(D19_24XX_MMC_DAT3);
|
|
omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
|
|
omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
|
|
omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
|
|
int nr_controllers)
|
|
{
|
|
int i;
|
|
|
|
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_omap34xx())
|
|
return;
|
|
base = OMAP3_MMC3_BASE;
|
|
irq = INT_34XX_MMC3_IRQ;
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
|
|
if (cpu_is_omap2420())
|
|
size = OMAP2420_MMC_SIZE;
|
|
else
|
|
size = HSMMC_SIZE;
|
|
|
|
omap_mmc_add(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
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
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_init_mbox();
|
|
omap_init_mcspi();
|
|
omap_hdq_init();
|
|
omap_init_sti();
|
|
omap_init_sha1_md5();
|
|
|
|
return 0;
|
|
}
|
|
arch_initcall(omap2_init_devices);
|