diff options
-rw-r--r-- | arch/arm/mach-s5pv310/Kconfig | 11 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/cpu.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/dev-pd.c | 139 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/include/mach/irqs.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/include/mach/map.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/include/mach/regs-pmu.h | 30 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/irq-combiner.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/mach-smdkc210.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/mach-smdkv310.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-s5pv310/mach-universal_c210.c | 80 | ||||
-rw-r--r-- | arch/arm/plat-s5p/include/plat/map-s5p.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-samsung/include/plat/devs.h | 1 |
13 files changed, 317 insertions, 10 deletions
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 3e1fe9d..b7aa3cd 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -15,6 +15,11 @@ config CPU_S5PV310 help Enable S5PV310 CPU support +config S5PV310_DEV_PD + bool + help + Compile in platform device definitions for Power Domain + config S5PV310_SETUP_I2C1 bool help @@ -75,6 +80,7 @@ config MACH_SMDKC210 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_I2C1 select S5PV310_SETUP_SDHCI help @@ -85,6 +91,10 @@ config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CPU_S5PV310 select S5P_DEV_ONENAND + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC2 + select S3C_DEV_HSMMC3 + select S5PV310_SETUP_SDHCI select S3C_DEV_I2C1 select S5PV310_SETUP_I2C1 help @@ -105,6 +115,7 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_I2C1 select S5PV310_SETUP_SDHCI help diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 61e3cb6..e01a4d0 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -27,7 +27,9 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o # device support -obj-y += dev-audio.o +obj-y += dev-audio.o +obj-$(CONFIG_S5PV310_DEV_PD) += dev-pd.o + obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 82ce4aa..9900464 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -43,6 +43,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .length = SZ_128K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S5P_VA_PMU, + .pfn = __phys_to_pfn(S5PV310_PA_PMU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)S5P_VA_COMBINER_BASE, .pfn = __phys_to_pfn(S5PV310_PA_COMBINER), .length = SZ_4K, @@ -127,6 +132,15 @@ void __init s5pv310_init_irq(void) gic_cpu_init(0, S5P_VA_GIC_CPU); for (irq = 0; irq < MAX_COMBINER_NR; irq++) { + + /* + * From SPI(0) to SPI(39) and SPI(51), SPI(53) are + * connected to the interrupt combiner. These irqs + * should be initialized to support cascade interrupt. + */ + if ((irq >= 40) && !(irq == 51) && !(irq == 53)) + continue; + combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), COMBINER_IRQ(irq, 0)); combiner_cascade_irq(irq, IRQ_SPI(irq)); @@ -168,7 +182,7 @@ static int __init s5pv310_l2x0_cache_init(void) __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, S5P_VA_L2CC + L2X0_POWER_CTRL); - l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff); + l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); return 0; } diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c new file mode 100644 index 0000000..58a50c2 --- /dev/null +++ b/arch/arm/mach-s5pv310/dev-pd.c @@ -0,0 +1,139 @@ +/* linux/arch/arm/mach-s5pv310/dev-pd.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - Power Domain support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#include <mach/regs-pmu.h> + +#include <plat/pd.h> + +static int s5pv310_pd_enable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + u32 timeout; + + __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base); + + /* Wait max 1ms */ + timeout = 10; + while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s enable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + + return 0; +} + +static int s5pv310_pd_disable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + u32 timeout; + + __raw_writel(0, pdata->base); + + /* Wait max 1ms */ + timeout = 10; + while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s disable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + + return 0; +} + +struct platform_device s5pv310_device_pd[] = { + { + .name = "samsung-pd", + .id = 0, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_MFC_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 1, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_G3D_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 2, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_LCD0_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 3, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_LCD1_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 4, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_TV_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 5, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_CAM_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 6, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_GPS_CONF, + }, + }, + }, +}; diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 34f2144..1dd130a 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h @@ -25,6 +25,8 @@ #define IRQ_SPI(x) S5P_IRQ(x+32) +#define IRQ_MCT1 IRQ_SPI(35) + #define IRQ_EINT0 IRQ_SPI(40) #define IRQ_EINT1 IRQ_SPI(41) #define IRQ_EINT2 IRQ_SPI(42) @@ -36,9 +38,8 @@ #define IRQ_JPEG IRQ_SPI(48) #define IRQ_2D IRQ_SPI(49) #define IRQ_PCIE IRQ_SPI(50) -#define IRQ_SYSTEM_TIMER IRQ_SPI(51) +#define IRQ_MCT0 IRQ_SPI(51) #define IRQ_MFC IRQ_SPI(52) -#define IRQ_WDT IRQ_SPI(53) #define IRQ_AUDIO_SS IRQ_SPI(54) #define IRQ_AC97 IRQ_SPI(55) #define IRQ_SPDIF IRQ_SPI(56) @@ -91,6 +92,8 @@ #define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) +#define IRQ_MCT_L1 COMBINER_IRQ(35, 3) + #define IRQ_EINT4 COMBINER_IRQ(37, 0) #define IRQ_EINT5 COMBINER_IRQ(37, 1) #define IRQ_EINT6 COMBINER_IRQ(37, 2) @@ -107,7 +110,11 @@ #define IRQ_EINT16_31 COMBINER_IRQ(39, 0) -#define MAX_COMBINER_NR 40 +#define IRQ_MCT_L0 COMBINER_IRQ(51, 0) + +#define IRQ_WDT COMBINER_IRQ(53, 0) + +#define MAX_COMBINER_NR 54 #define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 0d0e7eb..44af3e8 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -39,6 +39,8 @@ #define S5PV310_PA_SYSCON (0x10010000) #define S5P_PA_SYSCON S5PV310_PA_SYSCON +#define S5PV310_PA_PMU (0x10020000) + #define S5PV310_PA_CMU (0x10030000) #define S5PV310_PA_WATCHDOG (0x10060000) diff --git a/arch/arm/mach-s5pv310/include/mach/regs-pmu.h b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h new file mode 100644 index 0000000..fb333d0 --- /dev/null +++ b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h @@ -0,0 +1,30 @@ +/* linux/arch/arm/mach-s5pv310/include/mach/regs-pmu.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - Power management unit definition + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_REGS_PMU_H +#define __ASM_ARCH_REGS_PMU_H __FILE__ + +#include <mach/map.h> + +#define S5P_PMUREG(x) (S5P_VA_PMU + (x)) + +#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00) +#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20) +#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40) +#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60) +#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80) +#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0) +#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0) + +#define S5P_INT_LOCAL_PWR_EN 0x7 + +#endif /* __ASM_ARCH_REGS_PMU_H */ diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c index c3f88c3..aad5c3d 100644 --- a/arch/arm/mach-s5pv310/irq-combiner.c +++ b/arch/arm/mach-s5pv310/irq-combiner.c @@ -24,6 +24,7 @@ static DEFINE_SPINLOCK(irq_controller_lock); struct combiner_chip_data { unsigned int irq_offset; + unsigned int irq_mask; void __iomem *base; }; @@ -62,6 +63,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) spin_lock(&irq_controller_lock); status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); spin_unlock(&irq_controller_lock); + status &= chip_data->irq_mask; if (status == 0) goto out; @@ -104,10 +106,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base, combiner_data[combiner_nr].base = base; combiner_data[combiner_nr].irq_offset = irq_start; + combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); /* Disable all interrupts */ - __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR); + __raw_writel(combiner_data[combiner_nr].irq_mask, + base + COMBINER_ENABLE_CLEAR); /* Setup the Linux IRQ subsystem */ diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c index f3bc283..9262966 100644 --- a/arch/arm/mach-s5pv310/mach-smdkc210.c +++ b/arch/arm/mach-s5pv310/mach-smdkc210.c @@ -26,6 +26,7 @@ #include <plat/devs.h> #include <plat/sdhci.h> #include <plat/iic.h> +#include <plat/pd.h> #include <mach/map.h> @@ -146,16 +147,23 @@ static struct i2c_board_info i2c_devs1[] __initdata = { }; static struct platform_device *smdkc210_devices[] __initdata = { - &s3c_device_i2c1, &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_hsmmc2, &s3c_device_hsmmc3, + &s3c_device_i2c1, &s3c_device_rtc, &s3c_device_wdt, - &smdkc210_smsc911x, &s5pv310_device_ac97, &s5pv310_device_i2s0, + &s5pv310_device_pd[PD_MFC], + &s5pv310_device_pd[PD_G3D], + &s5pv310_device_pd[PD_LCD0], + &s5pv310_device_pd[PD_LCD1], + &s5pv310_device_pd[PD_CAM], + &s5pv310_device_pd[PD_TV], + &s5pv310_device_pd[PD_GPS], + &smdkc210_smsc911x, }; static void __init smdkc210_smsc911x_init(void) diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c index e4a826a..3eb029c 100644 --- a/arch/arm/mach-s5pv310/mach-smdkv310.c +++ b/arch/arm/mach-s5pv310/mach-smdkv310.c @@ -26,6 +26,7 @@ #include <plat/devs.h> #include <plat/sdhci.h> #include <plat/iic.h> +#include <plat/pd.h> #include <mach/map.h> @@ -146,16 +147,23 @@ static struct i2c_board_info i2c_devs1[] __initdata = { }; static struct platform_device *smdkv310_devices[] __initdata = { - &s3c_device_i2c1, &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_hsmmc2, &s3c_device_hsmmc3, + &s3c_device_i2c1, &s3c_device_rtc, &s3c_device_wdt, - &smdkv310_smsc911x, &s5pv310_device_ac97, &s5pv310_device_i2s0, + &s5pv310_device_pd[PD_MFC], + &s5pv310_device_pd[PD_G3D], + &s5pv310_device_pd[PD_LCD0], + &s5pv310_device_pd[PD_LCD1], + &s5pv310_device_pd[PD_CAM], + &s5pv310_device_pd[PD_TV], + &s5pv310_device_pd[PD_GPS], + &smdkv310_smsc911x, }; static void __init smdkv310_smsc911x_init(void) diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c index 16d8fc0..36bc3cf 100644 --- a/arch/arm/mach-s5pv310/mach-universal_c210.c +++ b/arch/arm/mach-s5pv310/mach-universal_c210.c @@ -13,6 +13,9 @@ #include <linux/i2c.h> #include <linux/gpio_keys.h> #include <linux/gpio.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/mmc/host.h> #include <asm/mach/arch.h> #include <asm/mach-types.h> @@ -21,6 +24,7 @@ #include <plat/s5pv310.h> #include <plat/cpu.h> #include <plat/devs.h> +#include <plat/sdhci.h> #include <mach/map.h> @@ -116,6 +120,73 @@ static struct platform_device universal_gpio_keys = { }, }; +/* eMMC */ +static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = { + .max_width = 8, + .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE), + .cd_type = S3C_SDHCI_CD_PERMANENT, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +static struct regulator_consumer_supply mmc0_supplies[] = { + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), +}; + +static struct regulator_init_data mmc0_fixed_voltage_init_data = { + .constraints = { + .name = "VMEM_VDD_2.8V", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies), + .consumer_supplies = mmc0_supplies, +}; + +static struct fixed_voltage_config mmc0_fixed_voltage_config = { + .supply_name = "MASSMEMORY_EN", + .microvolts = 2800000, + .gpio = S5PV310_GPE1(3), + .enable_high = true, + .init_data = &mmc0_fixed_voltage_init_data, +}; + +static struct platform_device mmc0_fixed_voltage = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &mmc0_fixed_voltage_config, + }, +}; + +/* SD */ +static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = { + .max_width = 4, + .host_caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE, + .ext_cd_gpio = S5PV310_GPX3(4), /* XEINT_28 */ + .ext_cd_gpio_invert = 1, + .cd_type = S3C_SDHCI_CD_GPIO, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +/* WiFi */ +static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = { + .max_width = 4, + .host_caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE, + .cd_type = S3C_SDHCI_CD_EXTERNAL, +}; + +static void __init universal_sdhci_init(void) +{ + s3c_sdhci0_set_platdata(&universal_hsmmc0_data); + s3c_sdhci2_set_platdata(&universal_hsmmc2_data); + s3c_sdhci3_set_platdata(&universal_hsmmc3_data); +} + /* I2C0 */ static struct i2c_board_info i2c0_devs[] __initdata = { /* Camera, To be updated */ @@ -127,6 +198,13 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; static struct platform_device *universal_devices[] __initdata = { + /* Samsung Platform Devices */ + &mmc0_fixed_voltage, + &s3c_device_hsmmc0, + &s3c_device_hsmmc2, + &s3c_device_hsmmc3, + + /* Universal Devices */ &universal_gpio_keys, &s5p_device_onenand, }; @@ -140,6 +218,8 @@ static void __init universal_map_io(void) static void __init universal_machine_init(void) { + universal_sdhci_init(); + i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index fef353d..d973d39 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -15,6 +15,7 @@ #define S5P_VA_CHIPID S3C_ADDR(0x02000000) #define S5P_VA_CMU S3C_ADDR(0x02100000) +#define S5P_VA_PMU S3C_ADDR(0x02180000) #define S5P_VA_GPIO S3C_ADDR(0x02200000) #define S5P_VA_GPIO1 S5P_VA_GPIO #define S5P_VA_GPIO2 S3C_ADDR(0x02240000) diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 94794c8..165fa84 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -104,6 +104,7 @@ extern struct platform_device s5pv310_device_i2s0; extern struct platform_device s5pv310_device_i2s1; extern struct platform_device s5pv310_device_i2s2; extern struct platform_device s5pv310_device_spdif; +extern struct platform_device s5pv310_device_pd[]; extern struct platform_device s5p6442_device_pcm0; extern struct platform_device s5p6442_device_pcm1; |