From 13904fba37aa00867dee0b4fe13df92fed1120f9 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Fri, 27 Aug 2010 13:56:54 +0900 Subject: ARM: S5P: Move OneNAND device definitions in plat-s5p This patch moves OneNAND device definitions from mach-s5pv210 to plat-s5p so that can support it commonly. Note: S5PC110 and S5PC210 have same OneNAND driver. Signed-off-by: Kukjin Kim Cc: Kyungmin Park --- arch/arm/plat-s5p/Kconfig | 5 ++++ arch/arm/plat-s5p/Makefile | 1 + arch/arm/plat-s5p/dev-onenand.c | 57 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 arch/arm/plat-s5p/dev-onenand.c (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index c6a855db2fb6..407e3236809d 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -46,3 +46,8 @@ config S5P_DEV_FIMC2 bool help Compile in platform device definitions for FIMC controller 2 + +config S5P_DEV_ONENAND + bool + help + Compile in platform device definition for OneNAND controller diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index b2e029673950..f3e917e27da8 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o +obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o diff --git a/arch/arm/plat-s5p/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c new file mode 100644 index 000000000000..6db926202caa --- /dev/null +++ b/arch/arm/plat-s5p/dev-onenand.c @@ -0,0 +1,57 @@ +/* linux/arch/arm/plat-s5p/dev-onenand.c + * + * Copyright 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright (c) 2008-2010 Samsung Electronics + * Kyungmin Park + * + * S5P series device definition for OneNAND devices + * + * 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 struct resource s5p_onenand_resources[] = { + [0] = { + .start = S5P_PA_ONENAND, + .end = S5P_PA_ONENAND + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S5P_PA_ONENAND_DMA, + .end = S5P_PA_ONENAND_DMA + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_ONENAND_AUDI, + .end = IRQ_ONENAND_AUDI, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_onenand = { + .name = "s5pc110-onenand", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_onenand_resources), + .resource = s5p_onenand_resources, +}; + +void s5p_onenand_set_platdata(struct onenand_platform_data *pdata) +{ + struct onenand_platform_data *pd; + + pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL); + if (!pd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + s5p_device_onenand.dev.platform_data = pd; +} -- cgit v1.2.3-59-g8ed1b From 19a2c06548db1fa69c40be5bf3ad2095d6119871 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 31 Aug 2010 16:30:51 +0900 Subject: ARM: S5P: Moves initial map for merging S5P64X0 This patch moves some initial maps from plat-s5p to machine, so that can merge mach-s5p6440 and mach-s5p6450. Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6440/cpu.c | 37 ++++++++++++++++++++++++++++---- arch/arm/mach-s5p6440/include/mach/map.h | 7 +----- arch/arm/mach-s5p6442/cpu.c | 27 ++++++++++++++++++++--- arch/arm/mach-s5p6442/include/mach/map.h | 6 ------ arch/arm/mach-s5pc100/cpu.c | 25 ++++++++++++++++++++- arch/arm/mach-s5pc100/include/mach/map.h | 11 ++++------ arch/arm/mach-s5pv210/cpu.c | 22 ++++++++++++++++++- arch/arm/mach-s5pv210/include/mach/map.h | 8 ------- arch/arm/mach-s5pv310/cpu.c | 26 +++++++++++++++------- arch/arm/plat-s5p/cpu.c | 22 ------------------- 10 files changed, 125 insertions(+), 66 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c index ec592e866054..8a09e0fc2730 100644 --- a/arch/arm/mach-s5p6440/cpu.c +++ b/arch/arm/mach-s5p6440/cpu.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-s5p6440/cpu.c * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * 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 @@ -40,6 +40,32 @@ #include #include +/* Initial IO mappings */ + +static struct map_desc s5p6440_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P6440_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P6440_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P6440_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, + } +}; + static void s5p6440_idle(void) { unsigned long val; @@ -55,15 +81,18 @@ static void s5p6440_idle(void) local_irq_enable(); } -/* s5p6440_map_io +/* + * s5p6440_map_io * * register the standard cpu IO areas -*/ + */ void __init s5p6440_map_io(void) { /* initialize any device information early */ s3c_adc_setname("s3c64xx-adc"); + + iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); } void __init s5p6440_init_clocks(int xtal) diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h index 6cc5cbc88ffb..11d31fe87ccf 100644 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ b/arch/arm/mach-s5p6440/include/mach/map.h @@ -24,23 +24,18 @@ #define S5P_PA_SYSCON S5P6440_PA_SYSCON #define S5P6440_PA_GPIO (0xE0308000) -#define S5P_PA_GPIO S5P6440_PA_GPIO #define S5P6440_PA_VIC0 (0xE4000000) -#define S5P_PA_VIC0 S5P6440_PA_VIC0 +#define S5P6440_PA_VIC1 (0xE4100000) #define S5P6440_PA_PDMA 0xE9000000 -#define S5P6440_PA_VIC1 (0xE4100000) -#define S5P_PA_VIC1 S5P6440_PA_VIC1 - #define S5P6440_PA_TIMER (0xEA000000) #define S5P_PA_TIMER S5P6440_PA_TIMER #define S5P6440_PA_RTC (0xEA100000) #define S5P6440_PA_WDT (0xEA200000) -#define S5P_PA_WDT S5P6440_PA_WDT #define S5P6440_PA_UART (0xEC000000) diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c index 70ac681af72b..842af86bda6d 100644 --- a/arch/arm/mach-s5p6442/cpu.c +++ b/arch/arm/mach-s5p6442/cpu.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-s5p6442/cpu.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * http://www.samsung.com * * 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 @@ -47,11 +47,31 @@ static struct map_desc s5p6442_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5P6442_PA_SYSTIMER), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P6442_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P6442_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P6442_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC2, .pfn = __phys_to_pfn(S5P6442_PA_VIC2), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, } }; @@ -63,10 +83,11 @@ static void s5p6442_idle(void) local_irq_enable(); } -/* s5p6442_map_io +/* + * s5p6442_map_io * * register the standard cpu IO areas -*/ + */ void __init s5p6442_map_io(void) { diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h index 281d256faafb..31fb2e68d527 100644 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ b/arch/arm/mach-s5p6442/include/mach/map.h @@ -23,16 +23,10 @@ #define S5P_PA_SYSCON S5P6442_PA_SYSCON #define S5P6442_PA_GPIO (0xE0200000) -#define S5P_PA_GPIO S5P6442_PA_GPIO #define S5P6442_PA_VIC0 (0xE4000000) -#define S5P_PA_VIC0 S5P6442_PA_VIC0 - #define S5P6442_PA_VIC1 (0xE4100000) -#define S5P_PA_VIC1 S5P6442_PA_VIC1 - #define S5P6442_PA_VIC2 (0xE4200000) -#define S5P_PA_VIC2 S5P6442_PA_VIC2 #define S5P6442_PA_MDMA 0xE8000000 #define S5P6442_PA_PDMA 0xE9000000 diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c index cd1afbce83e2..fd2708e7d8a9 100644 --- a/arch/arm/mach-s5pc100/cpu.c +++ b/arch/arm/mach-s5pc100/cpu.c @@ -1,4 +1,7 @@ /* linux/arch/arm/mach-s5pc100/cpu.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Copyright 2009 Samsung Electronics Co. * Byungho Min @@ -56,11 +59,31 @@ static struct map_desc s5pc100_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PC100_PA_SYSTIMER), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PC100_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5PC100_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5PC100_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC2, - .pfn = __phys_to_pfn(S5P_PA_VIC2), + .pfn = __phys_to_pfn(S5PC100_PA_VIC2), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S5PC100_VA_OTHERS, .pfn = __phys_to_pfn(S5PC100_PA_OTHERS), diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h index 01b9134feff0..8751ef4a6804 100644 --- a/arch/arm/mach-s5pc100/include/mach/map.h +++ b/arch/arm/mach-s5pc100/include/mach/map.h @@ -44,19 +44,16 @@ #define S5PC100_PA_OTHERS (0xE0200000) #define S5PC100_VA_OTHERS (S3C_VA_SYS + 0x10000) -#define S5P_PA_GPIO (0xE0300000) +#define S5PC100_PA_GPIO (0xE0300000) #define S5PC1XX_VA_GPIO S3C_ADDR(0x00500000) /* Interrupt */ -#define S5PC100_PA_VIC (0xE4000000) +#define S5PC100_PA_VIC0 (0xE4000000) +#define S5PC100_PA_VIC1 (0xE4100000) +#define S5PC100_PA_VIC2 (0xE4200000) #define S5PC100_VA_VIC S3C_VA_IRQ -#define S5PC100_PA_VIC_OFFSET 0x100000 #define S5PC100_VA_VIC_OFFSET 0x10000 -#define S5PC1XX_PA_VIC(x) (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET)) #define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET)) -#define S5P_PA_VIC0 S5PC1XX_PA_VIC(0) -#define S5P_PA_VIC1 S5PC1XX_PA_VIC(1) -#define S5P_PA_VIC2 S5PC1XX_PA_VIC(2) #define S5PC100_PA_ONENAND (0xE7100000) diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 245b82b53df4..2f16bfc0a116 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-s5pv210/cpu.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * http://www.samsung.com * * 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 @@ -50,6 +50,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PV210_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5PV210_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5PV210_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC2, .pfn = __phys_to_pfn(S5PV210_PA_VIC2), @@ -60,6 +75,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV210_PA_VIC3), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_SROMC, .pfn = __phys_to_pfn(S5PV210_PA_SROMC), diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index aa19d2f8dadb..bd9afd52466a 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -29,7 +29,6 @@ #define S5P_PA_SYSCON S5PV210_PA_SYSCON #define S5PV210_PA_GPIO (0xE0200000) -#define S5P_PA_GPIO S5PV210_PA_GPIO /* SPI */ #define S5PV210_PA_SPI0 0xE1300000 @@ -75,16 +74,9 @@ #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) #define S5PV210_PA_VIC0 (0xF2000000) -#define S5P_PA_VIC0 S5PV210_PA_VIC0 - #define S5PV210_PA_VIC1 (0xF2100000) -#define S5P_PA_VIC1 S5PV210_PA_VIC1 - #define S5PV210_PA_VIC2 (0xF2200000) -#define S5P_PA_VIC2 S5PV210_PA_VIC2 - #define S5PV210_PA_VIC3 (0xF2300000) -#define S5P_PA_VIC3 S5PV210_PA_VIC3 #define S5PV210_PA_SDRAM (0x20000000) #define S5P_PA_SDRAM S5PV210_PA_SDRAM diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index e5b261a99ab2..3b9c872ed68d 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -31,29 +31,39 @@ extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); /* Initial IO mappings */ static struct map_desc s5pv310_iodesc[] __initdata = { { - .virtual = (unsigned long)S5P_VA_COREPERI_BASE, - .pfn = __phys_to_pfn(S5PV310_PA_COREPERI), - .length = SZ_8K, + .virtual = (unsigned long)S5P_VA_SYSRAM, + .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_CMU, + .pfn = __phys_to_pfn(S5PV310_PA_CMU), + .length = SZ_128K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_COMBINER_BASE, .pfn = __phys_to_pfn(S5PV310_PA_COMBINER), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_COREPERI_BASE, + .pfn = __phys_to_pfn(S5PV310_PA_COREPERI), + .length = SZ_8K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_L2CC, .pfn = __phys_to_pfn(S5PV310_PA_L2CC), .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_SYSRAM, - .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PV310_PA_GPIO), .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_CMU, - .pfn = __phys_to_pfn(S5PV310_PA_CMU), - .length = SZ_128K, + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, .type = MT_DEVICE, }, }; diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index b07a078fd284..57f08eee6d62 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c @@ -88,33 +88,11 @@ static struct map_desc s5p_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5P_PA_SYSCON), .length = SZ_64K, .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_UART, - .pfn = __phys_to_pfn(S3C_PA_UART), - .length = SZ_512K, - .type = MT_DEVICE, -#ifdef CONFIG_ARM_VIC - }, { - .virtual = (unsigned long)VA_VIC0, - .pfn = __phys_to_pfn(S5P_PA_VIC0), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC1, - .pfn = __phys_to_pfn(S5P_PA_VIC1), - .length = SZ_16K, - .type = MT_DEVICE, -#endif }, { .virtual = (unsigned long)S3C_VA_TIMER, .pfn = __phys_to_pfn(S5P_PA_TIMER), .length = SZ_16K, .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO, - .pfn = __phys_to_pfn(S5P_PA_GPIO), - .length = SZ_4K, - .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_WATCHDOG, .pfn = __phys_to_pfn(S3C_PA_WDT), -- cgit v1.2.3-59-g8ed1b From 49b7a491b797305a0dc373e7f7a5d2a87955c819 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 7 Sep 2010 15:47:18 +0900 Subject: ARM: S5P64X0: Update Kconfig and Makefile This patch updates the Kconfig and Makefile for the S5P6440 and S5P6450 machines. It also updates arch/arm/ Kconfig and Makefile to include for support ARCH_S5P64X0 with one kernel image. Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 11 +++---- arch/arm/Makefile | 2 +- arch/arm/mach-s5p6440/Kconfig | 33 --------------------- arch/arm/mach-s5p6440/Makefile | 25 ---------------- arch/arm/mach-s5p6440/Makefile.boot | 2 -- arch/arm/mach-s5p64x0/Kconfig | 57 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-s5p64x0/Makefile | 30 +++++++++++++++++++ arch/arm/mach-s5p64x0/Makefile.boot | 2 ++ arch/arm/plat-s5p/Kconfig | 4 +-- 9 files changed, 98 insertions(+), 68 deletions(-) delete mode 100644 arch/arm/mach-s5p6440/Kconfig delete mode 100644 arch/arm/mach-s5p6440/Makefile delete mode 100644 arch/arm/mach-s5p6440/Makefile.boot create mode 100644 arch/arm/mach-s5p64x0/Kconfig create mode 100644 arch/arm/mach-s5p64x0/Makefile create mode 100644 arch/arm/mach-s5p64x0/Makefile.boot (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9c26ba7244fb..e4b74fbdba0a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -678,8 +678,8 @@ config ARCH_S3C64XX help Samsung S3C64XX series based systems -config ARCH_S5P6440 - bool "Samsung S5P6440" +config ARCH_S5P64X0 + bool "Samsung S5P6440 S5P6450" select CPU_V6 select GENERIC_GPIO select HAVE_CLK @@ -688,7 +688,8 @@ config ARCH_S5P6440 select HAVE_S3C2410_I2C select HAVE_S3C_RTC help - Samsung S5P6440 CPU based systems + Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, + SMDK6450. config ARCH_S5P6442 bool "Samsung S5P6442" @@ -928,7 +929,7 @@ if ARCH_S3C64XX source "arch/arm/mach-s3c64xx/Kconfig" endif -source "arch/arm/mach-s5p6440/Kconfig" +source "arch/arm/mach-s5p64x0/Kconfig" source "arch/arm/mach-s5p6442/Kconfig" @@ -1271,7 +1272,7 @@ source kernel/Kconfig.preempt config HZ int - default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || \ + default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER default AT91_TIMER_HZ if ARCH_AT91 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 59c1ce858fc8..8420f21571da 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -173,7 +173,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx -machine-$(CONFIG_ARCH_S5P6440) := s5p6440 +machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 machine-$(CONFIG_ARCH_S5P6442) := s5p6442 machine-$(CONFIG_ARCH_S5PC100) := s5pc100 machine-$(CONFIG_ARCH_S5PV210) := s5pv210 diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig deleted file mode 100644 index 6a4af7f57584..000000000000 --- a/arch/arm/mach-s5p6440/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -# arch/arm/mach-s5p6440/Kconfig -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -if ARCH_S5P6440 - -config CPU_S5P6440 - bool - select S3C_PL330_DMA - help - Enable S5P6440 CPU support - -config S5P6440_SETUP_I2C1 - bool - help - Common setup code for i2c bus 1. - -config MACH_SMDK6440 - bool "SMDK6440" - select CPU_S5P6440 - select S3C_DEV_I2C1 - select S3C_DEV_RTC - select S3C_DEV_WDT - select SAMSUNG_DEV_ADC - select SAMSUNG_DEV_TS - select S5P6440_SETUP_I2C1 - help - Machine support for the Samsung SMDK6440 - -endif diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile deleted file mode 100644 index c3fe4d3662a9..000000000000 --- a/arch/arm/mach-s5p6440/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# arch/arm/mach-s5p6440/Makefile -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -# Core support for S5P6440 system - -obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o -obj-$(CONFIG_CPU_S5P6440) += setup-i2c0.o - -# machine support - -obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o - -# device support -obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o -obj-$(CONFIG_S5P6440_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-s5p6440/Makefile.boot b/arch/arm/mach-s5p6440/Makefile.boot deleted file mode 100644 index ff90aa13bd67..000000000000 --- a/arch/arm/mach-s5p6440/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y := 0x20008000 -params_phys-y := 0x20000100 diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig new file mode 100644 index 000000000000..fbcae9352022 --- /dev/null +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -0,0 +1,57 @@ +# arch/arm/mach-s5p64x0/Kconfig +# +# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +if ARCH_S5P64X0 + +config CPU_S5P6440 + bool + select PLAT_S5P + select S3C_PL330_DMA + help + Enable S5P6440 CPU support + +config CPU_S5P6450 + bool + select PLAT_S5P + select S3C_PL330_DMA + help + Enable S5P6450 CPU support + +config S5P64X0_SETUP_I2C1 + bool + help + Common setup code for i2c bus 1. + +# machine support + +config MACH_SMDK6440 + bool "SMDK6440" + select CPU_S5P6440 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_WDT + select S3C64XX_DEV_SPI + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + select S5P64X0_SETUP_I2C1 + help + Machine support for the Samsung SMDK6440 + +config MACH_SMDK6450 + bool "SMDK6450" + select CPU_S5P6450 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_WDT + select S3C64XX_DEV_SPI + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + select S5P64X0_SETUP_I2C1 + help + Machine support for the Samsung SMDK6450 + +endif diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile new file mode 100644 index 000000000000..2655829e6bf8 --- /dev/null +++ b/arch/arm/mach-s5p64x0/Makefile @@ -0,0 +1,30 @@ +# arch/arm/mach-s5p64x0/Makefile +# +# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. +# http://www.samsung.com +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +# Core support for S5P64X0 system + +obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o +obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o +obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o +obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o + +# machine support + +obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o +obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o + +# device support + +obj-y += dev-audio.o +obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o + +obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-s5p64x0/Makefile.boot b/arch/arm/mach-s5p64x0/Makefile.boot new file mode 100644 index 000000000000..ff90aa13bd67 --- /dev/null +++ b/arch/arm/mach-s5p64x0/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0x20008000 +params_phys-y := 0x20000100 diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 407e3236809d..25960966af7c 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -7,7 +7,7 @@ config PLAT_S5P bool - depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310) + depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310) default y select ARM_VIC if !ARCH_S5PV310 select ARM_GIC if ARCH_S5PV310 @@ -30,7 +30,7 @@ config S5P_EXT_INT bool help Use the external interrupts (other than GPIO interrupts.) - Note: Do not choose this for S5P6440. + Note: Do not choose this for S5P6440 and S5P6450. config S5P_DEV_FIMC0 bool -- cgit v1.2.3-59-g8ed1b From a2e0d6249fa866ce7f5a8fe08a4d75511e4701c6 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Mon, 18 Oct 2010 18:29:51 +0900 Subject: ARM: S5P64X0: Add S5P64X0(S5P6440 and S5P6450) initialization support This patch adds ARCH_S5P64X0 which can support S5P6440 and S5P6450 with one kernel image. So moved some files of mach-s5p6440 into the new ARCH directory mach-s5p64x0. Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6440/cpu.c | 146 ---------------- arch/arm/mach-s5p6440/include/mach/debug-macro.S | 37 ---- arch/arm/mach-s5p6440/include/mach/entry-macro.S | 16 -- arch/arm/mach-s5p6440/include/mach/hardware.h | 18 -- arch/arm/mach-s5p6440/include/mach/io.h | 18 -- arch/arm/mach-s5p6440/include/mach/map.h | 81 --------- arch/arm/mach-s5p6440/include/mach/memory.h | 19 -- arch/arm/mach-s5p6440/include/mach/system.h | 23 --- arch/arm/mach-s5p6440/include/mach/timex.h | 24 --- arch/arm/mach-s5p6440/include/mach/uncompress.h | 24 --- arch/arm/mach-s5p6440/include/mach/vmalloc.h | 17 -- arch/arm/mach-s5p6440/init.c | 52 ------ arch/arm/mach-s5p64x0/cpu.c | 208 ++++++++++++++++++++++ arch/arm/mach-s5p64x0/include/mach/debug-macro.S | 33 ++++ arch/arm/mach-s5p64x0/include/mach/entry-macro.S | 16 ++ arch/arm/mach-s5p64x0/include/mach/hardware.h | 18 ++ arch/arm/mach-s5p64x0/include/mach/io.h | 25 +++ arch/arm/mach-s5p64x0/include/mach/map.h | 83 +++++++++ arch/arm/mach-s5p64x0/include/mach/memory.h | 19 ++ arch/arm/mach-s5p64x0/include/mach/system.h | 23 +++ arch/arm/mach-s5p64x0/include/mach/timex.h | 27 +++ arch/arm/mach-s5p64x0/include/mach/uncompress.h | 212 +++++++++++++++++++++++ arch/arm/mach-s5p64x0/include/mach/vmalloc.h | 20 +++ arch/arm/mach-s5p64x0/init.c | 73 ++++++++ arch/arm/plat-s5p/cpu.c | 12 +- arch/arm/plat-s5p/include/plat/s5p6440.h | 7 +- arch/arm/plat-s5p/include/plat/s5p6450.h | 36 ++++ 27 files changed, 807 insertions(+), 480 deletions(-) delete mode 100644 arch/arm/mach-s5p6440/cpu.c delete mode 100644 arch/arm/mach-s5p6440/include/mach/debug-macro.S delete mode 100644 arch/arm/mach-s5p6440/include/mach/entry-macro.S delete mode 100644 arch/arm/mach-s5p6440/include/mach/hardware.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/io.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/map.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/memory.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/system.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/timex.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/uncompress.h delete mode 100644 arch/arm/mach-s5p6440/include/mach/vmalloc.h delete mode 100644 arch/arm/mach-s5p6440/init.c create mode 100644 arch/arm/mach-s5p64x0/cpu.c create mode 100644 arch/arm/mach-s5p64x0/include/mach/debug-macro.S create mode 100644 arch/arm/mach-s5p64x0/include/mach/entry-macro.S create mode 100644 arch/arm/mach-s5p64x0/include/mach/hardware.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/io.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/map.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/memory.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/system.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/timex.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/uncompress.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/vmalloc.h create mode 100644 arch/arm/mach-s5p64x0/init.c create mode 100644 arch/arm/plat-s5p/include/plat/s5p6450.h (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c deleted file mode 100644 index 8a09e0fc2730..000000000000 --- a/arch/arm/mach-s5p6440/cpu.c +++ /dev/null @@ -1,146 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/cpu.c - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -/* Initial IO mappings */ - -static struct map_desc s5p6440_iodesc[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_GPIO, - .pfn = __phys_to_pfn(S5P6440_PA_GPIO), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC0, - .pfn = __phys_to_pfn(S5P6440_PA_VIC0), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC1, - .pfn = __phys_to_pfn(S5P6440_PA_VIC1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_UART, - .pfn = __phys_to_pfn(S3C_PA_UART), - .length = SZ_512K, - .type = MT_DEVICE, - } -}; - -static void s5p6440_idle(void) -{ - unsigned long val; - - if (!need_resched()) { - val = __raw_readl(S5P_PWR_CFG); - val &= ~(0x3<<5); - val |= (0x1<<5); - __raw_writel(val, S5P_PWR_CFG); - - cpu_do_idle(); - } - local_irq_enable(); -} - -/* - * s5p6440_map_io - * - * register the standard cpu IO areas - */ - -void __init s5p6440_map_io(void) -{ - /* initialize any device information early */ - s3c_adc_setname("s3c64xx-adc"); - - iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); -} - -void __init s5p6440_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - - s3c24xx_register_baseclocks(xtal); - s5p_register_clocks(xtal); - s5p6440_register_clocks(); - s5p6440_setup_clocks(); -} - -void __init s5p6440_init_irq(void) -{ - /* S5P6440 supports only 2 VIC */ - u32 vic[2]; - - /* - * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] - * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] - */ - vic[0] = 0xff800ae7; - vic[1] = 0xffbf23e5; - - s5p_init_irq(vic, ARRAY_SIZE(vic)); -} - -struct sysdev_class s5p6440_sysclass = { - .name = "s5p6440-core", -}; - -static struct sys_device s5p6440_sysdev = { - .cls = &s5p6440_sysclass, -}; - -static int __init s5p6440_core_init(void) -{ - return sysdev_class_register(&s5p6440_sysclass); -} - -core_initcall(s5p6440_core_init); - -int __init s5p6440_init(void) -{ - printk(KERN_INFO "S5P6440: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5p6440_idle; - - return sysdev_register(&s5p6440_sysdev); -} diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S deleted file mode 100644 index 1347d7f99079..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/debug-macro.S +++ /dev/null @@ -1,37 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * 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. -*/ - -/* pull in the relevant register and map files. */ - -#include -#include - - /* note, for the boot process to work we have to keep the UART - * virtual address aligned to an 1MiB boundary for the L1 - * mapping the head code makes. We keep the UART virtual address - * aligned and add in the offset when we load the value here. - */ - - .macro addruart, rx, rtmp - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 - ldreq \rx, = S3C_PA_UART - ldrne \rx, = S3C_VA_UART -#if CONFIG_DEBUG_S3C_UART != 0 - add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART) -#endif - .endm - -/* include the reset of the code which will do the work, we're only - * compiling for a single cpu processor type so the default of s3c2440 - * will be fine with us. - */ - -#include diff --git a/arch/arm/mach-s5p6440/include/mach/entry-macro.S b/arch/arm/mach-s5p6440/include/mach/entry-macro.S deleted file mode 100644 index e65f1b967262..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Low-level IRQ helper macros for the Samsung S5P6440 - * - * 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 diff --git a/arch/arm/mach-s5p6440/include/mach/hardware.h b/arch/arm/mach-s5p6440/include/mach/hardware.h deleted file mode 100644 index be8b26e875db..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/hardware.h +++ /dev/null @@ -1,18 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Hardware 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. -*/ - -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H __FILE__ - -/* currently nothing here, placeholder */ - -#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/io.h b/arch/arm/mach-s5p6440/include/mach/io.h deleted file mode 100644 index fa2d69cb1ad7..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s5p6440/include/mach/io.h - * - * Copyright 2008 Simtec Electronics - * Ben Dooks - * - * Default IO routines for S3C64XX based - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h deleted file mode 100644 index 11d31fe87ccf..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ /dev/null @@ -1,81 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/map.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Memory map definitions - * - * 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_MAP_H -#define __ASM_ARCH_MAP_H __FILE__ - -#include -#include - -#define S5P6440_PA_CHIPID (0xE0000000) -#define S5P_PA_CHIPID S5P6440_PA_CHIPID - -#define S5P6440_PA_SYSCON (0xE0100000) -#define S5P6440_PA_CLK (S5P6440_PA_SYSCON + 0x0) -#define S5P_PA_SYSCON S5P6440_PA_SYSCON - -#define S5P6440_PA_GPIO (0xE0308000) - -#define S5P6440_PA_VIC0 (0xE4000000) -#define S5P6440_PA_VIC1 (0xE4100000) - -#define S5P6440_PA_PDMA 0xE9000000 - -#define S5P6440_PA_TIMER (0xEA000000) -#define S5P_PA_TIMER S5P6440_PA_TIMER - -#define S5P6440_PA_RTC (0xEA100000) - -#define S5P6440_PA_WDT (0xEA200000) - -#define S5P6440_PA_UART (0xEC000000) - -#define S5P_PA_UART0 (S5P6440_PA_UART + 0x0) -#define S5P_PA_UART1 (S5P6440_PA_UART + 0x400) -#define S5P_PA_UART2 (S5P6440_PA_UART + 0x800) -#define S5P_PA_UART3 (S5P6440_PA_UART + 0xC00) - -#define S5P_SZ_UART SZ_256 - -#define S5P6440_PA_IIC0 (0xEC104000) -#define S5P6440_PA_IIC1 (0xEC20F000) - -#define S5P6440_PA_SPI0 0xEC400000 -#define S5P6440_PA_SPI1 0xEC500000 - -#define S5P6440_PA_HSOTG (0xED100000) - -#define S5P6440_PA_HSMMC0 (0xED800000) -#define S5P6440_PA_HSMMC1 (0xED900000) -#define S5P6440_PA_HSMMC2 (0xEDA00000) - -#define S5P6440_PA_SDRAM (0x20000000) -#define S5P_PA_SDRAM S5P6440_PA_SDRAM - -/* I2S */ -#define S5P6440_PA_I2S 0xF2000000 - -/* PCM */ -#define S5P6440_PA_PCM 0xF2100000 - -#define S5P6440_PA_ADC (0xF3000000) - -/* compatibiltiy defines. */ -#define S3C_PA_UART S5P6440_PA_UART -#define S3C_PA_IIC S5P6440_PA_IIC0 -#define S3C_PA_RTC S5P6440_PA_RTC -#define S3C_PA_IIC1 S5P6440_PA_IIC1 -#define S3C_PA_WDT S5P6440_PA_WDT - -#define SAMSUNG_PA_ADC S5P6440_PA_ADC - -#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/memory.h b/arch/arm/mach-s5p6440/include/mach/memory.h deleted file mode 100644 index d62910c71b56..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/memory.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Memory definitions - * - * 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_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PHYS_OFFSET UL(0x20000000) -#define CONSISTENT_DMA_SIZE SZ_8M - -#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/system.h b/arch/arm/mach-s5p6440/include/mach/system.h deleted file mode 100644 index a359ee3fa510..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/system.h +++ /dev/null @@ -1,23 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/system.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - system support header - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -#include - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/timex.h b/arch/arm/mach-s5p6440/include/mach/timex.h deleted file mode 100644 index fb2e8cd40829..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/timex.h +++ /dev/null @@ -1,24 +0,0 @@ -/* arch/arm/mach-s3c64xx/include/mach/timex.h - * - * Copyright (c) 2003-2005 Simtec Electronics - * Ben Dooks - * - * S3C6400 - time parameters - * - * 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_TIMEX_H -#define __ASM_ARCH_TIMEX_H - -/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it - * a variable is useless. It seems as long as we make our timers an - * exact multiple of HZ, any value that makes a 1->1 correspondence - * for the time conversion functions to/from jiffies is acceptable. -*/ - -#define CLOCK_TICK_RATE 12000000 - -#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h deleted file mode 100644 index 7c1f600d65c0..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/uncompress.h +++ /dev/null @@ -1,24 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - uncompress code - * - * 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_UNCOMPRESS_H -#define __ASM_ARCH_UNCOMPRESS_H - -#include -#include - -static void arch_detect_cpu(void) -{ - /* we do not need to do any cpu detection here at the moment. */ -} - -#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p6440/include/mach/vmalloc.h deleted file mode 100644 index e3f0eebf5205..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/vmalloc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* arch/arm/mach-s5p6440/include/mach/vmalloc.h - * - * Copyright 2010 Ben Dooks - * - * 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. - * - * S3C6400 vmalloc definition -*/ - -#ifndef __ASM_ARCH_VMALLOC_H -#define __ASM_ARCH_VMALLOC_H - -#define VMALLOC_END 0xE0000000UL - -#endif /* __ASM_ARCH_VMALLOC_H */ diff --git a/arch/arm/mach-s5p6440/init.c b/arch/arm/mach-s5p6440/init.c deleted file mode 100644 index a1f3727e4021..000000000000 --- a/arch/arm/mach-s5p6440/init.c +++ /dev/null @@ -1,52 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/init.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Init 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 -#include -#include - -static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = { - [0] = { - .name = "pclk_low", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "uclk1", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - -/* uart registration process */ -void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - struct s3c2410_uartcfg *tcfg = cfg; - u32 ucnt; - - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->clocks = s5p6440_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks); - } - } - - s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); -} diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c new file mode 100644 index 000000000000..fb90a3004e98 --- /dev/null +++ b/arch/arm/mach-s5p64x0/cpu.c @@ -0,0 +1,208 @@ +/* linux/arch/arm/mach-s5p64x0/cpu.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Initial IO mappings */ + +static struct map_desc s5p64x0_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P64X0_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc s5p6440_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6440_PA_UART(0)), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc s5p6450_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6450_PA_UART(0)), + .length = SZ_512K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART + SZ_512K, + .pfn = __phys_to_pfn(S5P6450_PA_UART(5)), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void s5p64x0_idle(void) +{ + unsigned long val; + + if (!need_resched()) { + val = __raw_readl(S5P64X0_PWR_CFG); + val &= ~(0x3 << 5); + val |= (0x1 << 5); + __raw_writel(val, S5P64X0_PWR_CFG); + + cpu_do_idle(); + } + local_irq_enable(); +} + +/* + * s5p64x0_map_io + * + * register the standard CPU IO areas + */ + +void __init s5p6440_map_io(void) +{ + /* initialize any device information early */ + s3c_adc_setname("s3c64x0-adc"); + + iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); + iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); +} + +void __init s5p6450_map_io(void) +{ + /* initialize any device information early */ + s3c_adc_setname("s3c64x0-adc"); + + iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); + iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc)); +} + +/* + * s5p64x0_init_clocks + * + * register and setup the CPU clocks + */ + +void __init s5p6440_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6440_register_clocks(); + s5p6440_setup_clocks(); +} + +void __init s5p6450_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6450_register_clocks(); + s5p6450_setup_clocks(); +} + +/* + * s5p64x0_init_irq + * + * register the CPU interrupts + */ + +void __init s5p6440_init_irq(void) +{ + /* S5P6440 supports 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] + * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] + */ + vic[0] = 0xff800ae7; + vic[1] = 0xffbf23e5; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); +} + +void __init s5p6450_init_irq(void) +{ + /* S5P6450 supports only 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[(13-15), (21-22)] + * VIC1 is missing IRQ VIC1[12, 14, 23] + */ + vic[0] = 0xff9f1fff; + vic[1] = 0xff7fafff; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); +} + +struct sysdev_class s5p64x0_sysclass = { + .name = "s5p64x0-core", +}; + +static struct sys_device s5p64x0_sysdev = { + .cls = &s5p64x0_sysclass, +}; + +static int __init s5p64x0_core_init(void) +{ + return sysdev_class_register(&s5p64x0_sysclass); +} +core_initcall(s5p64x0_core_init); + +int __init s5p64x0_init(void) +{ + printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n"); + + /* set idle function */ + pm_idle = s5p64x0_idle; + + return sysdev_register(&s5p64x0_sysdev); +} diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S new file mode 100644 index 000000000000..79b04e6a6f8e --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S @@ -0,0 +1,33 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/debug-macro.S + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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. +*/ + +/* pull in the relevant register and map files. */ + +#include +#include + +#include + + .macro addruart, rp, rv + mov \rp, #0xE0000000 + orr \rp, \rp, #0x00100000 + ldr \rp, [\rp, #0x118 ] + and \rp, \rp, #0xff000 + teq \rp, #0x50000 @@ S5P6450 + ldreq \rp, =0xEC800000 + movne \rp, #0xEC000000 @@ S5P6440 + ldrne \rv, = S3C_VA_UART +#if CONFIG_DEBUG_S3C_UART != 0 + add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART) + add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART) +#endif + .endm + +#include diff --git a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S new file mode 100644 index 000000000000..10b62b4f8211 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S @@ -0,0 +1,16 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Low-level IRQ helper macros for the Samsung S5P64X0 + * + * 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 diff --git a/arch/arm/mach-s5p64x0/include/mach/hardware.h b/arch/arm/mach-s5p64x0/include/mach/hardware.h new file mode 100644 index 000000000000..d3e87996dd9a --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/hardware.h @@ -0,0 +1,18 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/hardware.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Hardware 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. +*/ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H __FILE__ + +/* currently nothing here, placeholder */ + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h new file mode 100644 index 000000000000..a3e095c02fb5 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/io.h @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/io.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * + * Default IO routines for S5P64X0 based + * + * 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_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* No current ISA/PCI bus support. */ +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#define IO_SPACE_LIMIT (0xFFFFFFFF) + +#endif diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h new file mode 100644 index 000000000000..31e534156e06 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/map.h @@ -0,0 +1,83 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/map.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Memory map definitions + * + * 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_MAP_H +#define __ASM_ARCH_MAP_H __FILE__ + +#include +#include + +#define S5P64X0_PA_SDRAM (0x20000000) + +#define S5P64X0_PA_CHIPID (0xE0000000) +#define S5P_PA_CHIPID S5P64X0_PA_CHIPID + +#define S5P64X0_PA_SYSCON (0xE0100000) +#define S5P_PA_SYSCON S5P64X0_PA_SYSCON + +#define S5P64X0_PA_GPIO (0xE0308000) + +#define S5P64X0_PA_VIC0 (0xE4000000) +#define S5P64X0_PA_VIC1 (0xE4100000) + +#define S5P64X0_PA_PDMA (0xE9000000) + +#define S5P64X0_PA_TIMER (0xEA000000) +#define S5P_PA_TIMER S5P64X0_PA_TIMER + +#define S5P64X0_PA_RTC (0xEA100000) + +#define S5P64X0_PA_WDT (0xEA200000) + +#define S5P6440_PA_UART(x) (0xEC000000 + ((x) * S3C_UART_OFFSET)) +#define S5P6450_PA_UART(x) ((x < 5) ? (0xEC800000 + ((x) * S3C_UART_OFFSET)) : (0xEC000000)) + +#define S5P_PA_UART0 S5P6450_PA_UART(0) +#define S5P_PA_UART1 S5P6450_PA_UART(1) +#define S5P_PA_UART2 S5P6450_PA_UART(2) +#define S5P_PA_UART3 S5P6450_PA_UART(3) +#define S5P_PA_UART4 S5P6450_PA_UART(4) +#define S5P_PA_UART5 S5P6450_PA_UART(5) + +#define S5P_SZ_UART SZ_256 + +#define S5P6440_PA_IIC0 (0xEC104000) +#define S5P6440_PA_IIC1 (0xEC20F000) +#define S5P6450_PA_IIC0 (0xEC100000) +#define S5P6450_PA_IIC1 (0xEC200000) + +#define S5P64X0_PA_SPI0 (0xEC400000) +#define S5P64X0_PA_SPI1 (0xEC500000) + +#define S5P64X0_PA_HSOTG (0xED100000) + +#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) + +#define S5P64X0_PA_I2S (0xF2000000) + +#define S5P64X0_PA_PCM (0xF2100000) + +#define S5P64X0_PA_ADC (0xF3000000) + +/* compatibiltiy defines. */ + +#define S3C_PA_HSMMC0 S5P64X0_PA_HSMMC(0) +#define S3C_PA_HSMMC1 S5P64X0_PA_HSMMC(1) +#define S3C_PA_HSMMC2 S5P64X0_PA_HSMMC(2) +#define S3C_PA_IIC S5P6440_PA_IIC0 +#define S3C_PA_IIC1 S5P6440_PA_IIC1 +#define S3C_PA_RTC S5P64X0_PA_RTC +#define S3C_PA_WDT S5P64X0_PA_WDT + +#define SAMSUNG_PA_ADC S5P64X0_PA_ADC + +#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h new file mode 100644 index 000000000000..1b036b0a24ce --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/memory.h @@ -0,0 +1,19 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Memory definitions + * + * 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_MEMORY_H +#define __ASM_ARCH_MEMORY_H __FILE__ + +#define PHYS_OFFSET UL(0x20000000) +#define CONSISTENT_DMA_SIZE SZ_8M + +#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h new file mode 100644 index 000000000000..60f57532c970 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/system.h @@ -0,0 +1,23 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/system.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - system support header + * + * 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_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H __FILE__ + +#include + +static void arch_idle(void) +{ + /* nothing here yet */ +} + +#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/timex.h b/arch/arm/mach-s5p64x0/include/mach/timex.h new file mode 100644 index 000000000000..4b91faa195a8 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/timex.h @@ -0,0 +1,27 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + * + * S5P64X0 - time parameters + * + * 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_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it + * a variable is useless. It seems as long as we make our timers an + * exact multiple of HZ, any value that makes a 1->1 correspondence + * for the time conversion functions to/from jiffies is acceptable. +*/ + +#define CLOCK_TICK_RATE 12000000 + +#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h new file mode 100644 index 000000000000..c65b229aab23 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/uncompress.h @@ -0,0 +1,212 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - uncompress code + * + * 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_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include + +/* + * cannot use commonly + * because uart base of S5P6440 and S5P6450 is different + */ + +typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ + +/* uart setup */ + +static unsigned int fifo_mask; +static unsigned int fifo_max; + +/* forward declerations */ + +static void arch_detect_cpu(void); + +/* defines for UART registers */ + +#include +#include + +/* working in physical space... */ +#undef S3C2410_WDOGREG +#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x))) + +/* how many bytes we allow into the FIFO at a time in FIFO mode */ +#define FIFO_MAX (14) + +static unsigned long uart_base; + +static __inline__ void get_uart_base(void) +{ + unsigned int chipid; + + chipid = *(const volatile unsigned int __force *) 0xE0100118; + + uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT; + + if ((chipid & 0xff000) == 0x50000) + uart_base += 0xEC800000; + else + uart_base += 0xEC000000; +} + +static __inline__ void uart_wr(unsigned int reg, unsigned int val) +{ + volatile unsigned int *ptr; + + get_uart_base(); + ptr = (volatile unsigned int *)(reg + uart_base); + *ptr = val; +} + +static __inline__ unsigned int uart_rd(unsigned int reg) +{ + volatile unsigned int *ptr; + + get_uart_base(); + ptr = (volatile unsigned int *)(reg + uart_base); + return *ptr; +} + +/* + * we can deal with the case the UARTs are being run + * in FIFO mode, so that we don't hold up our execution + * waiting for tx to happen... + */ + +static void putc(int ch) +{ + if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { + int level; + + while (1) { + level = uart_rd(S3C2410_UFSTAT); + level &= fifo_mask; + + if (level < fifo_max) + break; + } + + } else { + /* not using fifos */ + + while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) + barrier(); + } + + /* write byte to transmission register */ + uart_wr(S3C2410_UTXH, ch); +} + +static inline void flush(void) +{ +} + +#define __raw_writel(d, ad) \ + do { \ + *((volatile unsigned int __force *)(ad)) = (d); \ + } while (0) + +/* + * CONFIG_S3C_BOOT_WATCHDOG + * + * Simple boot-time watchdog setup, to reboot the system if there is + * any problem with the boot process + */ + +#ifdef CONFIG_S3C_BOOT_WATCHDOG + +#define WDOG_COUNT (0xff00) + +static inline void arch_decomp_wdog(void) +{ + __raw_writel(WDOG_COUNT, S3C2410_WTCNT); +} + +static void arch_decomp_wdog_start(void) +{ + __raw_writel(WDOG_COUNT, S3C2410_WTDAT); + __raw_writel(WDOG_COUNT, S3C2410_WTCNT); + __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON); +} + +#else +#define arch_decomp_wdog_start() +#define arch_decomp_wdog() +#endif + +#ifdef CONFIG_S3C_BOOT_ERROR_RESET + +static void arch_decomp_error(const char *x) +{ + putstr("\n\n"); + putstr(x); + putstr("\n\n -- System resetting\n"); + + __raw_writel(0x4000, S3C2410_WTDAT); + __raw_writel(0x4000, S3C2410_WTCNT); + __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); + + while(1); +} + +#define arch_error arch_decomp_error +#endif + +#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO +static inline void arch_enable_uart_fifo(void) +{ + u32 fifocon = uart_rd(S3C2410_UFCON); + + if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { + fifocon |= S3C2410_UFCON_RESETBOTH; + uart_wr(S3C2410_UFCON, fifocon); + + /* wait for fifo reset to complete */ + while (1) { + fifocon = uart_rd(S3C2410_UFCON); + if (!(fifocon & S3C2410_UFCON_RESETBOTH)) + break; + } + } +} +#else +#define arch_enable_uart_fifo() do { } while(0) +#endif + +static void arch_decomp_setup(void) +{ + /* + * we may need to setup the uart(s) here if we are not running + * on an BAST... the BAST will have left the uarts configured + * after calling linux. + */ + + arch_detect_cpu(); + arch_decomp_wdog_start(); + + /* + * Enable the UART FIFOs if they where not enabled and our + * configuration says we should turn them on. + */ + + arch_enable_uart_fifo(); +} + + + +static void arch_detect_cpu(void) +{ + /* we do not need to do any cpu detection here at the moment. */ +} + +#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h new file mode 100644 index 000000000000..97a9df38f1cf --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h @@ -0,0 +1,20 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2010 Ben Dooks + * + * 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. + * + * S3C6400 vmalloc definition +*/ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H + +#define VMALLOC_END 0xE0000000UL + +#endif /* __ASM_ARCH_VMALLOC_H */ diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c new file mode 100644 index 000000000000..79833caf8165 --- /dev/null +++ b/arch/arm/mach-s5p64x0/init.c @@ -0,0 +1,73 @@ +/* linux/arch/arm/mach-s5p64x0/init.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Init 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 +#include +#include +#include +#include + +static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = { + [0] = { + .name = "pclk_low", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "uclk1", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, +}; + +/* uart registration process */ + +void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct s3c2410_uartcfg *tcfg = cfg; + u32 ucnt; + + for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { + if (!tcfg->clocks) { + tcfg->clocks = s5p64x0_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks); + } + } +} + +void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + int uart; + + for (uart = 0; uart < no; uart++) { + s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart); + s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; + } + + s5p64x0_common_init_uarts(cfg, no); + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); +} + +void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + s5p64x0_common_init_uarts(cfg, no); + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); +} diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index 57f08eee6d62..74f7f5a5446c 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ static const char name_s5p6440[] = "S5P6440"; static const char name_s5p6442[] = "S5P6442"; +static const char name_s5p6450[] = "S5P6450"; static const char name_s5pc100[] = "S5PC100"; static const char name_s5pv210[] = "S5PV210/S5PC110"; static const char name_s5pv310[] = "S5PV310"; @@ -38,7 +40,7 @@ static struct cpu_table cpu_ids[] __initdata = { .map_io = s5p6440_map_io, .init_clocks = s5p6440_init_clocks, .init_uarts = s5p6440_init_uarts, - .init = s5p6440_init, + .init = s5p64x0_init, .name = name_s5p6440, }, { .idcode = 0x36442000, @@ -48,6 +50,14 @@ static struct cpu_table cpu_ids[] __initdata = { .init_uarts = s5p6442_init_uarts, .init = s5p6442_init, .name = name_s5p6442, + }, { + .idcode = 0x36450000, + .idmask = 0xffffff00, + .map_io = s5p6450_map_io, + .init_clocks = s5p6450_init_clocks, + .init_uarts = s5p6450_init_uarts, + .init = s5p64x0_init, + .name = name_s5p6450, }, { .idcode = 0x43100000, .idmask = 0xfffff000, diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h index a4cd75afeb3b..528585d2cafc 100644 --- a/arch/arm/plat-s5p/include/plat/s5p6440.h +++ b/arch/arm/plat-s5p/include/plat/s5p6440.h @@ -12,24 +12,23 @@ /* Common init code for S5P6440 related SoCs */ -extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s5p6440_register_clocks(void); extern void s5p6440_setup_clocks(void); #ifdef CONFIG_CPU_S5P6440 -extern int s5p6440_init(void); +extern int s5p64x0_init(void); extern void s5p6440_init_irq(void); extern void s5p6440_map_io(void); extern void s5p6440_init_clocks(int xtal); -#define s5p6440_init_uarts s5p6440_common_init_uarts +extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no); #else #define s5p6440_init_clocks NULL #define s5p6440_init_uarts NULL #define s5p6440_map_io NULL -#define s5p6440_init NULL +#define s5p64x0_init NULL #endif /* S5P6440 timer */ diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h new file mode 100644 index 000000000000..640a41c26be3 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p6450.h @@ -0,0 +1,36 @@ +/* arch/arm/plat-s5p/include/plat/s5p6450.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for s5p6450 cpu 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. +*/ + +/* Common init code for S5P6450 related SoCs */ + +extern void s5p6450_register_clocks(void); +extern void s5p6450_setup_clocks(void); + +#ifdef CONFIG_CPU_S5P6450 + +extern int s5p64x0_init(void); +extern void s5p6450_init_irq(void); +extern void s5p6450_map_io(void); +extern void s5p6450_init_clocks(int xtal); + +extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +#else +#define s5p6450_init_clocks NULL +#define s5p6450_init_uarts NULL +#define s5p6450_map_io NULL +#define s5p64x0_init NULL +#endif + +/* S5P6450 timer */ + +extern struct sys_timer s5p6450_timer; -- cgit v1.2.3-59-g8ed1b From 3109e55099cb013f9e1b63d39606dc5d7ecf25bd Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Wed, 1 Sep 2010 15:35:30 +0900 Subject: ARM: S5P64X0: Update Clock for S5P6440 and S5P6450 This patch updates regarding clock files for supporting S5P6440 and S5P6450 with one kernel image. The mach-s5p64x0/clock.c is for common of them and there are specific clock files for each SoCs. Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6440/clock.c | 846 --------------------- arch/arm/mach-s5p6440/include/mach/regs-clock.h | 130 ---- arch/arm/mach-s5p64x0/clock-s5p6440.c | 626 +++++++++++++++ arch/arm/mach-s5p64x0/clock-s5p6450.c | 655 ++++++++++++++++ arch/arm/mach-s5p64x0/clock.c | 253 ++++++ arch/arm/mach-s5p64x0/include/mach/regs-clock.h | 63 ++ arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h | 46 ++ arch/arm/plat-s5p/clock.c | 19 + arch/arm/plat-s5p/include/plat/pll.h | 7 + arch/arm/plat-s5p/include/plat/s5p-clock.h | 8 +- 10 files changed, 1674 insertions(+), 979 deletions(-) delete mode 100644 arch/arm/mach-s5p6440/clock.c delete mode 100644 arch/arm/mach-s5p6440/include/mach/regs-clock.h create mode 100644 arch/arm/mach-s5p64x0/clock-s5p6440.c create mode 100644 arch/arm/mach-s5p64x0/clock-s5p6450.c create mode 100644 arch/arm/mach-s5p64x0/clock.c create mode 100644 arch/arm/mach-s5p64x0/include/mach/regs-clock.h create mode 100644 arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c deleted file mode 100644 index ca6e48dce777..000000000000 --- a/arch/arm/mach-s5p6440/clock.c +++ /dev/null @@ -1,846 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/clock.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Clock 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 -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* APLL Mux output clock */ -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - .id = -1, - }, - .sources = &clk_src_apll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, -}; - -static int s5p6440_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); - else - __raw_writel(epll_con, S5P_EPLL_CON); - - return 0; -} - -static unsigned long s5p6440_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -static u32 epll_div[][5] = { - { 36000000, 0, 48, 1, 4 }, - { 48000000, 0, 32, 1, 3 }, - { 60000000, 0, 40, 1, 3 }, - { 72000000, 0, 48, 1, 3 }, - { 84000000, 0, 28, 1, 2 }, - { 96000000, 0, 32, 1, 2 }, - { 32768000, 45264, 43, 1, 4 }, - { 45158000, 6903, 30, 1, 3 }, - { 49152000, 50332, 32, 1, 3 }, - { 67738000, 10398, 45, 1, 3 }, - { 73728000, 9961, 49, 1, 3 } -}; - -static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int epll_con, epll_con_k; - unsigned int i; - - if (clk->rate == rate) /* Return if nothing changed */ - return 0; - - epll_con = __raw_readl(S5P_EPLL_CON); - epll_con_k = __raw_readl(S5P_EPLL_CON_K); - - epll_con_k &= ~(PLL90XX_KDIV_MASK); - epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); - - for (i = 0; i < ARRAY_SIZE(epll_div); i++) { - if (epll_div[i][0] == rate) { - epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); - epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | - (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | - (epll_div[i][4] << PLL90XX_SDIV_SHIFT); - break; - } - } - - if (i == ARRAY_SIZE(epll_div)) { - printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); - return -EINVAL; - } - - __raw_writel(epll_con, S5P_EPLL_CON); - __raw_writel(epll_con_k, S5P_EPLL_CON_K); - - clk->rate = rate; - - return 0; -} - -static struct clk_ops s5p6440_epll_ops = { - .get_rate = s5p6440_epll_get_rate, - .set_rate = s5p6440_epll_set_rate, -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - .id = -1, - }, - .sources = &clk_src_epll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 }, -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - .id = -1, - }, - .sources = &clk_src_mpll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, -}; - -enum perf_level { - L0 = 532*1000, - L1 = 266*1000, - L2 = 133*1000, -}; - -static const u32 clock_table[][3] = { - /*{ARM_CLK, DIVarm, DIVhclk}*/ - {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)}, - {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)}, - {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)}, -}; - -static unsigned long s5p6440_armclk_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv; - - /* divisor mask starts at bit0, so no need to shift */ - clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK; - - return rate / (clkdiv + 1); -} - -static unsigned long s5p6440_armclk_round_rate(struct clk *clk, - unsigned long rate) -{ - u32 iter; - - for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) { - if (rate > clock_table[iter][0]) - return clock_table[iter-1][0]; - } - - return clock_table[ARRAY_SIZE(clock_table) - 1][0]; -} - -static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate) -{ - u32 round_tmp; - u32 iter; - u32 clk_div0_tmp; - u32 cur_rate = clk->ops->get_rate(clk); - unsigned long flags; - - round_tmp = clk->ops->round_rate(clk, rate); - if (round_tmp == cur_rate) - return 0; - - - for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) { - if (round_tmp == clock_table[iter][0]) - break; - } - - if (iter >= ARRAY_SIZE(clock_table)) - iter = ARRAY_SIZE(clock_table) - 1; - - local_irq_save(flags); - if (cur_rate > round_tmp) { - /* Frequency Down */ - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); - clk_div0_tmp |= clock_table[iter][1]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & - ~(S5P_CLKDIV0_HCLK_MASK); - clk_div0_tmp |= clock_table[iter][2]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - - } else { - /* Frequency Up */ - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & - ~(S5P_CLKDIV0_HCLK_MASK); - clk_div0_tmp |= clock_table[iter][2]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); - clk_div0_tmp |= clock_table[iter][1]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - } - local_irq_restore(flags); - - clk->rate = clock_table[iter][0]; - - return 0; -} - -static struct clk_ops s5p6440_clkarm_ops = { - .get_rate = s5p6440_armclk_get_rate, - .set_rate = s5p6440_armclk_set_rate, - .round_rate = s5p6440_armclk_round_rate, -}; - -static struct clksrc_clk clk_armclk = { - .clk = { - .name = "armclk", - .id = 1, - .parent = &clk_mout_apll.clk, - .ops = &s5p6440_clkarm_ops, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mpll = { - .clk = { - .name = "dout_mpll", - .id = -1, - .parent = &clk_mout_mpll.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk clk_hclk = { - .clk = { - .name = "clk_hclk", - .id = -1, - .parent = &clk_armclk.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk clk_pclk = { - .clk = { - .name = "clk_pclk", - .id = -1, - .parent = &clk_hclk.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 }, -}; - -static struct clk *clkset_hclklow_list[] = { - &clk_mout_apll.clk, - &clk_mout_mpll.clk, -}; - -static struct clksrc_sources clkset_hclklow = { - .sources = clkset_hclklow_list, - .nr_sources = ARRAY_SIZE(clkset_hclklow_list), -}; - -static struct clksrc_clk clk_hclk_low = { - .clk = { - .name = "hclk_low", - .id = -1, - }, - .sources = &clkset_hclklow, - .reg_src = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk clk_pclk_low = { - .clk = { - .name = "pclk_low", - .id = -1, - .parent = &clk_hclk_low.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, -}; - -int s5p6440_clk48m_ctrl(struct clk *clk, int enable) -{ - unsigned long flags; - u32 val; - - /* can't rely on clock lock, this register has other usages */ - local_irq_save(flags); - - val = __raw_readl(S5P_OTHERS); - if (enable) - val |= S5P_OTHERS_USB_SIG_MASK; - else - val &= ~S5P_OTHERS_USB_SIG_MASK; - - __raw_writel(val, S5P_OTHERS); - - local_irq_restore(flags); - - return 0; -} - -static int s5p6440_pclk_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable); -} - -static int s5p6440_hclk0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable); -} - -static int s5p6440_hclk1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable); -} - -static int s5p6440_sclk_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable); -} - -static int s5p6440_sclk1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable); -} - -static int s5p6440_mem_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable); -} - -/* - * The following clocks will be disabled during clock initialization. It is - * recommended to keep the following clocks disabled until the driver requests - * for enabling the clock. - */ -static struct clk init_clocks_disable[] = { - { - .name = "nand", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_mem_ctrl, - .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON, - }, { - .name = "adc", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_TSADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_IIC0, - }, { - .name = "i2s_v40", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_IIS2, - }, { - .name = "spi", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_SPI0, - }, { - .name = "spi", - .id = 1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_SPI1, - }, { - .name = "sclk_spi_48", - .id = 0, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48, - }, { - .name = "sclk_spi_48", - .id = 1, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48, - }, { - .name = "mmc_48m", - .id = 0, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48, - }, { - .name = "mmc_48m", - .id = 1, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48, - }, { - .name = "mmc_48m", - .id = 2, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48, - }, { - .name = "otg", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_USB - }, { - .name = "post", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_POST0 - }, { - .name = "lcd", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = S5P_CLKCON_HCLK1_DISPCON, - }, { - .name = "hsmmc", - .id = 0, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0, - }, { - .name = "hsmmc", - .id = 1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1, - }, { - .name = "hsmmc", - .id = 2, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_WDT, - }, { - .name = "timers", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_PWM, - }, { - .name = "hclk_fimgvg", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "tsi", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "pclk_fimgvg", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 31), - }, { - .name = "dmc0", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 30), - }, { - .name = "etm", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 29), - }, { - .name = "dsim", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 28), - }, { - .name = "gps", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "pcm", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "irom", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "dma", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "2d", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 8), - }, -}; - -/* - * The following clocks will be enabled during clock initialization. - */ -static struct clk init_clocks[] = { - { - .name = "gpio", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_GPIO, - }, { - .name = "uart", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART2, - }, { - .name = "uart", - .id = 3, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART3, - }, { - .name = "mem", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "intc", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 1), - }, -}; - -static struct clk clk_iis_cd_v40 = { - .name = "iis_cdclk_v40", - .id = -1, -}; - -static struct clk clk_pcm_cd = { - .name = "pcm_cdclk", - .id = -1, -}; - -static struct clk *clkset_group1_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, - &clk_fin_epll, -}; - -static struct clksrc_sources clkset_group1 = { - .sources = clkset_group1_list, - .nr_sources = ARRAY_SIZE(clkset_group1_list), -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, -}; - -static struct clksrc_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_audio_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, - &clk_fin_epll, - &clk_iis_cd_v40, - &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio = { - .sources = clkset_audio_list, - .nr_sources = ARRAY_SIZE(clkset_audio_list), -}; - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "mmc_bus", - .id = 0, - .ctrlbit = S5P_CLKCON_SCLK0_MMC0, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "mmc_bus", - .id = 1, - .ctrlbit = S5P_CLKCON_SCLK0_MMC1, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "mmc_bus", - .id = 2, - .ctrlbit = S5P_CLKCON_SCLK0_MMC2, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .id = -1, - .ctrlbit = S5P_CLKCON_SCLK0_UART, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "spi_epll", - .id = 0, - .ctrlbit = S5P_CLKCON_SCLK0_SPI0, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "spi_epll", - .id = 1, - .ctrlbit = S5P_CLKCON_SCLK0_SPI1, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_post", - .id = -1, - .ctrlbit = (1 << 10), - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 }, - }, { - .clk = { - .name = "sclk_dispcon", - .id = -1, - .ctrlbit = (1 << 1), - .enable = s5p6440_sclk1_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimgvg", - .id = -1, - .ctrlbit = (1 << 2), - .enable = s5p6440_sclk1_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_audio2", - .id = -1, - .ctrlbit = (1 << 11), - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_audio, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 }, - }, -}; - -/* Clock initialisation code */ -static struct clksrc_clk *sysclks[] = { - &clk_mout_apll, - &clk_mout_epll, - &clk_mout_mpll, - &clk_dout_mpll, - &clk_armclk, - &clk_hclk, - &clk_pclk, - &clk_hclk_low, - &clk_pclk_low, -}; - -void __init_or_cpufreq s5p6440_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long xtal; - unsigned long fclk; - unsigned long hclk; - unsigned long hclk_low; - unsigned long pclk; - unsigned long pclk_low; - unsigned long epll; - unsigned long apll; - unsigned long mpll; - unsigned int ptr; - - /* Set S5P6440 functions for clk_fout_epll */ - clk_fout_epll.enable = s5p6440_epll_enable; - clk_fout_epll.ops = &s5p6440_epll_ops; - - clk_48m.enable = s5p6440_clk48m_ctrl; - - xtal_clk = clk_get(NULL, "ext_xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON), - __raw_readl(S5P_EPLL_CON_K)); - mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); - apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502); - - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - - printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ - " E=%ld.%ldMHz\n", - print_mhz(apll), print_mhz(mpll), print_mhz(epll)); - - fclk = clk_get_rate(&clk_armclk.clk); - hclk = clk_get_rate(&clk_hclk.clk); - pclk = clk_get_rate(&clk_pclk.clk); - hclk_low = clk_get_rate(&clk_hclk_low.clk); - pclk_low = clk_get_rate(&clk_pclk_low.clk); - - printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ - " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", - print_mhz(hclk), print_mhz(hclk_low), - print_mhz(pclk), print_mhz(pclk_low)); - - clk_f.rate = fclk; - clk_h.rate = hclk; - clk_p.rate = pclk; - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_iis_cd_v40, - &clk_pcm_cd, -}; - -void __init s5p6440_register_clocks(void) -{ - struct clk *clkp; - int ret; - int ptr; - - ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - if (ret > 0) - printk(KERN_ERR "Failed to register %u clocks\n", ret); - - for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) - s3c_register_clksrc(sysclks[ptr], 1); - - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - (clkp->enable)(clkp, 0); - } - - s3c_pwmclk_init(); -} diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h deleted file mode 100644 index c783ecc9f193..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/regs-clock.h +++ /dev/null @@ -1,130 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Clock register definitions - * - * 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_CLOCK_H -#define __ASM_ARCH_REGS_CLOCK_H __FILE__ - -#include - -#define S5P_CLKREG(x) (S3C_VA_SYS + (x)) - -#define S5P_APLL_LOCK S5P_CLKREG(0x00) -#define S5P_MPLL_LOCK S5P_CLKREG(0x04) -#define S5P_EPLL_LOCK S5P_CLKREG(0x08) -#define S5P_APLL_CON S5P_CLKREG(0x0C) -#define S5P_MPLL_CON S5P_CLKREG(0x10) -#define S5P_EPLL_CON S5P_CLKREG(0x14) -#define S5P_EPLL_CON_K S5P_CLKREG(0x18) -#define S5P_CLK_SRC0 S5P_CLKREG(0x1C) -#define S5P_CLK_DIV0 S5P_CLKREG(0x20) -#define S5P_CLK_DIV1 S5P_CLKREG(0x24) -#define S5P_CLK_DIV2 S5P_CLKREG(0x28) -#define S5P_CLK_OUT S5P_CLKREG(0x2C) -#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30) -#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34) -#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38) -#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C) -#define S5P_CLK_DIV3 S5P_CLKREG(0x40) -#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44) -#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48) -#define S5P_AHB_CON0 S5P_CLKREG(0x100) -#define S5P_CLK_SRC1 S5P_CLKREG(0x10C) -#define S5P_SWRESET S5P_CLKREG(0x114) -#define S5P_SYS_ID S5P_CLKREG(0x118) -#define S5P_SYS_OTHERS S5P_CLKREG(0x11C) -#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C) -#define S5P_PWR_CFG S5P_CLKREG(0x804) -#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808) -#define S5P_NORMAL_CFG S5P_CLKREG(0x810) -#define S5P_STOP_CFG S5P_CLKREG(0x814) -#define S5P_SLEEP_CFG S5P_CLKREG(0x818) -#define S5P_OSC_FREQ S5P_CLKREG(0x820) -#define S5P_OSC_STABLE S5P_CLKREG(0x824) -#define S5P_PWR_STABLE S5P_CLKREG(0x828) -#define S5P_MTC_STABLE S5P_CLKREG(0x830) -#define S5P_OTHERS S5P_CLKREG(0x900) -#define S5P_RST_STAT S5P_CLKREG(0x904) -#define S5P_WAKEUP_STAT S5P_CLKREG(0x908) -#define S5P_SLPEN S5P_CLKREG(0x930) -#define S5P_INFORM0 S5P_CLKREG(0xA00) -#define S5P_INFORM1 S5P_CLKREG(0xA04) -#define S5P_INFORM2 S5P_CLKREG(0xA08) -#define S5P_INFORM3 S5P_CLKREG(0xA0C) - -/* CLKDIV0 */ -#define S5P_CLKDIV0_PCLK_MASK (0xf << 12) -#define S5P_CLKDIV0_PCLK_SHIFT (12) -#define S5P_CLKDIV0_HCLK_MASK (0xf << 8) -#define S5P_CLKDIV0_HCLK_SHIFT (8) -#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4) -#define S5P_CLKDIV0_ARM_MASK (0xf << 0) -#define S5P_CLKDIV0_ARM_SHIFT (0) - -/* CLKDIV3 */ -#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12) -#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12) -#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8) -#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8) - -/* HCLK0 GATE Registers */ -#define S5P_CLKCON_HCLK0_USB (1<<20) -#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19) -#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18) -#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17) -#define S5P_CLKCON_HCLK0_POST0 (1<<5) - -/* HCLK1 GATE Registers */ -#define S5P_CLKCON_HCLK1_DISPCON (1<<1) - -/* PCLK GATE Registers */ -#define S5P_CLKCON_PCLK_IIS2 (1<<26) -#define S5P_CLKCON_PCLK_SPI1 (1<<22) -#define S5P_CLKCON_PCLK_SPI0 (1<<21) -#define S5P_CLKCON_PCLK_GPIO (1<<18) -#define S5P_CLKCON_PCLK_IIC0 (1<<17) -#define S5P_CLKCON_PCLK_TSADC (1<<12) -#define S5P_CLKCON_PCLK_PWM (1<<7) -#define S5P_CLKCON_PCLK_RTC (1<<6) -#define S5P_CLKCON_PCLK_WDT (1<<5) -#define S5P_CLKCON_PCLK_UART3 (1<<4) -#define S5P_CLKCON_PCLK_UART2 (1<<3) -#define S5P_CLKCON_PCLK_UART1 (1<<2) -#define S5P_CLKCON_PCLK_UART0 (1<<1) - -/* SCLK0 GATE Registers */ -#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29) -#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28) -#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27) -#define S5P_CLKCON_SCLK0_MMC2 (1<<26) -#define S5P_CLKCON_SCLK0_MMC1 (1<<25) -#define S5P_CLKCON_SCLK0_MMC0 (1<<24) -#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23) -#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22) -#define S5P_CLKCON_SCLK0_SPI1 (1<<21) -#define S5P_CLKCON_SCLK0_SPI0 (1<<20) -#define S5P_CLKCON_SCLK0_UART (1<<5) - -/* SCLK1 GATE Registers */ - -/* MEM0 GATE Registers */ -#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2) - -/*OTHERS Resgister */ -#define S5P_OTHERS_USB_SIG_MASK (1<<16) -#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6) - -/* Compatibility defines */ -#define ARM_CLK_DIV S5P_CLK_DIV0 -#define ARM_DIV_RATIO_SHIFT 0 -#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT) - -#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c new file mode 100644 index 000000000000..f93dcd8b4d6a --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -0,0 +1,626 @@ +/* linux/arch/arm/mach-s5p64x0/clock-s5p6440.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P6440 - Clock 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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static u32 epll_div[][5] = { + { 36000000, 0, 48, 1, 4 }, + { 48000000, 0, 32, 1, 3 }, + { 60000000, 0, 40, 1, 3 }, + { 72000000, 0, 48, 1, 3 }, + { 84000000, 0, 28, 1, 2 }, + { 96000000, 0, 32, 1, 2 }, + { 32768000, 45264, 43, 1, 4 }, + { 45158000, 6903, 30, 1, 3 }, + { 49152000, 50332, 32, 1, 3 }, + { 67738000, 10398, 45, 1, 3 }, + { 73728000, 9961, 49, 1, 3 } +}; + +static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P64X0_EPLL_CON); + epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K); + + epll_con_k &= ~(PLL90XX_KDIV_MASK); + epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); + epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | + (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | + (epll_div[i][4] << PLL90XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P64X0_EPLL_CON); + __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5p6440_epll_ops = { + .get_rate = s5p64x0_epll_get_rate, + .set_rate = s5p6440_epll_set_rate, +}; + +static struct clksrc_clk clk_hclk = { + .clk = { + .name = "clk_hclk", + .id = -1, + .parent = &clk_armclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk = { + .clk = { + .name = "clk_pclk", + .id = -1, + .parent = &clk_hclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 }, +}; +static struct clksrc_clk clk_hclk_low = { + .clk = { + .name = "clk_hclk_low", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_SYS_OTHERS, .shift = 6, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_low = { + .clk = { + .name = "clk_pclk_low", + .id = -1, + .parent = &clk_hclk_low.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 }, +}; + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "nand", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_mem_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "post", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 5) + }, { + .name = "2d", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "otg", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 20) + }, { + .name = "irom", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "lcd", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "hclk_fimgvg", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "tsi", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "rtc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "timers", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "pcm", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "adc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "spi", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "spi", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "gps", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "i2s_v40", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 26), + }, { + .name = "dsim", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 28), + }, { + .name = "etm", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 29), + }, { + .name = "dmc0", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 30), + }, { + .name = "pclk_fimgvg", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 31), + }, { + .name = "sclk_spi_48", + .id = 0, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "sclk_spi_48", + .id = 1, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 23), + }, { + .name = "mmc_48m", + .id = 0, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "mmc_48m", + .id = 1, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 28), + }, { + .name = "mmc_48m", + .id = 2, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 29), + }, +}; + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "intc", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "mem", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "dma", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "uart", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .id = 2, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .id = 3, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "gpio", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 18), + }, +}; + +static struct clk clk_iis_cd_v40 = { + .name = "iis_cdclk_v40", + .id = -1, +}; + +static struct clk clk_pcm_cd = { + .name = "pcm_cdclk", + .id = -1, +}; + +static struct clk *clkset_group1_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, + &clk_fin_epll, +}; + +static struct clksrc_sources clkset_group1 = { + .sources = clkset_group1_list, + .nr_sources = ARRAY_SIZE(clkset_group1_list), +}; + +static struct clk *clkset_uart_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), +}; + +static struct clk *clkset_audio_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, + &clk_fin_epll, + &clk_iis_cd_v40, + &clk_pcm_cd, +}; + +static struct clksrc_sources clkset_audio = { + .sources = clkset_audio_list, + .nr_sources = ARRAY_SIZE(clkset_audio_list), +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = (1 << 24), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = (1 << 25), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = (1 << 26), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 0, + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_post", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_dispcon", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimgvg", + .id = -1, + .ctrlbit = (1 << 2), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_audio2", + .id = -1, + .ctrlbit = (1 << 11), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_audio, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 }, + }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *sysclks[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_mout_mpll, + &clk_dout_mpll, + &clk_armclk, + &clk_hclk, + &clk_pclk, + &clk_hclk_low, + &clk_pclk_low, +}; + +void __init_or_cpufreq s5p6440_setup_clocks(void) +{ + struct clk *xtal_clk; + + unsigned long xtal; + unsigned long fclk; + unsigned long hclk; + unsigned long hclk_low; + unsigned long pclk; + unsigned long pclk_low; + + unsigned long apll; + unsigned long mpll; + unsigned long epll; + unsigned int ptr; + + /* Set S5P6440 functions for clk_fout_epll */ + + clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.ops = &s5p6440_epll_ops; + + clk_48m.enable = s5p64x0_clk48m_ctrl; + + xtal_clk = clk_get(NULL, "ext_xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502); + mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502); + epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON), + __raw_readl(S5P64X0_EPLL_CON_K)); + + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + + printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ + " E=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll)); + + fclk = clk_get_rate(&clk_armclk.clk); + hclk = clk_get_rate(&clk_hclk.clk); + pclk = clk_get_rate(&clk_pclk.clk); + hclk_low = clk_get_rate(&clk_hclk_low.clk); + pclk_low = clk_get_rate(&clk_pclk_low.clk); + + printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ + " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", + print_mhz(hclk), print_mhz(hclk_low), + print_mhz(pclk), print_mhz(pclk_low)); + + clk_f.rate = fclk; + clk_h.rate = hclk; + clk_p.rate = pclk; + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); +} + +static struct clk *clks[] __initdata = { + &clk_ext, + &clk_iis_cd_v40, + &clk_pcm_cd, +}; + +void __init s5p6440_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c new file mode 100644 index 000000000000..f9afb05b217c --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -0,0 +1,655 @@ +/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P6450 - Clock 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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static struct clksrc_clk clk_mout_dpll = { + .clk = { + .name = "mout_dpll", + .id = -1, + }, + .sources = &clk_src_dpll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 }, +}; + +static u32 epll_div[][5] = { + { 133000000, 27307, 55, 2, 2 }, + { 100000000, 43691, 41, 2, 2 }, + { 480000000, 0, 80, 2, 0 }, +}; + +static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P64X0_EPLL_CON); + epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K); + + epll_con_k &= ~(PLL90XX_KDIV_MASK); + epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); + epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | + (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | + (epll_div[i][4] << PLL90XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P64X0_EPLL_CON); + __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5p6450_epll_ops = { + .get_rate = s5p64x0_epll_get_rate, + .set_rate = s5p6450_epll_set_rate, +}; + +static struct clksrc_clk clk_dout_epll = { + .clk = { + .name = "dout_epll", + .id = -1, + .parent = &clk_mout_epll.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 }, +}; + +static struct clksrc_clk clk_mout_hclk_sel = { + .clk = { + .name = "mout_hclk_sel", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 }, +}; + +static struct clk *clkset_hclk_list[] = { + &clk_mout_hclk_sel.clk, + &clk_armclk.clk, +}; + +static struct clksrc_sources clkset_hclk = { + .sources = clkset_hclk_list, + .nr_sources = ARRAY_SIZE(clkset_hclk_list), +}; + +static struct clksrc_clk clk_hclk = { + .clk = { + .name = "clk_hclk", + .id = -1, + }, + .sources = &clkset_hclk, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk = { + .clk = { + .name = "clk_pclk", + .id = -1, + .parent = &clk_hclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 }, +}; +static struct clksrc_clk clk_dout_pwm_ratio0 = { + .clk = { + .name = "clk_dout_pwm_ratio0", + .id = -1, + .parent = &clk_mout_hclk_sel.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_to_wdt_pwm = { + .clk = { + .name = "clk_pclk_to_wdt_pwm", + .id = -1, + .parent = &clk_dout_pwm_ratio0.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 }, +}; + +static struct clksrc_clk clk_hclk_low = { + .clk = { + .name = "clk_hclk_low", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_low = { + .clk = { + .name = "clk_pclk_low", + .id = -1, + .parent = &clk_hclk_low.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 }, +}; + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "usbhost", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "usbotg", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "adc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "spi", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "spi", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "iis", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 26), + }, { + .name = "i2c", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "dmc0", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 30), + } +}; + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "intc", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "mem", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "dma", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "uart", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .id = 2, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .id = 3, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "timers", + .id = -1, + .parent = &clk_pclk_to_wdt_pwm.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "gpio", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 18), + }, +}; + +static struct clk *clkset_uart_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), +}; + +static struct clk *clkset_mali_list[] = { + &clk_mout_epll.clk, + &clk_mout_apll.clk, + &clk_mout_mpll.clk, +}; + +static struct clksrc_sources clkset_mali = { + .sources = clkset_mali_list, + .nr_sources = ARRAY_SIZE(clkset_mali_list), +}; + +static struct clk *clkset_group2_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, +}; + +static struct clksrc_sources clkset_group2 = { + .sources = clkset_group2_list, + .nr_sources = ARRAY_SIZE(clkset_group2_list), +}; + +static struct clk *clkset_dispcon_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, + &clk_mout_dpll.clk, +}; + +static struct clksrc_sources clkset_dispcon = { + .sources = clkset_dispcon_list, + .nr_sources = ARRAY_SIZE(clkset_dispcon_list), +}; + +static struct clk *clkset_hsmmc44_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, + &s5p_clk_27m, + &clk_48m, +}; + +static struct clksrc_sources clkset_hsmmc44 = { + .sources = clkset_hsmmc44_list, + .nr_sources = ARRAY_SIZE(clkset_hsmmc44_list), +}; + +static struct clk *clkset_sclk_audio0_list[] = { + [0] = &clk_dout_epll.clk, + [1] = &clk_dout_mpll.clk, + [2] = &clk_ext_xtal_mux, + [3] = NULL, + [4] = NULL, +}; + +static struct clksrc_sources clkset_sclk_audio0 = { + .sources = clkset_sclk_audio0_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list), +}; + +static struct clksrc_clk clk_sclk_audio0 = { + .clk = { + .name = "audio-bus", + .id = -1, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 8), + .parent = &clk_dout_epll.clk, + }, + .sources = &clkset_sclk_audio0, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "sclk_mmc", + .id = 0, + .ctrlbit = (1 << 24), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 1, + .ctrlbit = (1 << 25), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 2, + .ctrlbit = (1 << 26), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 0, + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "aclk_mali", + .id = -1, + .ctrlbit = (1 << 2), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_mali, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_2d", + .id = -1, + .ctrlbit = (1 << 12), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_mali, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_usi", + .id = -1, + .ctrlbit = (1 << 7), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_camif", + .id = -1, + .ctrlbit = (1 << 6), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_dispcon", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_dispcon, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_hsmmc44", + .id = -1, + .ctrlbit = (1 << 30), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_hsmmc44, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 }, + }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *sysclks[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_dout_epll, + &clk_mout_mpll, + &clk_dout_mpll, + &clk_armclk, + &clk_mout_hclk_sel, + &clk_dout_pwm_ratio0, + &clk_pclk_to_wdt_pwm, + &clk_hclk, + &clk_pclk, + &clk_hclk_low, + &clk_pclk_low, + &clk_sclk_audio0, +}; + +void __init_or_cpufreq s5p6450_setup_clocks(void) +{ + struct clk *xtal_clk; + + unsigned long xtal; + unsigned long fclk; + unsigned long hclk; + unsigned long hclk_low; + unsigned long pclk; + unsigned long pclk_low; + + unsigned long apll; + unsigned long mpll; + unsigned long epll; + unsigned long dpll; + unsigned int ptr; + + /* Set S5P6450 functions for clk_fout_epll */ + + clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.ops = &s5p6450_epll_ops; + + clk_48m.enable = s5p64x0_clk48m_ctrl; + + xtal_clk = clk_get(NULL, "ext_xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502); + mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502); + epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON), + __raw_readl(S5P64X0_EPLL_CON_K)); + dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON), + __raw_readl(S5P6450_DPLL_CON_K), pll_4650c); + + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_dpll.rate = dpll; + + printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ + " E=%ld.%ldMHz, D=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll), + print_mhz(dpll)); + + fclk = clk_get_rate(&clk_armclk.clk); + hclk = clk_get_rate(&clk_hclk.clk); + pclk = clk_get_rate(&clk_pclk.clk); + hclk_low = clk_get_rate(&clk_hclk_low.clk); + pclk_low = clk_get_rate(&clk_pclk_low.clk); + + printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ + " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", + print_mhz(hclk), print_mhz(hclk_low), + print_mhz(pclk), print_mhz(pclk_low)); + + clk_f.rate = fclk; + clk_h.rate = hclk; + clk_p.rate = pclk; + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); +} + +void __init s5p6450_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c new file mode 100644 index 000000000000..523ba8039ac2 --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock.c @@ -0,0 +1,253 @@ +/* linux/arch/arm/mach-s5p64x0/clock.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Clock 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, + }, + .sources = &clk_src_apll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 0, .size = 1 }, +}; + +struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 1, .size = 1 }, +}; + +struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, + }, + .sources = &clk_src_epll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 2, .size = 1 }, +}; + +enum perf_level { + L0 = 532*1000, + L1 = 266*1000, + L2 = 133*1000, +}; + +static const u32 clock_table[][3] = { + /*{ARM_CLK, DIVarm, DIVhclk}*/ + {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, + {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, + {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, +}; + +int s5p64x0_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON); + else + __raw_writel(epll_con, S5P64X0_EPLL_CON); + + return 0; +} + +unsigned long s5p64x0_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +unsigned long s5p64x0_armclk_get_rate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + u32 clkdiv; + + /* divisor mask starts at bit0, so no need to shift */ + clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK; + + return rate / (clkdiv + 1); +} + +unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate) +{ + u32 iter; + + for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (rate > clock_table[iter][0]) + return clock_table[iter-1][0]; + } + + return clock_table[ARRAY_SIZE(clock_table) - 1][0]; +} + +int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate) +{ + u32 round_tmp; + u32 iter; + u32 clk_div0_tmp; + u32 cur_rate = clk->ops->get_rate(clk); + unsigned long flags; + + round_tmp = clk->ops->round_rate(clk, rate); + if (round_tmp == cur_rate) + return 0; + + + for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (round_tmp == clock_table[iter][0]) + break; + } + + if (iter >= ARRAY_SIZE(clock_table)) + iter = ARRAY_SIZE(clock_table) - 1; + + local_irq_save(flags); + if (cur_rate > round_tmp) { + /* Frequency Down */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P64X0_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + + } else { + /* Frequency Up */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P64X0_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + } + local_irq_restore(flags); + + clk->rate = clock_table[iter][0]; + + return 0; +} + +struct clk_ops s5p64x0_clkarm_ops = { + .get_rate = s5p64x0_armclk_get_rate, + .set_rate = s5p64x0_armclk_set_rate, + .round_rate = s5p64x0_armclk_round_rate, +}; + +struct clksrc_clk clk_armclk = { + .clk = { + .name = "armclk", + .id = 1, + .parent = &clk_mout_apll.clk, + .ops = &s5p64x0_clkarm_ops, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 0, .size = 4 }, +}; + +struct clksrc_clk clk_dout_mpll = { + .clk = { + .name = "dout_mpll", + .id = -1, + .parent = &clk_mout_mpll.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 }, +}; + +struct clk *clkset_hclk_low_list[] = { + &clk_mout_apll.clk, + &clk_mout_mpll.clk, +}; + +struct clksrc_sources clkset_hclk_low = { + .sources = clkset_hclk_low_list, + .nr_sources = ARRAY_SIZE(clkset_hclk_low_list), +}; + +int s5p64x0_pclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_PCLK, clk, enable); +} + +int s5p64x0_hclk0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK0, clk, enable); +} + +int s5p64x0_hclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK1, clk, enable); +} + +int s5p64x0_sclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK0, clk, enable); +} + +int s5p64x0_sclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK1, clk, enable); +} + +int s5p64x0_mem_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_MEM0, clk, enable); +} + +int s5p64x0_clk48m_ctrl(struct clk *clk, int enable) +{ + unsigned long flags; + u32 val; + + /* can't rely on clock lock, this register has other usages */ + local_irq_save(flags); + + val = __raw_readl(S5P64X0_OTHERS); + if (enable) + val |= S5P64X0_OTHERS_USB_SIG_MASK; + else + val &= ~S5P64X0_OTHERS_USB_SIG_MASK; + + __raw_writel(val, S5P64X0_OTHERS); + + local_irq_restore(flags); + + return 0; +} diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h new file mode 100644 index 000000000000..58e1bc813804 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h @@ -0,0 +1,63 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/regs-clock.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Clock register definitions + * + * 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_CLOCK_H +#define __ASM_ARCH_REGS_CLOCK_H __FILE__ + +#include + +#define S5P_CLKREG(x) (S3C_VA_SYS + (x)) + +#define S5P64X0_APLL_CON S5P_CLKREG(0x0C) +#define S5P64X0_MPLL_CON S5P_CLKREG(0x10) +#define S5P64X0_EPLL_CON S5P_CLKREG(0x14) +#define S5P64X0_EPLL_CON_K S5P_CLKREG(0x18) + +#define S5P64X0_CLK_SRC0 S5P_CLKREG(0x1C) + +#define S5P64X0_CLK_DIV0 S5P_CLKREG(0x20) +#define S5P64X0_CLK_DIV1 S5P_CLKREG(0x24) +#define S5P64X0_CLK_DIV2 S5P_CLKREG(0x28) + +#define S5P64X0_CLK_GATE_HCLK0 S5P_CLKREG(0x30) +#define S5P64X0_CLK_GATE_PCLK S5P_CLKREG(0x34) +#define S5P64X0_CLK_GATE_SCLK0 S5P_CLKREG(0x38) +#define S5P64X0_CLK_GATE_MEM0 S5P_CLKREG(0x3C) + +#define S5P64X0_CLK_DIV3 S5P_CLKREG(0x40) + +#define S5P64X0_CLK_GATE_HCLK1 S5P_CLKREG(0x44) +#define S5P64X0_CLK_GATE_SCLK1 S5P_CLKREG(0x48) + +#define S5P6450_DPLL_CON S5P_CLKREG(0x50) +#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54) + +#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C) + +#define S5P64X0_SYS_ID S5P_CLKREG(0x118) +#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C) + +#define S5P64X0_PWR_CFG S5P_CLKREG(0x804) +#define S5P64X0_OTHERS S5P_CLKREG(0x900) + +#define S5P64X0_CLKDIV0_HCLK_SHIFT (8) +#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT) + +#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16) + +/* Compatibility defines */ + +#define ARM_CLK_DIV S5P64X0_CLK_DIV0 +#define ARM_DIV_RATIO_SHIFT 0 +#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) + +#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h new file mode 100644 index 000000000000..ff85b4b6e8d9 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h @@ -0,0 +1,46 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for s5p64x0 clock 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. +*/ + +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H __FILE__ + +#include + +extern struct clksrc_clk clk_mout_apll; +extern struct clksrc_clk clk_mout_mpll; +extern struct clksrc_clk clk_mout_epll; + +extern int s5p64x0_epll_enable(struct clk *clk, int enable); +extern unsigned long s5p64x0_epll_get_rate(struct clk *clk); + +extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk); +extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate); +extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate); + +extern struct clk_ops s5p64x0_clkarm_ops; + +extern struct clksrc_clk clk_armclk; +extern struct clksrc_clk clk_dout_mpll; + +extern struct clk *clkset_hclk_low_list[]; +extern struct clksrc_sources clkset_hclk_low; + +extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable); +extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable); +extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable); +extern int s5p64x0_sclk_ctrl(struct clk *clk, int enable); +extern int s5p64x0_sclk1_ctrl(struct clk *clk, int enable); +extern int s5p64x0_mem_ctrl(struct clk *clk, int enable); + +extern int s5p64x0_clk48m_ctrl(struct clk *clk, int enable); + +#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index b5e255265f20..8aaf4e6b60c3 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -74,6 +74,13 @@ struct clk clk_fout_epll = { .ctrlbit = (1 << 31), }; +/* DPLL clock output */ +struct clk clk_fout_dpll = { + .name = "fout_dpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + /* VPLL clock output */ struct clk clk_fout_vpll = { .name = "fout_vpll", @@ -122,6 +129,17 @@ struct clksrc_sources clk_src_epll = { .nr_sources = ARRAY_SIZE(clk_src_epll_list), }; +/* Possible clock sources for DPLL Mux */ +static struct clk *clk_src_dpll_list[] = { + [0] = &clk_fin_dpll, + [1] = &clk_fout_dpll, +}; + +struct clksrc_sources clk_src_dpll = { + .sources = clk_src_dpll_list, + .nr_sources = ARRAY_SIZE(clk_src_dpll_list), +}; + struct clk clk_vpll = { .name = "vpll", .id = -1, @@ -145,6 +163,7 @@ static struct clk *s5p_clks[] __initdata = { &clk_fout_apll, &clk_fout_mpll, &clk_fout_epll, + &clk_fout_dpll, &clk_fout_vpll, &clk_arm, &clk_vpll, diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h index 4e8fe08cb70d..bf28fadee7ae 100644 --- a/arch/arm/plat-s5p/include/plat/pll.h +++ b/arch/arm/plat-s5p/include/plat/pll.h @@ -47,6 +47,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, } #define PLL46XX_KDIV_MASK (0xFFFF) +#define PLL4650C_KDIV_MASK (0xFFF) #define PLL46XX_MDIV_MASK (0x1FF) #define PLL46XX_PDIV_MASK (0x3F) #define PLL46XX_SDIV_MASK (0x7) @@ -57,6 +58,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, enum pll46xx_type_t { pll_4600, pll_4650, + pll_4650c, }; static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, @@ -72,6 +74,11 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; kdiv = pll_con1 & PLL46XX_KDIV_MASK; + if (pll_type == pll_4650c) + kdiv = pll_con1 & PLL4650C_KDIV_MASK; + else + kdiv = pll_con1 & PLL46XX_KDIV_MASK; + tmp = baseclk; if (pll_type == pll_4600) { diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 09418b1101fe..17036c898409 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -1,7 +1,7 @@ /* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h * - * Copyright 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Header file for s5p clock support * @@ -20,6 +20,7 @@ #define clk_fin_apll clk_ext_xtal_mux #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux +#define clk_fin_dpll clk_ext_xtal_mux #define clk_fin_vpll clk_ext_xtal_mux #define clk_fin_hpll clk_ext_xtal_mux @@ -30,6 +31,7 @@ extern struct clk s5p_clk_27m; extern struct clk clk_fout_apll; extern struct clk clk_fout_mpll; extern struct clk clk_fout_epll; +extern struct clk clk_fout_dpll; extern struct clk clk_fout_vpll; extern struct clk clk_arm; extern struct clk clk_vpll; @@ -37,8 +39,8 @@ extern struct clk clk_vpll; extern struct clksrc_sources clk_src_apll; extern struct clksrc_sources clk_src_mpll; extern struct clksrc_sources clk_src_epll; +extern struct clksrc_sources clk_src_dpll; -extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable); extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); #endif /* __ASM_PLAT_S5P_CLOCK_H */ -- cgit v1.2.3-59-g8ed1b From 2555e663b367b8d555e76023f4de3f6338c28d6c Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Wed, 1 Sep 2010 15:13:44 +0900 Subject: ARM: S5P64X0: Add UART serial support for S5P6450 This patch adds UART serial port support for S5P6450 SoC. The S5P6450 has 6 UARTs, so adds resource of UART4 and UART5. And to fix membase which is in serial/samsung.c is from Ben Dooks. Signed-off-by: Kukjin Kim Cc: Ben Dooks --- arch/arm/plat-s5p/dev-uart.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ drivers/serial/Kconfig | 7 +++--- drivers/serial/samsung.c | 2 +- 3 files changed, 63 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c index a89331ef4ae1..6a7342886171 100644 --- a/arch/arm/plat-s5p/dev-uart.c +++ b/arch/arm/plat-s5p/dev-uart.c @@ -119,6 +119,56 @@ static struct resource s5p_uart3_resource[] = { #endif }; +static struct resource s5p_uart4_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 + [0] = { + .start = S5P_PA_UART4, + .end = S5P_PA_UART4 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX4, + .end = IRQ_S5P_UART_RX4, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX4, + .end = IRQ_S5P_UART_TX4, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR4, + .end = IRQ_S5P_UART_ERR4, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + +static struct resource s5p_uart5_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 + [0] = { + .start = S5P_PA_UART5, + .end = S5P_PA_UART5 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX5, + .end = IRQ_S5P_UART_RX5, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX5, + .end = IRQ_S5P_UART_TX5, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR5, + .end = IRQ_S5P_UART_ERR5, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { [0] = { .resources = s5p_uart0_resource, @@ -136,4 +186,12 @@ struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { .resources = s5p_uart3_resource, .nr_resources = ARRAY_SIZE(s5p_uart3_resource), }, + [4] = { + .resources = s5p_uart4_resource, + .nr_resources = ARRAY_SIZE(s5p_uart4_resource), + }, + [5] = { + .resources = s5p_uart5_resource, + .nr_resources = ARRAY_SIZE(s5p_uart5_resource), + }, }; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 12900f7083b0..3198c5335f0b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS int depends on ARM && PLAT_SAMSUNG default 2 if ARCH_S3C2400 + default 6 if ARCH_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 default 3 help @@ -526,12 +527,12 @@ config SERIAL_S3C24A0 Serial port support for the Samsung S3C24A0 SoC config SERIAL_S3C6400 - tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100) + tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support" + depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100) select SERIAL_SAMSUNG_UARTS_4 default y help - Serial port support for the Samsung S3C6400, S3C6410, S5P6440 + Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450 and S5PC100 SoCs config SERIAL_S5PV210 diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index b1156ba8ad14..7ac2bf5167cd 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c @@ -1101,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); port->mapbase = res->start; - port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000); + port->membase = S3C_VA_UART + (res->start & 0xfffff); ret = platform_get_irq(platdev, 0); if (ret < 0) port->irq = 0; -- cgit v1.2.3-59-g8ed1b From 1d826d14cc2783d0c09750c2e1eeb2bdd358769b Mon Sep 17 00:00:00 2001 From: Jaecheol Lee Date: Wed, 15 Sep 2010 15:57:37 +0900 Subject: ARM: S5PV210: Add DMC map_desc table for supporting DMC access This patch adds DMC(DRAM Memory Controller) map_desc table. Because some driver such as CPUFREQ need to access DMC register. Signed-off-by: Jaecheol Lee Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/cpu.c | 10 ++++++++++ arch/arm/mach-s5pv210/include/mach/map.h | 3 +++ arch/arm/plat-s5p/include/plat/map-s5p.h | 2 ++ 3 files changed, 15 insertions(+) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 2f16bfc0a116..3347a23074b4 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -85,6 +85,16 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV210_PA_SROMC), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_DMC0, + .pfn = __phys_to_pfn(S5PV210_PA_DMC0), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_DMC1, + .pfn = __phys_to_pfn(S5PV210_PA_DMC1), + .length = SZ_4K, + .type = MT_DEVICE, } }; diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index bd9afd52466a..3e89c22412a3 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -96,6 +96,9 @@ #define S5PV210_PA_ADC (0xE1700000) +#define S5PV210_PA_DMC0 (0xF0000000) +#define S5PV210_PA_DMC1 (0xF1400000) + /* compatibiltiy defines. */ #define S3C_PA_UART S5PV210_PA_UART #define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index c4ff88bf6477..24728947682d 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -18,6 +18,8 @@ #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) #define S5P_VA_SROMC S3C_ADDR(0x01100000) #define S5P_VA_SYSRAM S3C_ADDR(0x01180000) +#define S5P_VA_DMC0 S3C_ADDR(0x00A00000) +#define S5P_VA_DMC1 S3C_ADDR(0x00A80000) #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) -- cgit v1.2.3-59-g8ed1b From 658bf4bef844c9a15e6700e1e27c939529f4a5ca Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 2 Oct 2010 12:45:25 +0900 Subject: ARM: S5P: Remove the unused clk_arm clock from plat-s5p All the S5P series SoCs use the 'struct clksrc_clk' type to represent the armclk. So the clk_arm clock instance available in the plat-s5p clock code is not used in any of the S5P series SoCs. This patch removes the unused clk_arm instance from plat-s5p clock code. Reported-by: Jaecheol Lee Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim --- arch/arm/plat-s5p/clock.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 8aaf4e6b60c3..818800962694 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -88,14 +88,6 @@ struct clk clk_fout_vpll = { .ctrlbit = (1 << 31), }; -/* ARM clock */ -struct clk clk_arm = { - .name = "armclk", - .id = -1, - .rate = 0, - .ctrlbit = 0, -}; - /* Possible clock sources for APLL Mux */ static struct clk *clk_src_apll_list[] = { [0] = &clk_fin_apll, @@ -165,7 +157,6 @@ static struct clk *s5p_clks[] __initdata = { &clk_fout_epll, &clk_fout_dpll, &clk_fout_vpll, - &clk_arm, &clk_vpll, &clk_xusbxti, }; -- cgit v1.2.3-59-g8ed1b From ca1931ca1e87c32f9abaef378c6996b25774cb02 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 29 Sep 2010 22:10:51 +0900 Subject: ARM: S5PV210: Enable USB HSOTG gadget build Add the necessary definitions and mapping information to enable the s3c-hsotg gadget to build. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/cpu.c | 5 +++++ arch/arm/mach-s5pv210/include/mach/map.h | 4 ++++ arch/arm/mach-s5pv210/include/mach/regs-sys.h | 19 +++++++++++++++++++ arch/arm/plat-s5p/include/plat/map-s5p.h | 1 + 4 files changed, 29 insertions(+) create mode 100644 arch/arm/mach-s5pv210/include/mach/regs-sys.h (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 3347a23074b4..8eb480e201b0 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -95,6 +95,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV210_PA_DMC1), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_USB_HSPHY, + .pfn =__phys_to_pfn(S5PV210_PA_HSPHY), + .length = SZ_4K, + .type = MT_DEVICE, } }; diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index 3e89c22412a3..12a409f964ca 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -73,6 +73,9 @@ #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) +#define S5PV210_PA_HSOTG (0xEC000000) +#define S5PV210_PA_HSPHY (0xEC100000) + #define S5PV210_PA_VIC0 (0xF2000000) #define S5PV210_PA_VIC1 (0xF2100000) #define S5PV210_PA_VIC2 (0xF2200000) @@ -111,6 +114,7 @@ #define S3C_PA_FB S5PV210_PA_FB #define S3C_PA_RTC S5PV210_PA_RTC #define S3C_PA_WDT S5PV210_PA_WATCHDOG +#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG #define S5P_PA_FIMC0 S5PV210_PA_FIMC0 #define S5P_PA_FIMC1 S5PV210_PA_FIMC1 #define S5P_PA_FIMC2 S5PV210_PA_FIMC2 diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h new file mode 100644 index 000000000000..26691d39d0f4 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h @@ -0,0 +1,19 @@ +/* arch/arm/mach-s5pv210/include/mach/regs-sys.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5PV210 - System registers definitions + * + * 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. +*/ + +#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) +#define S5PV210_USB_PHY0_EN (1 << 0) +#define S5PV210_USB_PHY1_EN (1 << 1) + +/* compatibility defines for s3c-hsotg driver */ +#define S3C64XX_OTHERS S5PV210_USB_PHY_CON +#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index 24728947682d..c833f3f21816 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -18,6 +18,7 @@ #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) #define S5P_VA_SROMC S3C_ADDR(0x01100000) #define S5P_VA_SYSRAM S3C_ADDR(0x01180000) +#define S3C_VA_USB_HSPHY S3C_ADDR(0x02000000) #define S5P_VA_DMC0 S3C_ADDR(0x00A00000) #define S5P_VA_DMC1 S3C_ADDR(0x00A80000) -- cgit v1.2.3-59-g8ed1b From 170a46177094b390299d1206748d7f15cd375dc9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 1 Oct 2010 10:40:37 +0900 Subject: ARM: S5P: Add common S5P GPIO Interrupt support This patch adds common code to enable support of GPIO interrupt on S5P SoCs. The total number of GPIO pins is quite large on S5P SoCs. Registering irq support for all of them would be a resource waste. Because of that the interrupt support for standard GPIO pins is registered dynamically by the s5p_register_gpio_interrupt() function. Signed-off-by: Marek Szyprowski Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park [kgene.kim@samsung.com: minor title fixes] Signed-off-by: Kukjin Kim --- arch/arm/plat-s5p/Kconfig | 5 + arch/arm/plat-s5p/Makefile | 1 + arch/arm/plat-s5p/include/plat/irqs.h | 9 + arch/arm/plat-s5p/irq-gpioint.c | 242 +++++++++++++++++++++++++ arch/arm/plat-samsung/include/plat/gpio-cfg.h | 18 ++ arch/arm/plat-samsung/include/plat/gpio-core.h | 4 + 6 files changed, 279 insertions(+) create mode 100644 arch/arm/plat-s5p/irq-gpioint.c (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 25960966af7c..65dbfa8e0a86 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -32,6 +32,11 @@ config S5P_EXT_INT Use the external interrupts (other than GPIO interrupts.) Note: Do not choose this for S5P6440 and S5P6450. +config S5P_GPIO_INT + bool + help + Common code for the GPIO interrupts (other than external interrupts.) + config S5P_DEV_FIMC0 bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index f3e917e27da8..e0823be3c8b9 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -18,6 +18,7 @@ obj-y += cpu.o obj-y += clock.o obj-y += irq.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o +obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o # devices diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 3fb3a3a17465..23603c7f1943 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -94,4 +94,13 @@ ((irq) - S5P_EINT_BASE1) : \ ((irq) + 16 - S5P_EINT_BASE2)) +/* Typically only a few gpio chips require gpio interrupt support. + To avoid memory waste irq descriptors are allocated only for + S5P_GPIOINT_GROUP_COUNT chips, each with total number of + S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged + to any gpio chip with the s5p_register_gpio_interrupt() function */ +#define S5P_GPIOINT_GROUP_COUNT 4 +#define S5P_GPIOINT_GROUP_SIZE 8 +#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE) + #endif /* __ASM_PLAT_S5P_IRQS_H */ diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c new file mode 100644 index 000000000000..32263a306c90 --- /dev/null +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -0,0 +1,242 @@ +/* linux/arch/arm/plat-s5p/irq-gpioint.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * Author: Kyungmin Park + * Author: Joonyoung Shim + * Author: Marek Szyprowski + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x)) + +#define GPIOINT_CON_OFFSET 0x700 +#define GPIOINT_MASK_OFFSET 0x900 +#define GPIOINT_PEND_OFFSET 0xA00 + +#define GPIOINT_LEVEL_LOW 0x0 +#define GPIOINT_LEVEL_HIGH 0x1 +#define GPIOINT_EDGE_FALLING 0x2 +#define GPIOINT_EDGE_RISING 0x3 +#define GPIOINT_EDGE_BOTH 0x4 + +static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR]; + +static int s5p_gpioint_get_group(unsigned int irq) +{ + struct gpio_chip *chip = get_irq_data(irq); + struct s3c_gpio_chip *s3c_chip = container_of(chip, + struct s3c_gpio_chip, chip); + int group; + + for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) + if (s3c_chip == irq_chips[group]) + break; + + return group; +} + +static int s5p_gpioint_get_offset(unsigned int irq) +{ + struct gpio_chip *chip = get_irq_data(irq); + struct s3c_gpio_chip *s3c_chip = container_of(chip, + struct s3c_gpio_chip, chip); + + return irq - s3c_chip->irq_base; +} + +static void s5p_gpioint_ack(unsigned int irq) +{ + int group, offset, pend_offset; + unsigned int value; + + group = s5p_gpioint_get_group(irq); + offset = s5p_gpioint_get_offset(irq); + pend_offset = group << 2; + + value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); + value |= 1 << offset; + __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset); +} + +static void s5p_gpioint_mask(unsigned int irq) +{ + int group, offset, mask_offset; + unsigned int value; + + group = s5p_gpioint_get_group(irq); + offset = s5p_gpioint_get_offset(irq); + mask_offset = group << 2; + + value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); + value |= 1 << offset; + __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); +} + +static void s5p_gpioint_unmask(unsigned int irq) +{ + int group, offset, mask_offset; + unsigned int value; + + group = s5p_gpioint_get_group(irq); + offset = s5p_gpioint_get_offset(irq); + mask_offset = group << 2; + + value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); + value &= ~(1 << offset); + __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset); +} + +static void s5p_gpioint_mask_ack(unsigned int irq) +{ + s5p_gpioint_mask(irq); + s5p_gpioint_ack(irq); +} + +static int s5p_gpioint_set_type(unsigned int irq, unsigned int type) +{ + int group, offset, con_offset; + unsigned int value; + + group = s5p_gpioint_get_group(irq); + offset = s5p_gpioint_get_offset(irq); + con_offset = group << 2; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + type = GPIOINT_EDGE_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + type = GPIOINT_EDGE_FALLING; + break; + case IRQ_TYPE_EDGE_BOTH: + type = GPIOINT_EDGE_BOTH; + break; + case IRQ_TYPE_LEVEL_HIGH: + type = GPIOINT_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + type = GPIOINT_LEVEL_LOW; + break; + case IRQ_TYPE_NONE: + default: + printk(KERN_WARNING "No irq type\n"); + return -EINVAL; + } + + value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset); + value &= ~(0x7 << (offset * 0x4)); + value |= (type << (offset * 0x4)); + __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset); + + return 0; +} + +struct irq_chip s5p_gpioint = { + .name = "s5p_gpioint", + .ack = s5p_gpioint_ack, + .mask = s5p_gpioint_mask, + .mask_ack = s5p_gpioint_mask_ack, + .unmask = s5p_gpioint_unmask, + .set_type = s5p_gpioint_set_type, +}; + +static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) +{ + int group, offset, pend_offset, mask_offset; + int real_irq; + unsigned int pend, mask; + + for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) { + pend_offset = group << 2; + pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + + pend_offset); + if (!pend) + continue; + + mask_offset = group << 2; + mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + + mask_offset); + pend &= ~mask; + + for (offset = 0; offset < 8; offset++) { + if (pend & (1 << offset)) { + struct s3c_gpio_chip *chip = irq_chips[group]; + if (chip) { + real_irq = chip->irq_base + offset; + generic_handle_irq(real_irq); + } + } + } + } +} + +static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) +{ + static int used_gpioint_groups = 0; + static bool handler_registered = 0; + int irq, group = chip->group; + int i; + + if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) + return -ENOMEM; + + chip->irq_base = S5P_GPIOINT_BASE + + used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; + used_gpioint_groups++; + + if (!handler_registered) { + set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler); + handler_registered = 1; + } + + irq_chips[group] = chip; + for (i = 0; i < chip->chip.ngpio; i++) { + irq = chip->irq_base + i; + set_irq_chip(irq, &s5p_gpioint); + set_irq_data(irq, &chip->chip); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + return 0; +} + +int __init s5p_register_gpio_interrupt(int pin) +{ + struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin); + int offset, group; + int ret; + + if (!my_chip) + return -EINVAL; + + offset = pin - my_chip->chip.base; + group = my_chip->group; + + /* check if the group has been already registered */ + if (my_chip->irq_base) + return my_chip->irq_base + offset; + + /* register gpio group */ + ret = s5p_gpioint_add(my_chip); + if (ret == 0) { + printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", + group); + return my_chip->irq_base + offset; + } + return ret; +} diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 1c6b92947c5d..5b43b95da68e 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h @@ -169,4 +169,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin); */ extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); +/** + * s5p_register_gpio_interrupt() - register interrupt support for a gpio group + * @pin: The pin number from the group to be registered + * + * This function registers gpio interrupt support for the group that the + * specified pin belongs to. + * + * The total number of gpio pins is quite large ob s5p series. Registering + * irq support for all of them would be a resource waste. Because of that the + * interrupt support for standard gpio pins is registered dynamically. + * + * It will return the irq number of the interrupt that has been registered + * or -ENOMEM if no more gpio interrupts can be registered. It is allowed + * to call this function more than once for the same gpio group (the group + * will be registered only once). + */ +extern int s5p_register_gpio_interrupt(int pin); + #endif /* __PLAT_GPIO_CFG_H */ diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index e358c7da8480..c22c27ca675a 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -43,6 +43,8 @@ struct s3c_gpio_cfg; * struct s3c_gpio_chip - wrapper for specific implementation of gpio * @chip: The chip structure to be exported via gpiolib. * @base: The base pointer to the gpio configuration registers. + * @group: The group register number for gpio interrupt support. + * @irq_base: The base irq number. * @config: special function and pull-resistor control information. * @lock: Lock for exclusive access to this gpio bank. * @pm_save: Save information for suspend/resume support. @@ -63,6 +65,8 @@ struct s3c_gpio_chip { struct s3c_gpio_cfg *config; struct s3c_gpio_pm *pm; void __iomem *base; + int irq_base; + int group; spinlock_t lock; #ifdef CONFIG_PM u32 pm_save[4]; -- cgit v1.2.3-59-g8ed1b From 8ce14a221efe8ef9019e2c5b1e06fcd329e66d78 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 1 Oct 2010 11:24:39 +0900 Subject: ARM: SAMSUNG: Add common samsung_gpiolib_to_irq function This patch adds a common callback for gpio_to_irq() for external and gpio interrupts for Samsung SoCs. Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Cc: Ben Dooks [kgene.kim@samsung.com: moved samsung_gpiolib_to_irq() for s3c24xx build] Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/gpiolib.c | 8 ++----- arch/arm/mach-s5pc100/gpiolib.c | 31 +++++++------------------- arch/arm/mach-s5pv210/gpiolib.c | 8 +++++++ arch/arm/plat-s3c24xx/gpiolib.c | 8 ++----- arch/arm/plat-s5p/irq-gpioint.c | 1 + arch/arm/plat-samsung/gpio.c | 8 +++++++ arch/arm/plat-samsung/include/plat/gpio-core.h | 11 +++++++++ 7 files changed, 40 insertions(+), 35 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c index 300dee4a667b..fd99a82e82c4 100644 --- a/arch/arm/mach-s3c64xx/gpiolib.c +++ b/arch/arm/mach-s3c64xx/gpiolib.c @@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { .get_pull = s3c_gpio_getpull_updown, }; -int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin) -{ - return IRQ_EINT(0) + pin; -} - static struct s3c_gpio_chip gpio_2bit[] = { { .base = S3C64XX_GPF_BASE, @@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPN_BASE, + .irq_base = IRQ_EINT(0), .config = &gpio_2bit_cfg_eint10, .chip = { .base = S3C64XX_GPN(0), .ngpio = S3C64XX_GPIO_N_NR, .label = "GPN", - .to_irq = s3c64xx_gpio2int_gpn, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S3C64XX_GPO_BASE, diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c index 5811578ad4e4..def4ff83e051 100644 --- a/arch/arm/mach-s5pc100/gpiolib.c +++ b/arch/arm/mach-s5pc100/gpiolib.c @@ -61,25 +61,6 @@ * L3 8 4Bit None */ -static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset) -{ - int base; - - base = chip->base - S5PC100_GPH0(0); - if (base == 0) - return IRQ_EINT(offset); - base = chip->base - S5PC100_GPH1(0); - if (base == 0) - return IRQ_EINT(8 + offset); - base = chip->base - S5PC100_GPH2(0); - if (base == 0) - return IRQ_EINT(16 + offset); - base = chip->base - S5PC100_GPH3(0); - if (base == 0) - return IRQ_EINT(24 + offset); - return -EINVAL; -} - static struct s3c_gpio_cfg gpio_cfg = { .set_config = s3c_gpio_setcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, @@ -223,38 +204,42 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { }, { .base = S5PC100_GPH0_BASE, .config = &gpio_cfg_eint, + .irq_base = IRQ_EINT(0), .chip = { .base = S5PC100_GPH0(0), .ngpio = S5PC100_GPIO_H0_NR, .label = "GPH0", - .to_irq = s5pc100_gpiolib_to_eint, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S5PC100_GPH1_BASE, .config = &gpio_cfg_eint, + .irq_base = IRQ_EINT(8), .chip = { .base = S5PC100_GPH1(0), .ngpio = S5PC100_GPIO_H1_NR, .label = "GPH1", - .to_irq = s5pc100_gpiolib_to_eint, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S5PC100_GPH2_BASE, .config = &gpio_cfg_eint, + .irq_base = IRQ_EINT(16), .chip = { .base = S5PC100_GPH2(0), .ngpio = S5PC100_GPIO_H2_NR, .label = "GPH2", - .to_irq = s5pc100_gpiolib_to_eint, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S5PC100_GPH3_BASE, .config = &gpio_cfg_eint, + .irq_base = IRQ_EINT(24), .chip = { .base = S5PC100_GPH3(0), .ngpio = S5PC100_GPIO_H3_NR, .label = "GPH3", - .to_irq = s5pc100_gpiolib_to_eint, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S5PC100_GPI_BASE, diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c index 29dfb894d4f4..ab673effd767 100644 --- a/arch/arm/mach-s5pv210/gpiolib.c +++ b/arch/arm/mach-s5pv210/gpiolib.c @@ -224,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { }, { .base = (S5P_VA_GPIO + 0xC00), .config = &gpio_cfg_noint, + .irq_base = IRQ_EINT(0), .chip = { .base = S5PV210_GPH0(0), .ngpio = S5PV210_GPIO_H0_NR, .label = "GPH0", + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = (S5P_VA_GPIO + 0xC20), .config = &gpio_cfg_noint, + .irq_base = IRQ_EINT(8), .chip = { .base = S5PV210_GPH1(0), .ngpio = S5PV210_GPIO_H1_NR, .label = "GPH1", + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = (S5P_VA_GPIO + 0xC40), .config = &gpio_cfg_noint, + .irq_base = IRQ_EINT(16), .chip = { .base = S5PV210_GPH2(0), .ngpio = S5PV210_GPIO_H2_NR, .label = "GPH2", + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = (S5P_VA_GPIO + 0xC60), .config = &gpio_cfg_noint, + .irq_base = IRQ_EINT(24), .chip = { .base = S5PV210_GPH3(0), .ngpio = S5PV210_GPIO_H3_NR, .label = "GPH3", + .to_irq = samsung_gpiolib_to_irq, }, }, }; diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 4c0896f2572d..243b6411050d 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset) return -EINVAL; } -static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset) -{ - return IRQ_EINT8 + offset; -} - static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { .set_config = s3c_gpio_setcfg_s3c24xx_a, .get_config = s3c_gpio_getcfg_s3c24xx_a, @@ -157,12 +152,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = { [6] = { .base = S3C2410_GPGCON, .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .irq_base = IRQ_EINT8, .chip = { .base = S3C2410_GPG(0), .owner = THIS_MODULE, .label = "GPIOG", .ngpio = 16, - .to_irq = s3c24xx_gpiolib_bankg_toirq, + .to_irq = samsung_gpiolib_to_irq, }, }, { .base = S3C2410_GPHCON, diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 32263a306c90..768fd39a3a98 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -234,6 +234,7 @@ int __init s5p_register_gpio_interrupt(int pin) /* register gpio group */ ret = s5p_gpioint_add(my_chip); if (ret == 0) { + my_chip->chip.to_irq = samsung_gpiolib_to_irq; printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", group); return my_chip->irq_base + offset; diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c index b83a83351cea..7743c4b8b2fb 100644 --- a/arch/arm/plat-samsung/gpio.c +++ b/arch/arm/plat-samsung/gpio.c @@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) if (ret >= 0) s3c_gpiolib_track(chip); } + +int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct s3c_gpio_chip *s3c_chip = container_of(chip, + struct s3c_gpio_chip, chip); + + return s3c_chip->irq_base + offset; +} diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index c22c27ca675a..13a22b8861ef 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -122,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); + +/** + * samsung_gpiolib_to_irq - convert gpio pin to irq number + * @chip: The gpio chip that the pin belongs to. + * @offset: The offset of the pin in the chip. + * + * This helper returns the irq number calculated from the chip->irq_base and + * the provided offset. + */ +extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset); + /* exported for core SoC support to change */ extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; -- cgit v1.2.3-59-g8ed1b From 9adf5d222cfbbc4b7e972bfe3472368f9b453091 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Sat, 2 Oct 2010 11:48:09 +0900 Subject: ARM: S5P: Unify defines for both gpio interrupt types Samsung S5P SoCs have the same interrupt type defines for both external interrupts and gpio interrupts. This patch removes all duplicates from S5PC100 and S5PV210 specific includes as well as gpio interrupt code and put a common defines to plat/irqs.h NOTE: Do not use this for S5P6440 and S5P6450. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park [kgene.kim@samsung.com: add note for S5P64X0] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pc100/include/mach/regs-gpio.h | 7 ------- arch/arm/mach-s5pv210/include/mach/regs-gpio.h | 7 ------- arch/arm/plat-s5p/include/plat/irqs.h | 7 +++++++ arch/arm/plat-s5p/irq-eint.c | 10 +++++----- arch/arm/plat-s5p/irq-gpioint.c | 16 +++++----------- 5 files changed, 17 insertions(+), 30 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h index 6abe481e248d..8c47536b117b 100644 --- a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h @@ -64,13 +64,6 @@ #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) -/* values for S5P_EXTINT0 */ -#define S5P_EXTINT_LOWLEV (0x00) -#define S5P_EXTINT_HILEV (0x01) -#define S5P_EXTINT_FALLEDGE (0x02) -#define S5P_EXTINT_RISEEDGE (0x03) -#define S5P_EXTINT_BOTHEDGE (0x04) - #define EINT_MODE S3C_GPIO_SFN(0x2) #define EINT_GPIO_0(x) S5PC100_GPH0(x) diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h index 49e029b4978a..de0c89976078 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h @@ -31,13 +31,6 @@ #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) -/* values for S5P_EXTINT0 */ -#define S5P_EXTINT_LOWLEV (0x00) -#define S5P_EXTINT_HILEV (0x01) -#define S5P_EXTINT_FALLEDGE (0x02) -#define S5P_EXTINT_RISEEDGE (0x03) -#define S5P_EXTINT_BOTHEDGE (0x04) - #define EINT_MODE S3C_GPIO_SFN(0xf) #define EINT_GPIO_0(x) S5PV210_GPH0(x) diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 23603c7f1943..7f653bce3c13 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -103,4 +103,11 @@ #define S5P_GPIOINT_GROUP_SIZE 8 #define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE) +/* IRQ types common for all s5p platforms */ +#define S5P_IRQ_TYPE_LEVEL_LOW (0x00) +#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01) +#define S5P_IRQ_TYPE_EDGE_FALLING (0x02) +#define S5P_IRQ_TYPE_EDGE_RISING (0x03) +#define S5P_IRQ_TYPE_EDGE_BOTH (0x04) + #endif /* __ASM_PLAT_S5P_IRQS_H */ diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index f36cd3327025..752f1a645f9d 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) switch (type) { case IRQ_TYPE_EDGE_RISING: - newvalue = S5P_EXTINT_RISEEDGE; + newvalue = S5P_IRQ_TYPE_EDGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: - newvalue = S5P_EXTINT_FALLEDGE; + newvalue = S5P_IRQ_TYPE_EDGE_FALLING; break; case IRQ_TYPE_EDGE_BOTH: - newvalue = S5P_EXTINT_BOTHEDGE; + newvalue = S5P_IRQ_TYPE_EDGE_BOTH; break; case IRQ_TYPE_LEVEL_LOW: - newvalue = S5P_EXTINT_LOWLEV; + newvalue = S5P_IRQ_TYPE_LEVEL_LOW; break; case IRQ_TYPE_LEVEL_HIGH: - newvalue = S5P_EXTINT_HILEV; + newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; break; default: diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 768fd39a3a98..0e5dc8cbf5e3 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -28,12 +28,6 @@ #define GPIOINT_MASK_OFFSET 0x900 #define GPIOINT_PEND_OFFSET 0xA00 -#define GPIOINT_LEVEL_LOW 0x0 -#define GPIOINT_LEVEL_HIGH 0x1 -#define GPIOINT_EDGE_FALLING 0x2 -#define GPIOINT_EDGE_RISING 0x3 -#define GPIOINT_EDGE_BOTH 0x4 - static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR]; static int s5p_gpioint_get_group(unsigned int irq) @@ -118,19 +112,19 @@ static int s5p_gpioint_set_type(unsigned int irq, unsigned int type) switch (type) { case IRQ_TYPE_EDGE_RISING: - type = GPIOINT_EDGE_RISING; + type = S5P_IRQ_TYPE_EDGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: - type = GPIOINT_EDGE_FALLING; + type = S5P_IRQ_TYPE_EDGE_FALLING; break; case IRQ_TYPE_EDGE_BOTH: - type = GPIOINT_EDGE_BOTH; + type = S5P_IRQ_TYPE_EDGE_BOTH; break; case IRQ_TYPE_LEVEL_HIGH: - type = GPIOINT_LEVEL_HIGH; + type = S5P_IRQ_TYPE_LEVEL_HIGH; break; case IRQ_TYPE_LEVEL_LOW: - type = GPIOINT_LEVEL_LOW; + type = S5P_IRQ_TYPE_LEVEL_LOW; break; case IRQ_TYPE_NONE: default: -- cgit v1.2.3-59-g8ed1b From ea31fd4330c823bd156d6484e32a0777c35f200f Mon Sep 17 00:00:00 2001 From: Jongpill Lee Date: Sat, 2 Oct 2010 19:13:42 +0900 Subject: ARM: S5PV210: Add Power Management Support This patch adds suspend-to-ram support for S5PV210. Note. This patch is confirmed on SMDKV210 and SMDKC110 board. Signed-off-by: Jongpill Lee Signed-off-by: Sangbeom Kim Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/Kconfig | 6 + arch/arm/mach-s5pv210/Makefile | 1 + arch/arm/mach-s5pv210/include/mach/pm-core.h | 43 ++++++ arch/arm/mach-s5pv210/include/mach/regs-clock.h | 7 +- arch/arm/mach-s5pv210/mach-smdkc110.c | 3 + arch/arm/mach-s5pv210/mach-smdkv210.c | 3 + arch/arm/mach-s5pv210/pm.c | 166 +++++++++++++++++++++++ arch/arm/mach-s5pv210/sleep.S | 170 ++++++++++++++++++++++++ arch/arm/plat-s5p/Makefile | 2 + arch/arm/plat-s5p/irq-pm.c | 93 +++++++++++++ arch/arm/plat-s5p/pm.c | 52 ++++++++ arch/arm/plat-samsung/pm-gpio.c | 4 +- 12 files changed, 546 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-s5pv210/include/mach/pm-core.h create mode 100644 arch/arm/mach-s5pv210/pm.c create mode 100644 arch/arm/mach-s5pv210/sleep.S create mode 100644 arch/arm/plat-s5p/irq-pm.c create mode 100644 arch/arm/plat-s5p/pm.c (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index af2a8132eaba..640b590dc365 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -13,6 +13,7 @@ config CPU_S5PV210 bool select S3C_PL330_DMA select S5P_EXT_INT + select S5PV210_PM if PM help Enable S5PV210 CPU support @@ -152,4 +153,9 @@ config MACH_TORBRECK endmenu +config S5PV210_PM + bool + help + Power Management code common to S5PV210 + endif diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 226f335b2d4a..157754f0a919 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -14,6 +14,7 @@ obj- := obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o +obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o # machine support diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h new file mode 100644 index 000000000000..e8d394f8b057 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h @@ -0,0 +1,43 @@ +/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h, + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c + * + * 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. +*/ + +static inline void s3c_pm_debug_init_uart(void) +{ + /* nothing here yet */ +} + +static inline void s3c_pm_arch_prepare_irqs(void) +{ + __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); + __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); +} + +static inline void s3c_pm_arch_stop_clocks(void) +{ + /* nothing here yet */ +} + +static inline void s3c_pm_arch_show_resume_irqs(void) +{ + /* nothing here yet */ +} + +static inline void s3c_pm_arch_update_uart(void __iomem *regs, + struct pm_uart_save *save) +{ + /* nothing here yet */ +} diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h index 499aef737476..929fd3a33f8a 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h @@ -95,7 +95,7 @@ /* Registers related to power management */ #define S5P_PWR_CFG S5P_CLKREG(0xC000) #define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) -#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) +#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) #define S5P_PWR_MODE S5P_CLKREG(0xC00C) #define S5P_NORMAL_CFG S5P_CLKREG(0xC010) #define S5P_IDLE_CFG S5P_CLKREG(0xC020) @@ -159,8 +159,11 @@ #define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) /* OTHERS Resgister */ +#define S5P_OTHERS_RET_IO (1 << 31) +#define S5P_OTHERS_RET_CF (1 << 30) +#define S5P_OTHERS_RET_MMC (1 << 29) +#define S5P_OTHERS_RET_UART (1 << 28) #define S5P_OTHERS_USB_SIG_MASK (1 << 16) -#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28) /* MIPI */ #define S5P_MIPI_DPHY_EN (3) diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 8211bb87c54b..053b50ddcfaa 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Following are default values for UCON, ULCON and UFCON UART registers */ #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ @@ -110,6 +111,8 @@ static void __init smdkc110_map_io(void) static void __init smdkc110_machine_init(void) { + s3c_pm_init(); + s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_i2c2_set_platdata(NULL); diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index fbbc0a3c3738..5a9c79cb63bd 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Following are default values for UCON, ULCON and UFCON UART registers */ #define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ @@ -145,6 +146,8 @@ static void __init smdkv210_map_io(void) static void __init smdkv210_machine_init(void) { + s3c_pm_init(); + samsung_keypad_set_platdata(&smdkv210_keypad_data); s3c24xx_ts_set_platdata(&s3c_ts_platform); diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c new file mode 100644 index 000000000000..549d7924fd4c --- /dev/null +++ b/arch/arm/mach-s5pv210/pm.c @@ -0,0 +1,166 @@ +/* linux/arch/arm/mach-s5pv210/pm.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV210 - Power Management support + * + * Based on arch/arm/mach-s3c2410/pm.c + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * 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 + +#include +#include + +static struct sleep_save s5pv210_core_save[] = { + /* Clock source */ + SAVE_ITEM(S5P_CLK_SRC0), + SAVE_ITEM(S5P_CLK_SRC1), + SAVE_ITEM(S5P_CLK_SRC2), + SAVE_ITEM(S5P_CLK_SRC3), + SAVE_ITEM(S5P_CLK_SRC4), + SAVE_ITEM(S5P_CLK_SRC5), + SAVE_ITEM(S5P_CLK_SRC6), + + /* Clock source Mask */ + SAVE_ITEM(S5P_CLK_SRC_MASK0), + SAVE_ITEM(S5P_CLK_SRC_MASK1), + + /* Clock Divider */ + SAVE_ITEM(S5P_CLK_DIV0), + SAVE_ITEM(S5P_CLK_DIV1), + SAVE_ITEM(S5P_CLK_DIV2), + SAVE_ITEM(S5P_CLK_DIV3), + SAVE_ITEM(S5P_CLK_DIV4), + SAVE_ITEM(S5P_CLK_DIV5), + SAVE_ITEM(S5P_CLK_DIV6), + SAVE_ITEM(S5P_CLK_DIV7), + + /* Clock Main Gate */ + SAVE_ITEM(S5P_CLKGATE_MAIN0), + SAVE_ITEM(S5P_CLKGATE_MAIN1), + SAVE_ITEM(S5P_CLKGATE_MAIN2), + + /* Clock source Peri Gate */ + SAVE_ITEM(S5P_CLKGATE_PERI0), + SAVE_ITEM(S5P_CLKGATE_PERI1), + + /* Clock source SCLK Gate */ + SAVE_ITEM(S5P_CLKGATE_SCLK0), + SAVE_ITEM(S5P_CLKGATE_SCLK1), + + /* Clock IP Clock gate */ + SAVE_ITEM(S5P_CLKGATE_IP0), + SAVE_ITEM(S5P_CLKGATE_IP1), + SAVE_ITEM(S5P_CLKGATE_IP2), + SAVE_ITEM(S5P_CLKGATE_IP3), + SAVE_ITEM(S5P_CLKGATE_IP4), + + /* Clock Blcok and Bus gate */ + SAVE_ITEM(S5P_CLKGATE_BLOCK), + SAVE_ITEM(S5P_CLKGATE_BUS0), + + /* Clock ETC */ + SAVE_ITEM(S5P_CLK_OUT), + SAVE_ITEM(S5P_MDNIE_SEL), + + /* PWM Register */ + SAVE_ITEM(S3C2410_TCFG0), + SAVE_ITEM(S3C2410_TCFG1), + SAVE_ITEM(S3C64XX_TINT_CSTAT), + SAVE_ITEM(S3C2410_TCON), + SAVE_ITEM(S3C2410_TCNTB(0)), + SAVE_ITEM(S3C2410_TCMPB(0)), + SAVE_ITEM(S3C2410_TCNTO(0)), +}; + +void s5pv210_cpu_suspend(void) +{ + unsigned long tmp; + + /* issue the standby signal into the pm unit. Note, we + * issue a write-buffer drain just in case */ + + tmp = 0; + + asm("b 1f\n\t" + ".align 5\n\t" + "1:\n\t" + "mcr p15, 0, %0, c7, c10, 5\n\t" + "mcr p15, 0, %0, c7, c10, 4\n\t" + "wfi" : : "r" (tmp)); + + /* we should never get past here */ + panic("sleep resumed to originator?"); +} + +static void s5pv210_pm_prepare(void) +{ + unsigned int tmp; + + /* ensure at least INFORM0 has the resume address */ + __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); + + tmp = __raw_readl(S5P_SLEEP_CFG); + tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); + __raw_writel(tmp, S5P_SLEEP_CFG); + + /* WFI for SLEEP mode configuration by SYSCON */ + tmp = __raw_readl(S5P_PWR_CFG); + tmp &= S5P_CFG_WFI_CLEAN; + tmp |= S5P_CFG_WFI_SLEEP; + __raw_writel(tmp, S5P_PWR_CFG); + + /* SYSCON interrupt handling disable */ + tmp = __raw_readl(S5P_OTHERS); + tmp |= S5P_OTHER_SYSC_INTOFF; + __raw_writel(tmp, S5P_OTHERS); + + s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); +} + +static int s5pv210_pm_add(struct sys_device *sysdev) +{ + pm_cpu_prep = s5pv210_pm_prepare; + pm_cpu_sleep = s5pv210_cpu_suspend; + + return 0; +} + +static int s5pv210_pm_resume(struct sys_device *dev) +{ + u32 tmp; + + tmp = __raw_readl(S5P_OTHERS); + tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\ + S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART); + __raw_writel(tmp , S5P_OTHERS); + + s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); + + return 0; +} + +static struct sysdev_driver s5pv210_pm_driver = { + .add = s5pv210_pm_add, + .resume = s5pv210_pm_resume, +}; + +static __init int s5pv210_pm_drvinit(void) +{ + return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver); +} +arch_initcall(s5pv210_pm_drvinit); diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S new file mode 100644 index 000000000000..d4d222b716b4 --- /dev/null +++ b/arch/arm/mach-s5pv210/sleep.S @@ -0,0 +1,170 @@ +/* linux/arch/arm/plat-s5p/sleep.S + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV210 power Manager (Suspend-To-RAM) support + * Based on S3C2410 sleep code by: + * Ben Dooks, (c) 2004 Simtec Electronics + * + * Based on PXA/SA1100 sleep code by: + * Nicolas Pitre, (c) 2002 Monta Vista Software Inc + * Cliff Brake, (c) 2001 + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + + .text + + /* s3c_cpu_save + * + * entry: + * r0 = save address (virtual addr of s3c_sleep_save_phys) + */ + +ENTRY(s3c_cpu_save) + + stmfd sp!, { r3 - r12, lr } + + mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID + mrc p15, 0, r5, c3, c0, 0 @ Domain ID + mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 + mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 + mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control + mrc p15, 0, r9, c1, c0, 0 @ Control register + mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register + mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls + mrc p15, 0, r12, c10, c2, 0 @ Read PRRR + mrc p15, 0, r3, c10, c2, 1 @ READ NMRR + + stmia r0, { r3 - r13 } + + bl s3c_pm_cb_flushcache + + ldr r0, =pm_cpu_sleep + ldr r0, [ r0 ] + mov pc, r0 + +resume_with_mmu: + /* + * After MMU is turned on, restore the previous MMU table. + */ + ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET) + add r4, r4, r9 + str r12, [r4] + + ldmfd sp!, { r3 - r12, pc } + + .ltorg + + .data + + .global s3c_sleep_save_phys +s3c_sleep_save_phys: + .word 0 + + /* sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the + * s3c_cpu_resume entry. + */ + + .word 0x2bedf00d + + /* s3c_cpu_resume + * + * resume code entry for bootloader to call + * + * we must put this code here in the data segment as we have no + * other way of restoring the stack pointer after sleep, and we + * must not write to the code segment (code is read-only) + */ + +ENTRY(s3c_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r0 + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache + + ldr r0, s3c_sleep_save_phys @ address of restore block + ldmia r0, { r3 - r13 } + + mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID + mcr p15, 0, r5, c3, c0, 0 @ Domain ID + + mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control + mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 + mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 + + mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register + + mov r0, #0 + mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB + + mov r0, #0 @ restore copro access + mcr p15, 0, r11, c1, c0, 2 @ Co-processor access + mcr p15, 0, r0, c7, c5, 4 + + mcr p15, 0, r12, c10, c2, 0 @ write PRRR + mcr p15, 0, r3, c10, c2, 1 @ write NMRR + + /* + * In Cortex-A8, when MMU is turned on, the pipeline is flushed. + * And there are no valid entries in the MMU table at this point. + * So before turning on the MMU, the MMU entry for the DRAM address + * range is added. After the MMU is turned on, the other entries + * in the MMU table will be restored. + */ + + /* r6 = Translation Table BASE0 */ + mov r4, r6 + mov r4, r4, LSR #14 + mov r4, r4, LSL #14 + + /* Load address for adding to MMU table list */ + ldr r11, =0xE010F000 @ INFORM0 reg. + ldr r10, [r11, #0] + mov r10, r10, LSR #18 + bic r10, r10, #0x3 + orr r4, r4, r10 + + /* Calculate MMU table entry */ + mov r10, r10, LSL #18 + ldr r5, =0x40E + orr r10, r10, r5 + + /* Back up originally data */ + ldr r12, [r4] + + /* Add calculated MMU table entry into MMU table list */ + str r10, [r4] + + ldr r2, =resume_with_mmu + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc + + nop + nop + nop + nop + nop @ second-to-last before mmu + + mov pc, r2 @ go back to virtual address + + .ltorg diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index e0823be3c8b9..de65238a7aef 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -19,6 +19,8 @@ obj-y += clock.o obj-y += irq.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o +obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_PM) += irq-pm.o # devices diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c new file mode 100644 index 000000000000..dc33b9ecda45 --- /dev/null +++ b/arch/arm/plat-s5p/irq-pm.c @@ -0,0 +1,93 @@ +/* linux/arch/arm/plat-s5p/irq-pm.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/plat-s3c24xx/irq-pm.c, + * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * 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 +#include +#include + +#include +#include + +/* state for IRQs over sleep */ + +/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM, + * as wakeup sources + * + * set bit to 1 in allow bitfield to enable the wakeup settings on it +*/ + +unsigned long s3c_irqwake_intallow = 0x00000006L; +unsigned long s3c_irqwake_eintallow = 0xffffffffL; + +int s3c_irq_wake(unsigned int irqno, unsigned int state) +{ + unsigned long irqbit; + + switch (irqno) { + case IRQ_RTC_TIC: + case IRQ_RTC_ALARM: + irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM); + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= ~irqbit; + break; + default: + return -ENOENT; + } + return 0; +} + +static struct sleep_save eint_save[] = { + SAVE_ITEM(S5P_EINT_CON(0)), + SAVE_ITEM(S5P_EINT_CON(1)), + SAVE_ITEM(S5P_EINT_CON(2)), + SAVE_ITEM(S5P_EINT_CON(3)), + + SAVE_ITEM(S5P_EINT_FLTCON(0)), + SAVE_ITEM(S5P_EINT_FLTCON(1)), + SAVE_ITEM(S5P_EINT_FLTCON(2)), + SAVE_ITEM(S5P_EINT_FLTCON(3)), + SAVE_ITEM(S5P_EINT_FLTCON(4)), + SAVE_ITEM(S5P_EINT_FLTCON(5)), + SAVE_ITEM(S5P_EINT_FLTCON(6)), + SAVE_ITEM(S5P_EINT_FLTCON(7)), + + SAVE_ITEM(S5P_EINT_MASK(0)), + SAVE_ITEM(S5P_EINT_MASK(1)), + SAVE_ITEM(S5P_EINT_MASK(2)), + SAVE_ITEM(S5P_EINT_MASK(3)), +}; + +int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) +{ + s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); + + return 0; +} + +int s3c24xx_irq_resume(struct sys_device *dev) +{ + s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); + + return 0; +} + diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c new file mode 100644 index 000000000000..d592b6304b48 --- /dev/null +++ b/arch/arm/plat-s5p/pm.c @@ -0,0 +1,52 @@ +/* linux/arch/arm/plat-s5p/pm.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P Power Manager (Suspend-To-RAM) support + * + * Based on arch/arm/plat-s3c24xx/pm.c + * Copyright (c) 2004,2006 Simtec Electronics + * Ben Dooks + * + * 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 + +#define PFX "s5p pm: " + +/* s3c_pm_check_resume_pin + * + * check to see if the pin is configured correctly for sleep mode, and + * make any necessary adjustments if it is not +*/ + +static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) +{ + /* nothing here yet */ +} + +/* s3c_pm_configure_extint + * + * configure all external interrupt pins +*/ + +void s3c_pm_configure_extint(void) +{ + /* nothing here yet */ +} + +void s3c_pm_restore_core(void) +{ + /* nothing here yet */ +} + +void s3c_pm_save_core(void) +{ + /* nothing here yet */ +} + diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c index 7df03f87fbfa..96528200eb79 100644 --- a/arch/arm/plat-samsung/pm-gpio.c +++ b/arch/arm/plat-samsung/pm-gpio.c @@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = { .resume = s3c_gpio_pm_2bit_resume, }; -#ifdef CONFIG_ARCH_S3C64XX +#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) { chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); @@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = { .save = s3c_gpio_pm_4bit_save, .resume = s3c_gpio_pm_4bit_resume, }; -#endif /* CONFIG_ARCH_S3C64XX */ +#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */ /** * s3c_pm_save_gpio() - save gpio chip data for suspend -- cgit v1.2.3-59-g8ed1b From dc6c0ca39daad44f3169656296ef81d39a6dc7f5 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 14 Oct 2010 15:35:07 +0900 Subject: ARM: S5P: Fix missed IRQ_EINT_BIT() When merged patches, missed IRQ_EINT_BIT() definition from commit ea31fd43 (ARM: S5PV210: Add Power Management Support). The IRQ_EINT_BIT() is used in the Power Management operation (plat-samsung/pm.c). Signed-off-by: Kukjin Kim --- arch/arm/plat-s5p/include/plat/irqs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 7f653bce3c13..ba9121c60a2a 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -94,6 +94,8 @@ ((irq) - S5P_EINT_BASE1) : \ ((irq) + 16 - S5P_EINT_BASE2)) +#define IRQ_EINT_BIT(x) EINT_OFFSET(x) + /* Typically only a few gpio chips require gpio interrupt support. To avoid memory waste irq descriptors are allocated only for S5P_GPIOINT_GROUP_COUNT chips, each with total number of -- cgit v1.2.3-59-g8ed1b From dd56d2df56485553f4777f68e0ead87fbb02f706 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Tue, 5 Oct 2010 10:49:38 +0900 Subject: ARM: S5P: Cleanup the S5P SoCs' VA address mapping Basically S5P SoCs use the Samsung common VA address mapping where plat-samsung and use plat-s5p's mapping also. The later is a little mess. So this patch cleans it up. Cc: Ben Dooks Signed-off-by: Kukjin Kim --- arch/arm/plat-s5p/include/plat/map-s5p.h | 40 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index c833f3f21816..ec96a193f5e1 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -13,27 +13,35 @@ #ifndef __ASM_PLAT_MAP_S5P_H #define __ASM_PLAT_MAP_S5P_H __FILE__ -#define S5P_VA_CHIPID S3C_ADDR(0x00700000) -#define S5P_VA_GPIO S3C_ADDR(0x00500000) -#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) -#define S5P_VA_SROMC S3C_ADDR(0x01100000) -#define S5P_VA_SYSRAM S3C_ADDR(0x01180000) -#define S3C_VA_USB_HSPHY S3C_ADDR(0x02000000) -#define S5P_VA_DMC0 S3C_ADDR(0x00A00000) -#define S5P_VA_DMC1 S3C_ADDR(0x00A80000) - -#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) +#define S5P_VA_CHIPID S3C_ADDR(0x02000000) +#define S5P_VA_CMU S3C_ADDR(0x02100000) +#define S5P_VA_GPIO S3C_ADDR(0x02200000) + +#define S5P_VA_SYSRAM S3C_ADDR(0x02400000) +#define S5P_VA_DMC0 S3C_ADDR(0x02440000) +#define S5P_VA_DMC1 S3C_ADDR(0x02480000) +#define S5P_VA_SROMC S3C_ADDR(0x024C0000) + +#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000) +#define S5P_VA_L2CC S3C_ADDR(0x02600000) + +#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000) #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) -#define S5P_VA_COREPERI_BASE S3C_ADDR(0x00800000) +#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) #define S5P_VA_SCU S5P_VA_COREPERI(0x0) #define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) #define S5P_VA_TWD S5P_VA_COREPERI(0x600) #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) -#define S5P_VA_L2CC S3C_ADDR(0x00900000) -#define S5P_VA_CMU S3C_ADDR(0x00920000) +#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000) + +#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) +#define VA_VIC0 VA_VIC(0) +#define VA_VIC1 VA_VIC(1) +#define VA_VIC2 VA_VIC(2) +#define VA_VIC3 VA_VIC(3) #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) #define S5P_VA_UART0 S5P_VA_UART(0) @@ -45,10 +53,4 @@ #define S3C_UART_OFFSET (0x400) #endif -#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) -#define VA_VIC0 VA_VIC(0) -#define VA_VIC1 VA_VIC(1) -#define VA_VIC2 VA_VIC(2) -#define VA_VIC3 VA_VIC(3) - #endif /* __ASM_PLAT_MAP_S5P_H */ -- cgit v1.2.3-59-g8ed1b From d4b34c6c849d67b7afaa90d55dc7fab981c72950 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Thu, 14 Oct 2010 10:39:08 +0900 Subject: ARM: S5P: Reduce duplicated EPLL control codes S5P Samsung SoCs has a EPLL to support various PLL clock sources for other H/W blocks. Until now, to control EPLL, each of SoCs make their own functions in 'mach-s5pxxx/clock.c'. But some of functions, 'xxx_epll_get_rate()' and 'xxx_epll_enable()', are exactly same in all S5P SoCs, so this patch move these duplicated codes to common EPLL functions that use platform wide. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/clock-s5p6440.c | 4 ++-- arch/arm/mach-s5p64x0/clock-s5p6450.c | 4 ++-- arch/arm/mach-s5p64x0/clock.c | 18 ------------------ arch/arm/mach-s5p64x0/include/mach/regs-clock.h | 2 ++ arch/arm/mach-s5pc100/clock.c | 22 ++-------------------- arch/arm/mach-s5pv310/include/mach/regs-clock.h | 4 ++++ arch/arm/plat-s5p/clock.c | 20 ++++++++++++++++++++ arch/arm/plat-s5p/include/plat/s5p-clock.h | 4 ++++ 8 files changed, 36 insertions(+), 42 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index f93dcd8b4d6a..cfccdff744d2 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -85,7 +85,7 @@ static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) } static struct clk_ops s5p6440_epll_ops = { - .get_rate = s5p64x0_epll_get_rate, + .get_rate = s5p_epll_get_rate, .set_rate = s5p6440_epll_set_rate, }; @@ -548,7 +548,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) /* Set S5P6440 functions for clk_fout_epll */ - clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.enable = s5p_epll_enable; clk_fout_epll.ops = &s5p6440_epll_ops; clk_48m.enable = s5p64x0_clk48m_ctrl; diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index f9afb05b217c..f1498d35111b 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -86,7 +86,7 @@ static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate) } static struct clk_ops s5p6450_epll_ops = { - .get_rate = s5p64x0_epll_get_rate, + .get_rate = s5p_epll_get_rate, .set_rate = s5p6450_epll_set_rate, }; @@ -581,7 +581,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void) /* Set S5P6450 functions for clk_fout_epll */ - clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.enable = s5p_epll_enable; clk_fout_epll.ops = &s5p6450_epll_ops; clk_48m.enable = s5p64x0_clk48m_ctrl; diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c index 523ba8039ac2..b52c6e2f37a6 100644 --- a/arch/arm/mach-s5p64x0/clock.c +++ b/arch/arm/mach-s5p64x0/clock.c @@ -73,24 +73,6 @@ static const u32 clock_table[][3] = { {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, }; -int s5p64x0_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON); - else - __raw_writel(epll_con, S5P64X0_EPLL_CON); - - return 0; -} - -unsigned long s5p64x0_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - unsigned long s5p64x0_armclk_get_rate(struct clk *clk) { unsigned long rate = clk_get_rate(clk->parent); diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h index 58e1bc813804..a133f22fa155 100644 --- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h +++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h @@ -60,4 +60,6 @@ #define ARM_DIV_RATIO_SHIFT 0 #define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) +#define S5P_EPLL_CON S5P64X0_EPLL_CON + #endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 306ae743ad72..42c2636ca3ac 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = { .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, }; -static int s5pc100_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); - else - __raw_writel(epll_con, S5P_EPLL_CON); - - return 0; -} - -static unsigned long s5pc100_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - static u32 epll_div[][4] = { { 32750000, 131, 3, 4 }, { 32768000, 131, 3, 4 }, @@ -347,7 +329,7 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate) } static struct clk_ops s5pc100_epll_ops = { - .get_rate = s5pc100_epll_get_rate, + .get_rate = s5p_epll_get_rate, .set_rate = s5pc100_epll_set_rate, }; @@ -1261,7 +1243,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void) unsigned int ptr; /* Set S5PC100 functions for clk_fout_epll */ - clk_fout_epll.enable = s5pc100_epll_enable; + clk_fout_epll.enable = s5p_epll_enable; clk_fout_epll.ops = &s5pc100_epll_ops; printk(KERN_DEBUG "%s: registering clocks\n", __func__); diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index 12e983c11ad4..f1028cad9788 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h @@ -84,4 +84,8 @@ #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) +/* Compatibility defines */ + +#define S5P_EPLL_CON S5P_EPLL_CON0 + #endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 818800962694..8d081d968c58 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -148,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) return 0; } +int s5p_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); + else + __raw_writel(epll_con, S5P_EPLL_CON); + + return 0; +} + +unsigned long s5p_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + static struct clk *s5p_clks[] __initdata = { &clk_ext_xtal_mux, &clk_48m, diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 17036c898409..2b6dcff8ab2b 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll; extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); +/* Common EPLL operations for S5P platform */ +extern int s5p_epll_enable(struct clk *clk, int enable); +extern unsigned long s5p_epll_get_rate(struct clk *clk); + #endif /* __ASM_PLAT_S5P_CLOCK_H */ -- cgit v1.2.3-59-g8ed1b From 37ea63b14bec667957ca3cfaa899c6e103fdb854 Mon Sep 17 00:00:00 2001 From: Jongpill Lee Date: Thu, 14 Oct 2010 15:46:18 +0900 Subject: ARM: S5P: Add initial map for GPIO2 and GPIO3 This patch adds initial map for GPIO2 and GPIO3. S5PV310/S5PC210 has separated GPIO1, GPIO2 and GPIO3. Signed-off-by: Jongpill Lee Signed-off-by: Sangbeom Kim Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpu.c | 12 +++++++++++- arch/arm/plat-s5p/include/plat/map-s5p.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 66beac424e40..5b9790054421 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -57,10 +57,20 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_GPIO, + .virtual = (unsigned long)S5P_VA_GPIO1, .pfn = __phys_to_pfn(S5PV310_PA_GPIO1), .length = SZ_4K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO2, + .pfn = __phys_to_pfn(S5PV310_PA_GPIO2), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO3, + .pfn = __phys_to_pfn(S5PV310_PA_GPIO3), + .length = SZ_256, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_UART, .pfn = __phys_to_pfn(S3C_PA_UART), diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index ec96a193f5e1..fef353d44513 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -16,6 +16,9 @@ #define S5P_VA_CHIPID S3C_ADDR(0x02000000) #define S5P_VA_CMU S3C_ADDR(0x02100000) #define S5P_VA_GPIO S3C_ADDR(0x02200000) +#define S5P_VA_GPIO1 S5P_VA_GPIO +#define S5P_VA_GPIO2 S3C_ADDR(0x02240000) +#define S5P_VA_GPIO3 S3C_ADDR(0x02280000) #define S5P_VA_SYSRAM S3C_ADDR(0x02400000) #define S5P_VA_DMC0 S3C_ADDR(0x02440000) -- cgit v1.2.3-59-g8ed1b