diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 1150b360f38c..3bf72a60bf53 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -14,6 +14,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 @@ -73,6 +78,7 @@ config MACH_SMDKC210 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKC210 @@ -101,6 +107,7 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKV310 diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 84afc64e7c01..e310609d6268 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -27,6 +27,9 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o # device support +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 b2a37d0f9d7a..7b6e066e2271 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -42,6 +42,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV310_PA_CMU), .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), diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c new file mode 100644 index 000000000000..58a50c2d0b67 --- /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 +#include +#include +#include + +#include + +#include + +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/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 7acf4e77e92e..a16d0c9c27bc 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 000000000000..fb333d0f6073 --- /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 + +#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/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c index 2b8d4fc52d7c..f65e668ceae9 100644 --- a/arch/arm/mach-s5pv310/mach-smdkc210.c +++ b/arch/arm/mach-s5pv310/mach-smdkc210.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,13 @@ static struct platform_device *smdkc210_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkc210_smsc911x, + &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], }; 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 35826d66632c..19aa3e3c011d 100644 --- a/arch/arm/mach-s5pv310/mach-smdkv310.c +++ b/arch/arm/mach-s5pv310/mach-smdkv310.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,13 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkv310_smsc911x, + &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], }; static void __init smdkv310_smsc911x_init(void) diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index fef353d44513..d973d39666a3 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 2d82a6cb1444..4dad6e24e970 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -122,6 +122,8 @@ extern struct platform_device s5p_device_fimc0; extern struct platform_device s5p_device_fimc1; extern struct platform_device s5p_device_fimc2; +extern struct platform_device s5pv310_device_pd[]; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440