From 0deac0bf66110fe70507c5dcec661c9e85fa07ca Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Mar 2010 20:36:22 +0000 Subject: ARM: Arrange for COMMON_CLKDEV to select HAVE_CLK If support for COMMON_CLKDEV is enabled, we have CLK support. Signed-off-by: Russell King --- arch/arm/Kconfig | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..bcaa8c83e522 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -238,7 +238,6 @@ config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" select ARM_AMBA select ARCH_HAS_CPUFREQ - select HAVE_CLK select COMMON_CLKDEV select ICST525 help @@ -247,7 +246,6 @@ config ARCH_INTEGRATOR config ARCH_REALVIEW bool "ARM Ltd. RealView family" select ARM_AMBA - select HAVE_CLK select COMMON_CLKDEV select ICST307 select GENERIC_TIME @@ -260,7 +258,6 @@ config ARCH_VERSATILE bool "ARM Ltd. Versatile family" select ARM_AMBA select ARM_VIC - select HAVE_CLK select COMMON_CLKDEV select ICST307 select GENERIC_TIME @@ -321,7 +318,6 @@ config ARCH_EP93XX select ARM_AMBA select ARM_VIC select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_HOLES_MEMORYMODEL @@ -341,7 +337,6 @@ config ARCH_MXC select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select COMMON_CLKDEV help Support for Freescale MXC/iMX-based family of processors @@ -349,7 +344,6 @@ config ARCH_MXC config ARCH_STMP3XXX bool "Freescale STMP3xxx" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME @@ -516,7 +510,6 @@ config ARCH_MMP depends on MMU select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -552,7 +545,6 @@ config ARCH_W90X900 select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -568,7 +560,6 @@ config ARCH_W90X900 config ARCH_NUC93X bool "Nuvoton NUC93X CPU" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV help Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a @@ -577,7 +568,6 @@ config ARCH_NUC93X config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV help This enables support for Philips PNX4008 mobile platform. @@ -588,7 +578,6 @@ config ARCH_PXA select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select GENERIC_GPIO - select HAVE_CLK select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select GENERIC_TIME @@ -743,7 +732,6 @@ config ARCH_U300 select ARM_VIC select GENERIC_TIME select GENERIC_CLOCKEVENTS - select HAVE_CLK select COMMON_CLKDEV select GENERIC_GPIO help @@ -764,7 +752,6 @@ config ARCH_NOMADIK select ARM_AMBA select ARM_VIC select CPU_ARM926T - select HAVE_CLK select COMMON_CLKDEV select GENERIC_TIME select GENERIC_CLOCKEVENTS @@ -780,7 +767,6 @@ config ARCH_DAVINCI select GENERIC_CLOCKEVENTS select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK select ZONE_DMA select HAVE_IDE select COMMON_CLKDEV -- cgit v1.2.3 From 94bdc0e2d76c5f2467346bf14e7e16d6d8e0395d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 3 Mar 2010 04:54:37 +0100 Subject: ARM: 5973/1: ux500: add gpio support Add support for the GPIOs on the U8500, using the plat-nomadik GPIO driver. Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-u8500.c | 82 ++++++++++++++++++++++++++++- arch/arm/mach-ux500/include/mach/gpio.h | 12 +++++ arch/arm/mach-ux500/include/mach/hardware.h | 12 +++++ arch/arm/mach-ux500/include/mach/irqs.h | 8 ++- 6 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-ux500/include/mach/gpio.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..540f85922113 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -756,6 +756,7 @@ config ARCH_U8500 select GENERIC_TIME select GENERIC_CLOCKEVENTS select COMMON_CLKDEV + select ARCH_REQUIRE_GPIOLIB help Support for ST-Ericsson's Ux500 architecture diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 03625d744857..cd412a3e0ab8 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -8,6 +8,7 @@ config MACH_U8500_MOP default y select ARM_GIC select HAS_MTU + select NOMADIK_GPIO help Include support for mop500 development platform based on U8500 architecture. The platform is based diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c index 09bcba1ccef1..5fb44661adaf 100644 --- a/arch/arm/mach-ux500/cpu-u8500.c +++ b/arch/arm/mach-ux500/cpu-u8500.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -23,9 +24,82 @@ #include #include -/* add any platform devices here - TODO */ +#define GPIO_RESOURCE(block) \ + { \ + .start = U8500_GPIOBANK##block##_BASE, \ + .end = U8500_GPIOBANK##block##_BASE + 127, \ + .flags = IORESOURCE_MEM, \ + }, \ + { \ + .start = IRQ_GPIO##block, \ + .end = IRQ_GPIO##block, \ + .flags = IORESOURCE_IRQ, \ + } + +#define GPIO_DEVICE(block) \ + { \ + .name = "gpio", \ + .id = block, \ + .num_resources = 2, \ + .resource = &u8500_gpio_resources[block * 2], \ + .dev = { \ + .platform_data = &u8500_gpio_data[block], \ + }, \ + } + +#define GPIO_DATA(_name, first) \ + { \ + .name = _name, \ + .first_gpio = first, \ + .first_irq = NOMADIK_GPIO_TO_IRQ(first), \ + } + +static struct nmk_gpio_platform_data u8500_gpio_data[] = { + GPIO_DATA("GPIO-0-31", 0), + GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ + GPIO_DATA("GPIO-64-95", 64), + GPIO_DATA("GPIO-96-127", 96), /* 97..127 not routed to pin */ + GPIO_DATA("GPIO-128-159", 128), + GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */ + GPIO_DATA("GPIO-192-223", 192), + GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */ + GPIO_DATA("GPIO-256-288", 256), /* 258..288 not routed to pin */ +}; + +static struct resource u8500_gpio_resources[] = { + GPIO_RESOURCE(0), + GPIO_RESOURCE(1), + GPIO_RESOURCE(2), + GPIO_RESOURCE(3), + GPIO_RESOURCE(4), + GPIO_RESOURCE(5), + GPIO_RESOURCE(6), + GPIO_RESOURCE(7), + GPIO_RESOURCE(8), +}; + +static struct platform_device u8500_gpio_devs[] = { + GPIO_DEVICE(0), + GPIO_DEVICE(1), + GPIO_DEVICE(2), + GPIO_DEVICE(3), + GPIO_DEVICE(4), + GPIO_DEVICE(5), + GPIO_DEVICE(6), + GPIO_DEVICE(7), + GPIO_DEVICE(8), +}; + static struct platform_device *platform_devs[] __initdata = { - /* yet to be added, add i2c0, gpio.. */ + &u8500_gpio_devs[0], + &u8500_gpio_devs[1], + &u8500_gpio_devs[2], + &u8500_gpio_devs[3], + &u8500_gpio_devs[4], + &u8500_gpio_devs[5], + &u8500_gpio_devs[6], + &u8500_gpio_devs[7], + &u8500_gpio_devs[8], }; #define __IO_DEV_DESC(x, sz) { \ @@ -49,6 +123,10 @@ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), + __IO_DEV_DESC(U8500_GPIO5_BASE, SZ_4K), }; static struct map_desc u8500ed_io_desc[] __initdata = { diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h new file mode 100644 index 000000000000..3c4cd31ad9f7 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/gpio.h @@ -0,0 +1,12 @@ +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +/* + * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough + * room for a couple of GPIO expanders. + */ +#define ARCH_NR_GPIOS 350 + +#include + +#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index f29a43d9d45a..99ca89fe9b30 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -23,6 +23,8 @@ /* typesafe io address */ #define __io_address(n) __io(IO_ADDRESS(n)) +/* used by some plat-nomadik code */ +#define io_p2v(n) __io_address(n) /* * Base address definitions for U8500 Onchip IPs. All the @@ -128,6 +130,16 @@ #define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xe000) #define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000) +#define U8500_GPIOBANK0_BASE U8500_GPIO1_BASE +#define U8500_GPIOBANK1_BASE (U8500_GPIO1_BASE + 0x80) +#define U8500_GPIOBANK2_BASE U8500_GPIO3_BASE +#define U8500_GPIOBANK3_BASE (U8500_GPIO3_BASE + 0x80) +#define U8500_GPIOBANK4_BASE (U8500_GPIO3_BASE + 0x100) +#define U8500_GPIOBANK5_BASE (U8500_GPIO3_BASE + 0x180) +#define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE +#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80) +#define U8500_GPIOBANK8_BASE U8500_GPIO5_BASE + /* ST-Ericsson modified pl022 id */ #define SSP_PER_ID 0x01080022 diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 394b5dd2200f..8a1f6976c245 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h @@ -66,6 +66,12 @@ /* There are 128 shared peripheral interrupts assigned to * INTID[160:32]. The first 32 interrupts are reserved. */ -#define NR_IRQS 161 +#define U8500_SOC_NR_IRQS 161 + +/* After chip-specific IRQ numbers we have the GPIO ones */ +#define NOMADIK_NR_GPIO 288 +#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + U8500_SOC_NR_IRQS) +#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - U8500_SOC_NR_IRQS) +#define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) #endif /*ASM_ARCH_IRQS_H*/ -- cgit v1.2.3 From 5cfc8ee0bb5134e1204e1ec5843e164f24315021 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 24 Mar 2010 00:22:36 +0000 Subject: ARM: convert arm to arch_gettimeoffset() Convert arm to use GENERIC_TIME via the arch_getoffset() infrastructure, reducing the amount of arch specific code we need to maintain. The arm architecture is the last arch that need to be converted. Signed-off-by: John Stultz Signed-off-by: Russell King Cc: Andrew Morton --- arch/arm/Kconfig | 23 +++++++++++++ arch/arm/include/asm/mach/time.h | 2 +- arch/arm/kernel/time.c | 70 ++++------------------------------------ arch/arm/mach-at91/Kconfig | 1 + 4 files changed, 31 insertions(+), 65 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bcaa8c83e522..bf856f492eb5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -42,6 +42,11 @@ config GENERIC_GPIO config GENERIC_TIME bool + default y + +config ARCH_USES_GETTIMEOFFSET + bool + default n config GENERIC_CLOCKEVENTS bool @@ -231,6 +236,7 @@ config ARCH_AAEC2000 select CPU_ARM920T select ARM_AMBA select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Agilent AAEC-2000 @@ -271,6 +277,7 @@ config ARCH_AT91 select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 and AT91CAP9 processors. @@ -290,6 +297,7 @@ config ARCH_BCMRING config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x-based" select CPU_ARM720T + select ARCH_USES_GETTIMEOFFSET help Support for Cirrus Logic 711x/721x based boards. @@ -298,6 +306,7 @@ config ARCH_GEMINI select CPU_FA526 select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select ARCH_USES_GETTIMEOFFSET help Support for the Cortina Systems Gemini family SoCs @@ -306,6 +315,7 @@ config ARCH_EBSA110 select CPU_SA110 select ISA select NO_IOPORT + select ARCH_USES_GETTIMEOFFSET help This is an evaluation board for the StrongARM processor available from Digital. It has limited hardware on-board, including an @@ -321,6 +331,7 @@ config ARCH_EP93XX select COMMON_CLKDEV select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_HOLES_MEMORYMODEL + select ARCH_USES_GETTIMEOFFSET help This enables support for the Cirrus EP93xx series of CPUs. @@ -328,6 +339,7 @@ config ARCH_FOOTBRIDGE bool "FootBridge" select CPU_SA110 select FOOTBRIDGE + select ARCH_USES_GETTIMEOFFSET help Support for systems based on the DC21285 companion chip ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. @@ -366,6 +378,7 @@ config ARCH_H720X bool "Hynix HMS720x-based" select CPU_ARM720T select ISA_DMA_API + select ARCH_USES_GETTIMEOFFSET help This enables support for systems based on the Hynix HMS720x @@ -408,6 +421,7 @@ config ARCH_IXP23XX depends on MMU select CPU_XSC3 select PCI + select ARCH_USES_GETTIMEOFFSET help Support for Intel's IXP23xx (XScale) family of processors. @@ -416,6 +430,7 @@ config ARCH_IXP2000 depends on MMU select CPU_XSCALE select PCI + select ARCH_USES_GETTIMEOFFSET help Support for Intel's IXP2400/2800 (XScale) family of processors. @@ -434,6 +449,7 @@ config ARCH_L7200 bool "LinkUp-L7200" select CPU_ARM720T select FIQ + select ARCH_USES_GETTIMEOFFSET help Say Y here if you intend to run this kernel on a LinkUp Systems L7200 Software Development Board which uses an ARM720T processor. @@ -523,6 +539,7 @@ config ARCH_KS8695 select CPU_ARM922T select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB + select ARCH_USES_GETTIMEOFFSET help Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based System-on-Chip devices. @@ -569,6 +586,7 @@ config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T select COMMON_CLKDEV + select ARCH_USES_GETTIMEOFFSET help This enables support for Philips PNX4008 mobile platform. @@ -613,6 +631,7 @@ config ARCH_RPC select ISA_DMA_API select NO_IOPORT select ARCH_SPARSEMEM_ENABLE + select ARCH_USES_GETTIMEOFFSET help On the Acorn Risc-PC, Linux can support the internal IDE disk and CD-ROM interface, serial and parallel port, and the floppy drive. @@ -639,6 +658,7 @@ config ARCH_S3C2410 select GENERIC_GPIO select ARCH_HAS_CPUFREQ select HAVE_CLK + select ARCH_USES_GETTIMEOFFSET help Samsung S3C2410X CPU based systems, such as the Simtec Electronics BAST (), the IPAQ 1940 or @@ -652,6 +672,7 @@ config ARCH_S3C64XX select ARM_VIC select HAVE_CLK select NO_IOPORT + select ARCH_USES_GETTIMEOFFSET select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select SAMSUNG_CLKSRC @@ -708,6 +729,7 @@ config ARCH_SHARK select ISA_DMA select ZONE_DMA select PCI + select ARCH_USES_GETTIMEOFFSET help Support for the StrongARM based Digital DNARD machine, also known as "Shark" (). @@ -717,6 +739,7 @@ config ARCH_LH7A40X select CPU_ARM922T select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM + select ARCH_USES_GETTIMEOFFSET help Say Y here for systems based on one of the Sharp LH7A40X System on a Chip processors. These CPUs include an ARM922T diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h index 8bffc3ff3acf..35d408f6dccf 100644 --- a/arch/arm/include/asm/mach/time.h +++ b/arch/arm/include/asm/mach/time.h @@ -38,7 +38,7 @@ struct sys_timer { void (*init)(void); void (*suspend)(void); void (*resume)(void); -#ifndef CONFIG_GENERIC_TIME +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET unsigned long (*offset)(void); #endif }; diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 28753805d2d1..38c261f9951c 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -72,12 +72,15 @@ unsigned long profile_pc(struct pt_regs *regs) EXPORT_SYMBOL(profile_pc); #endif -#ifndef CONFIG_GENERIC_TIME -static unsigned long dummy_gettimeoffset(void) +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET +u32 arch_gettimeoffset(void) { + if (system_timer->offset != NULL) + return system_timer->offset() * 1000; + return 0; } -#endif +#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */ #ifdef CONFIG_LEDS_TIMER static inline void do_leds(void) @@ -93,63 +96,6 @@ static inline void do_leds(void) #define do_leds() #endif -#ifndef CONFIG_GENERIC_TIME -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - unsigned long usec, sec; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - usec = system_timer->offset(); - sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - /* usec may have gone up a lot: be safe */ - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - time_t wtm_sec, sec = tv->tv_sec; - long wtm_nsec, nsec = tv->tv_nsec; - - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_seqlock_irq(&xtime_lock); - /* - * This is revolting. We need to set "xtime" correctly. However, the - * value in this location is the value at the most recent update of - * wall time. Discover what correction gettimeofday() would have - * done, and then undo it! - */ - nsec -= system_timer->offset() * NSEC_PER_USEC; - - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); - - set_normalized_timespec(&xtime, sec, nsec); - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - - ntp_clear(); - write_sequnlock_irq(&xtime_lock); - clock_was_set(); - return 0; -} - -EXPORT_SYMBOL(do_settimeofday); -#endif /* !CONFIG_GENERIC_TIME */ #ifndef CONFIG_GENERIC_CLOCKEVENTS /* @@ -214,10 +160,6 @@ device_initcall(timer_init_sysfs); void __init time_init(void) { -#ifndef CONFIG_GENERIC_TIME - if (system_timer->offset == NULL) - system_timer->offset = dummy_gettimeoffset; -#endif system_timer->init(); } diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 2db43a5ddd9b..8a5e8e9fe448 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -97,6 +97,7 @@ config ARCH_AT572D940HF config ARCH_AT91X40 bool "AT91x40" + select ARCH_USES_GETTIMEOFFSET endchoice -- cgit v1.2.3 From cee37e501ea34958d6d33d75d2bd21d9c343e379 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Thu, 1 Apr 2010 12:31:05 +0100 Subject: ARM: 6016/1: ST SPEAr: Added support for SPEAr platform and machines in arch/arm/ Reviewed-by: Linus Walleij Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/Kconfig | 13 +++++++++++++ arch/arm/Makefile | 5 +++++ 2 files changed, 18 insertions(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..1459231bcbb3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -801,6 +801,18 @@ config ARCH_OMAP help Support for TI's OMAP platform (OMAP1 and OMAP2). +config PLAT_SPEAR + bool "ST SPEAr" + select ARM_AMBA + select ARCH_REQUIRE_GPIOLIB + select COMMON_CLKDEV + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO + select GENERIC_TIME + select HAVE_CLK + help + Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx). + endchoice # @@ -886,6 +898,7 @@ source "arch/arm/plat-samsung/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-s5pc1xx/Kconfig" +source "arch/arm/plat-spear/Kconfig" if ARCH_S3C2410 source "arch/arm/mach-s3c2400/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..b3a3518a36fd 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -178,6 +178,10 @@ machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_ARCH_NUC93X) := nuc93x machine-$(CONFIG_FOOTBRIDGE) := footbridge +machine-$(CONFIG_MACH_SPEAR300) := spear3xx +machine-$(CONFIG_MACH_SPEAR310) := spear3xx +machine-$(CONFIG_MACH_SPEAR320) := spear3xx +machine-$(CONFIG_MACH_SPEAR600) := spear6xx # Platform directory name. This list is sorted alphanumerically # by CONFIG_* macro name. @@ -192,6 +196,7 @@ plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx samsung plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_SPEAR) := spear ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. -- cgit v1.2.3 From 6e8699f7d68589e0e9ab324f598a3357bceb40bc Mon Sep 17 00:00:00 2001 From: Albin Tonnerre Date: Sat, 3 Apr 2010 11:40:28 +0100 Subject: ARM: 6026/1: ARM: Add support for LZMA-compressed kernel images This patch allows using a kernel image compressed with LZMA on ARM. Extracting the image is fairly slow, but it might be useful on machines with a very limited amount of storage, as the size benefit is quite significant (about 25% smaller with LZMA compared to GZIP) Tested-by: Martin Michlmayr Tested-by: Paulius Zaleckas Signed-off-by: Albin Tonnerre Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/boot/compressed/Makefile | 1 + arch/arm/boot/compressed/decompress.c | 4 ++++ arch/arm/boot/compressed/piggy.lzma.S | 6 ++++++ 4 files changed, 12 insertions(+) create mode 100644 arch/arm/boot/compressed/piggy.lzma.S (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf856f492eb5..5c8128c76996 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -21,6 +21,7 @@ config ARM select HAVE_GENERIC_DMA_COHERENT select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO + select HAVE_KERNEL_LZMA select HAVE_PERF_EVENTS select PERF_USE_VMALLOC help diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 97c89e7de7d3..53faa9063a03 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -65,6 +65,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ suffix_$(CONFIG_KERNEL_GZIP) = gzip suffix_$(CONFIG_KERNEL_LZO) = lzo +suffix_$(CONFIG_KERNEL_LZMA) = lzma targets := vmlinux vmlinux.lds \ piggy.$(suffix_y) piggy.$(suffix_y).o \ diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index 9c097073ce4c..4c72a97bc3e1 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -40,6 +40,10 @@ extern void error(char *); #include "../../../../lib/decompress_unlzo.c" #endif +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { decompress(input, len, NULL, NULL, output, NULL, error); diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S new file mode 100644 index 000000000000..d7e69cffbc0a --- /dev/null +++ b/arch/arm/boot/compressed/piggy.lzma.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.lzma" + .globl input_data_end +input_data_end: -- cgit v1.2.3 From 52882173cfed4fabcc1496755000bf022d681e52 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 19 Apr 2010 13:20:49 +0100 Subject: ARM: 6058/1: Add support for PCI domains This patch adds support for PCI domains on ARM platforms. Also, protect asm/mach/pci.h from multiple inclustions, otherwise build fails because of pci_domain_nr() and pci_proc_domain() redefinitions. Signed-off-by: Anton Vorontsov Signed-off-by: Russell King --- arch/arm/Kconfig | 4 ++++ arch/arm/include/asm/mach/pci.h | 11 +++++++++++ arch/arm/include/asm/pci.h | 15 +++++++++++++++ arch/arm/kernel/bios32.c | 3 +++ 4 files changed, 33 insertions(+) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c8128c76996..88f9334110cf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1074,6 +1074,10 @@ config PCI your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or VESA. If you have PCI, say Y, otherwise N. +config PCI_DOMAINS + bool + depends on PCI + config PCI_SYSCALL def_bool PCI diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index a38bdc7afa34..52f0da1e97df 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -8,10 +8,16 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_MACH_PCI_H +#define __ASM_MACH_PCI_H + struct pci_sys_data; struct pci_bus; struct hw_pci { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif struct list_head buses; int nr_controllers; int (*setup)(int nr, struct pci_sys_data *); @@ -26,6 +32,9 @@ struct hw_pci { * Per-controller structure */ struct pci_sys_data { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif struct list_head node; int busnr; /* primary bus number */ u64 mem_offset; /* bus->cpu memory mapping offset */ @@ -70,3 +79,5 @@ extern int pci_v3_setup(int nr, struct pci_sys_data *); extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); extern void pci_v3_preinit(void); extern void pci_v3_postinit(void); + +#endif /* __ASM_MACH_PCI_H */ diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 47980118d0a5..92e2a833693d 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -4,8 +4,23 @@ #ifdef __KERNEL__ #include +#include /* for pci_sys_data */ #include /* for PCIBIOS_MIN_* */ +#ifdef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_sys_data *root = bus->sysdata; + + return root->domain; +} + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#endif /* CONFIG_PCI_DOMAINS */ + #ifdef CONFIG_PCI_HOST_ITE8152 /* ITE bridge requires setting latency timer to avoid early bus access termination by PIC bus mater devices diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index bd397e0b663e..c6273a3bfc25 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -527,6 +527,9 @@ static void __init pcibios_init_hw(struct hw_pci *hw) if (!sys) panic("PCI: unable to allocate sys data!"); +#ifdef CONFIG_PCI_DOMAINS + sys->domain = hw->domain; +#endif sys->hw = hw; sys->busnr = busnr; sys->swizzle = hw->swizzle; -- cgit v1.2.3 From b9cedda230793cbf58eb012ddadedd490cc8e129 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 18:10:33 +0000 Subject: ARM: Integrator: convert to generic time support Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/common.h | 1 - arch/arm/mach-integrator/core.c | 62 ++++++++++++++++---------------- arch/arm/mach-integrator/integrator_ap.c | 1 - arch/arm/mach-integrator/integrator_cp.c | 1 - 5 files changed, 31 insertions(+), 35 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c5408bf1bf43..7698d8705a8f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -241,6 +241,7 @@ config ARCH_INTEGRATOR select HAVE_CLK select COMMON_CLKDEV select ICST525 + select GENERIC_TIME help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 609c49de3d47..7dc24bb9bdc1 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,2 +1 @@ extern void integrator_time_init(unsigned long, unsigned int); -extern unsigned long integrator_gettimeoffset(void); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 096f899625f8..87c6f980944d 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -225,7 +226,6 @@ EXPORT_SYMBOL(cm_control); #define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) #define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) #define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) -#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) /* * How long is the timer interval? @@ -241,42 +241,38 @@ EXPORT_SYMBOL(cm_control); static unsigned long timer_reload; -/* - * Returns number of ms since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -unsigned long integrator_gettimeoffset(void) +static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE; + +static cycle_t timersp_read(struct clocksource *cs) { - unsigned long ticks1, ticks2, status; + return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff); +} - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; - do { - ticks1 = ticks2; - status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; - } while (ticks2 > ticks1); +static struct clocksource clocksource_timersp = { + .name = "timer2", + .rating = 200, + .read = timersp_read, + .mask = CLOCKSOURCE_MASK(16), + .shift = 16, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; - /* - * Number of ticks since last interrupt. - */ - ticks1 = timer_reload - ticks2; +static void integrator_clocksource_init(u32 khz) +{ + struct clocksource *cs = &clocksource_timersp; + void __iomem *base = clksrc_base; + u32 ctrl = TIMER_CTRL_ENABLE; - /* - * Interrupt pending? If so, we've reloaded once already. - */ - if (status & (1 << IRQ_TIMERINT1)) - ticks1 += timer_reload; + if (khz >= 1500) { + khz /= 16; + ctrl = TIMER_CTRL_DIV16; + } - /* - * Convert the ticks to usecs - */ - return TICKS2USECS(ticks1); + writel(ctrl, base + TIMER_CTRL); + writel(0xffff, base + TIMER_LOAD); + + cs->mult = clocksource_khz2mult(khz, cs->shift); + clocksource_register(cs); } /* @@ -308,6 +304,8 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; + integrator_clocksource_init(reload * HZ / 1000); + timer_reload = reload; timer_ctrl |= ctrl; diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 018c32da4c86..cfb718fe31a8 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -342,7 +342,6 @@ static void __init ap_init_timer(void) static struct sys_timer ap_timer = { .init = ap_init_timer, - .offset = integrator_gettimeoffset, }; MACHINE_START(INTEGRATOR, "ARM-Integrator") diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index c66e8fa0e622..3e84732163ea 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -577,7 +577,6 @@ static void __init intcp_timer_init(void) static struct sys_timer cp_timer = { .init = intcp_timer_init, - .offset = integrator_gettimeoffset, }; MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") -- cgit v1.2.3 From 13edd86d7a8b64735c60c308faac785a6f2257b2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 15 Jan 2010 21:49:23 +0000 Subject: ARM: Integrator: convert to generic clockevent support Signed-off-by: Russell King --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/core.c | 107 +++++++++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 34 deletions(-) (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7698d8705a8f..86fecec1600d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -242,6 +242,7 @@ config ARCH_INTEGRATOR select COMMON_CLKDEV select ICST525 select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 87c6f980944d..b1ccbe3f233f 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -275,61 +276,99 @@ static void integrator_clocksource_init(u32 khz) clocksource_register(cs); } +static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; + /* * IRQ handler for the timer */ -static irqreturn_t -integrator_timer_interrupt(int irq, void *dev_id) +static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) { - /* - * clear the interrupt - */ - writel(1, TIMER1_VA_BASE + TIMER_INTCLR); + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); - timer_tick(); + evt->event_handler(evt); return IRQ_HANDLED; } +static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) +{ + u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; + + BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT); + + if (mode == CLOCK_EVT_MODE_PERIODIC) { + writel(ctrl, clkevt_base + TIMER_CTRL); + writel(timer_reload, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device integrator_clockevent = { + .name = "timer1", + .shift = 34, + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = clkevt_set_mode, + .set_next_event = clkevt_set_next_event, + .rating = 300, + .cpumask = cpu_all_mask, +}; + static struct irqaction integrator_timer_irq = { - .name = "Integrator Timer Tick", + .name = "timer", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, .handler = integrator_timer_interrupt, + .dev_id = &integrator_clockevent, }; -/* - * Set up timer interrupt, and return the current time in seconds. - */ -void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +static void integrator_clockevent_init(u32 khz, unsigned int ctrl) { - unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; + struct clock_event_device *evt = &integrator_clockevent; - integrator_clocksource_init(reload * HZ / 1000); + if (khz * 1000 > 0x100000 * HZ) { + khz /= 256; + ctrl |= TIMER_CTRL_DIV256; + } else if (khz * 1000 > 0x10000 * HZ) { + khz /= 16; + ctrl |= TIMER_CTRL_DIV16; + } - timer_reload = reload; - timer_ctrl |= ctrl; + timer_reload = khz * 1000 / HZ; + writel(ctrl, clkevt_base + TIMER_CTRL); - if (timer_reload > 0x100000) { - timer_reload >>= 8; - timer_ctrl |= TIMER_CTRL_DIV256; - } else if (timer_reload > 0x010000) { - timer_reload >>= 4; - timer_ctrl |= TIMER_CTRL_DIV16; - } + evt->irq = IRQ_TIMERINT1; + evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); - /* - * Initialise to a known state (all timers off) - */ + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + clockevents_register_device(evt); +} + +/* + * Set up timer(s). + */ +void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +{ writel(0, TIMER0_VA_BASE + TIMER_CTRL); writel(0, TIMER1_VA_BASE + TIMER_CTRL); writel(0, TIMER2_VA_BASE + TIMER_CTRL); - writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); - writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); - writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); - - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); + integrator_clocksource_init(reload * HZ / 1000); + integrator_clockevent_init(reload * HZ / 1000, ctrl); } -- cgit v1.2.3 From c5a0adb51002e51a4254cb7f0ab7190d41d8b930 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Jan 2010 20:16:10 +0000 Subject: ARM: ICST: kill duplicate icst code The only difference between ICST307 and ICST525 are the two arrays for calculating the S parameter; the code is now identical. Merge the two files and kill the duplicated code. Signed-off-by: Russell King --- arch/arm/Kconfig | 6 +- arch/arm/common/Kconfig | 5 +- arch/arm/common/Makefile | 3 +- arch/arm/common/icst.c | 100 ++++++++++++++++++++++++++++++ arch/arm/common/icst307.c | 101 ------------------------------- arch/arm/common/icst525.c | 99 ------------------------------ arch/arm/include/asm/hardware/icst.h | 24 ++++++++ arch/arm/include/asm/hardware/icst307.h | 34 ----------- arch/arm/include/asm/hardware/icst525.h | 33 ---------- arch/arm/mach-integrator/clock.c | 10 +-- arch/arm/mach-integrator/cpu.c | 20 +++--- arch/arm/mach-integrator/impd1.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/clock.c | 10 +-- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-realview/realview_eb.c | 1 - arch/arm/mach-realview/realview_pb1176.c | 1 - arch/arm/mach-realview/realview_pb11mp.c | 1 - arch/arm/mach-realview/realview_pba8.c | 1 - arch/arm/mach-versatile/clock.c | 10 +-- arch/arm/mach-versatile/core.c | 2 +- 21 files changed, 158 insertions(+), 309 deletions(-) create mode 100644 arch/arm/common/icst.c delete mode 100644 arch/arm/common/icst307.c delete mode 100644 arch/arm/common/icst525.c delete mode 100644 arch/arm/include/asm/hardware/icst307.h delete mode 100644 arch/arm/include/asm/hardware/icst525.h (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86fecec1600d..3c436fdbe2a0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -240,7 +240,7 @@ config ARCH_INTEGRATOR select ARCH_HAS_CPUFREQ select HAVE_CLK select COMMON_CLKDEV - select ICST525 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS help @@ -251,7 +251,7 @@ config ARCH_REALVIEW select ARM_AMBA select HAVE_CLK select COMMON_CLKDEV - select ICST307 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB @@ -264,7 +264,7 @@ config ARCH_VERSATILE select ARM_VIC select HAVE_CLK select COMMON_CLKDEV - select ICST307 + select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 4efbb9df0444..323d2d289523 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -12,10 +12,7 @@ config ARM_VIC_NR The maximum number of VICs available in the system, for power management. -config ICST525 - bool - -config ICST307 +config ICST bool config SA1111 diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 76be7ff2a7ca..5e8ad0d6c917 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -4,8 +4,7 @@ obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o -obj-$(CONFIG_ICST525) += icst525.o -obj-$(CONFIG_ICST307) += icst307.o +obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c new file mode 100644 index 000000000000..9a7f09cff300 --- /dev/null +++ b/arch/arm/common/icst.c @@ -0,0 +1,100 @@ +/* + * linux/arch/arm/common/icst307.c + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * + * 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. + * + * Support functions for calculating clocks/divisors for the ICST307 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + * + * This is an almost identical implementation to the ICST525 clock generator. + * The s2div and idx2s files are different + */ +#include +#include + +#include + +/* + * Divisors for each OD setting. + */ +const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; +const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; +EXPORT_SYMBOL(icst307_s2div); +EXPORT_SYMBOL(icst525_s2div); + +unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco) +{ + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); +} + +EXPORT_SYMBOL(icst_hz); + +/* + * Ascending divisor S values. + */ +const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; +const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 }; +EXPORT_SYMBOL(icst307_idx2s); +EXPORT_SYMBOL(icst525_idx2s); + +struct icst_vco +icst_hz_to_vco(const struct icst_params *p, unsigned long freq) +{ + struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f; + unsigned int i = 0, rd, best = (unsigned int)-1; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = freq * p->s2div[p->idx2s[i]]; + + if (f > p->vco_min && f <= p->vco_max) + break; + } while (i < 8); + + if (i >= 8) + return vco; + + vco.s = p->idx2s[i]; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long fref_div, f_pll; + unsigned int vd; + int f_diff; + + fref_div = (2 * p->ref) / rd; + + vd = (f + fref_div / 2) / fref_div; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = fref_div * vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst_hz_to_vco); diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c deleted file mode 100644 index 8332c0726e73..000000000000 --- a/arch/arm/common/icst307.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/arm/common/icst307.c - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * 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. - * - * Support functions for calculating clocks/divisors for the ICST307 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - * - * This is an almost identical implementation to the ICST525 clock generator. - * The s2div and idx2s files are different - */ -#include -#include - -#include - -/* - * Divisors for each OD setting. - */ -const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; - -EXPORT_SYMBOL(icst307_s2div); - -unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco) -{ - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); -} - -EXPORT_SYMBOL(icst307_hz); - -/* - * Ascending divisor S values. - */ -const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; - -EXPORT_SYMBOL(icst307_idx2s); - -struct icst_vco -icst307_hz_to_vco(const struct icst_params *p, unsigned long freq) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f; - unsigned int i = 0, rd, best = (unsigned int)-1; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = freq * p->s2div[p->idx2s[i]]; - - /* - * f must be between 6MHz and 200MHz (3.3 or 5V) - */ - if (f > p->vco_min && f <= p->vco_max) - break; - } while (i < 8); - - if (i >= 8) - return vco; - - vco.s = p->idx2s[i]; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long fref_div, f_pll; - unsigned int vd; - int f_diff; - - fref_div = (2 * p->ref) / rd; - - vd = (f + fref_div / 2) / fref_div; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = fref_div * vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst307_hz_to_vco); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c deleted file mode 100644 index 4180255eb078..000000000000 --- a/arch/arm/common/icst525.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * linux/arch/arm/common/icst525.c - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * 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. - * - * Support functions for calculating clocks/divisors for the ICST525 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - */ -#include -#include - -#include - -/* - * Divisors for each OD setting. - */ -const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; - -EXPORT_SYMBOL(icst525_s2div); - -unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco) -{ - return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]); -} - -EXPORT_SYMBOL(icst525_hz); - -/* - * Ascending divisor S values. - */ -const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 }; - -EXPORT_SYMBOL(icst525_idx2s); - -struct icst_vco -icst525_hz_to_vco(const struct icst_params *p, unsigned long freq) -{ - struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; - unsigned long f; - unsigned int i = 0, rd, best = (unsigned int)-1; - - /* - * First, find the PLL output divisor such - * that the PLL output is within spec. - */ - do { - f = freq * p->s2div[p->idx2s[i]]; - - /* - * f must be between 10MHz and - * 320MHz (5V) or 200MHz (3V) - */ - if (f > p->vco_min && f <= p->vco_max) - break; - } while (i < 8); - - if (i >= 8) - return vco; - - vco.s = p->idx2s[i]; - - /* - * Now find the closest divisor combination - * which gives a PLL output of 'f'. - */ - for (rd = p->rd_min; rd <= p->rd_max; rd++) { - unsigned long fref_div, f_pll; - unsigned int vd; - int f_diff; - - fref_div = (2 * p->ref) / rd; - - vd = (f + fref_div / 2) / fref_div; - if (vd < p->vd_min || vd > p->vd_max) - continue; - - f_pll = fref_div * vd; - f_diff = f_pll - f; - if (f_diff < 0) - f_diff = -f_diff; - - if ((unsigned)f_diff < best) { - vco.v = vd - 8; - vco.r = rd - 2; - if (f_diff == 0) - break; - best = f_diff; - } - } - - return vco; -} - -EXPORT_SYMBOL(icst525_hz_to_vco); diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h index 4d403680fa47..10382a3dcec9 100644 --- a/arch/arm/include/asm/hardware/icst.h +++ b/arch/arm/include/asm/hardware/icst.h @@ -32,4 +32,28 @@ struct icst_vco { unsigned char s; }; +unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq); + +/* + * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). + * This frequency is pre-output divider. + */ +#define ICST307_VCO_MIN 6000000 +#define ICST307_VCO_MAX 200000000 + +extern const unsigned char icst307_s2div[]; +extern const unsigned char icst307_idx2s[]; + +/* + * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). + * This frequency is pre-output divider. + */ +#define ICST525_VCO_MIN 10000000 +#define ICST525_VCO_MAX_3V 200000000 +#define ICST525_VCO_MAX_5V 320000000 + +extern const unsigned char icst525_s2div[]; +extern const unsigned char icst525_idx2s[]; + #endif diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h deleted file mode 100644 index d76fc6e09e47..000000000000 --- a/arch/arm/include/asm/hardware/icst307.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * arch/arm/include/asm/hardware/icst307.h - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * 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. - * - * Support functions for calculating clocks/divisors for the ICS307 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - * - * This file is similar to the icst525.h file - */ -#ifndef ASMARM_HARDWARE_ICST307_H -#define ASMARM_HARDWARE_ICST307_H - -#include - -unsigned long icst307_hz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst307_hz_to_vco(const struct icst_params *p, unsigned long freq); - -/* - * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). - * This frequency is pre-output divider. - */ -#define ICST307_VCO_MIN 6000000 -#define ICST307_VCO_MAX 200000000 - -extern const unsigned char icst307_s2div[]; -extern const unsigned char icst307_idx2s[]; - -#endif diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h deleted file mode 100644 index 2f9b95386b1b..000000000000 --- a/arch/arm/include/asm/hardware/icst525.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/include/asm/hardware/icst525.h - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * 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. - * - * Support functions for calculating clocks/divisors for the ICST525 - * clock generators. See http://www.icst.com/ for more information - * on these devices. - */ -#ifndef ASMARM_HARDWARE_ICST525_H -#define ASMARM_HARDWARE_ICST525_H - -#include - -unsigned long icst525_hz(const struct icst_params *p, struct icst_vco vco); -struct icst_vco icst525_hz_to_vco(const struct icst_params *p, unsigned long freq); - -/* - * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). - * This frequency is pre-output divider. - */ -#define ICST525_VCO_MIN 10000000 -#define ICST525_VCO_MAX_3V 200000000 -#define ICST525_VCO_MAX_5V 320000000 - -extern const unsigned char icst525_s2div[]; -extern const unsigned char icst525_idx2s[]; - -#endif diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c index a4f80d33429d..52fc294eac74 100644 --- a/arch/arm/mach-integrator/clock.c +++ b/arch/arm/mach-integrator/clock.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -38,8 +38,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst525_hz_to_vco(clk->params, rate); - return icst525_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -50,8 +50,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst525_hz_to_vco(clk->params, rate); - clk->rate = icst525_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 9481c5408bf8..1cb222daa06d 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include static struct cpufreq_driver integrator_driver; @@ -66,11 +66,11 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - vco = icst525_hz_to_vco(&cclk_params, policy->max * 1000); - policy->max = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, policy->max * 1000); + policy->max = icst_hz(&cclk_params, vco) / 1000; - vco = icst525_hz_to_vco(&cclk_params, policy->min * 1000); - policy->min = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, policy->min * 1000); + policy->min = icst_hz(&cclk_params, vco) / 1000; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, @@ -112,17 +112,17 @@ static int integrator_set_target(struct cpufreq_policy *policy, } vco.v = cm_osc & 255; vco.r = 22; - freqs.old = icst525_hz(&cclk_params, vco) / 1000; + freqs.old = icst_hz(&cclk_params, vco) / 1000; - /* icst525_hz_to_vco rounds down -- so we need the next + /* icst_hz_to_vco rounds down -- so we need the next * larger freq in case of CPUFREQ_RELATION_L. */ if (relation == CPUFREQ_RELATION_L) target_freq += 999; if (target_freq > policy->max) target_freq = policy->max; - vco = icst525_hz_to_vco(&cclk_params, target_freq * 1000); - freqs.new = icst525_hz(&cclk_params, vco) / 1000; + vco = icst_hz_to_vco(&cclk_params, target_freq * 1000); + freqs.new = icst_hz(&cclk_params, vco) / 1000; freqs.cpu = policy->cpu; @@ -180,7 +180,7 @@ static unsigned int integrator_get(unsigned int cpu) vco.v = cm_osc & 255; vco.r = 22; - current_freq = icst525_hz(&cclk_params, vco) / 1000; /* current freq */ + current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */ set_cpus_allowed(current, cpus_allowed); diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index e24cfc357ffb..3e2110216851 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 9997d1f6c184..a9ab8fda3992 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index 2ba0667d18f5..18c545921e41 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include "clock.h" @@ -42,8 +42,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - return icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -54,8 +54,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - clk->rate = icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 26d44caad540..a8c215a406a2 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 7d857d300558..39d953c89d9a 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 44392e51dd50..a93aac5f473e 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 3e02731af959..c7c656e235cc 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index fe4e25c4201a..3e3aaa3a2bc0 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index 82753be453d0..adc67d771c78 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include "clock.h" @@ -43,8 +43,8 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - return icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); } EXPORT_SYMBOL(clk_round_rate); @@ -55,8 +55,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk->setvco) { struct icst_vco vco; - vco = icst307_hz_to_vco(clk->params, rate); - clk->rate = icst307_hz(clk->params, vco); + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); clk->setvco(clk, vco); ret = 0; } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 51d7aeb6a507..3c67691d4e72 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From f4b8b319bf21bf3576014ce7336763cd3e1684ef Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 12:48:06 +0000 Subject: ARM: Realview/Versatile/Integrator: separate out common clock code Signed-off-by: Russell King --- arch/arm/Kconfig | 6 +++ arch/arm/Makefile | 1 + arch/arm/mach-integrator/Makefile | 2 +- arch/arm/mach-integrator/clock.c | 60 ------------------------- arch/arm/mach-realview/Makefile | 2 +- arch/arm/mach-realview/clock.c | 64 -------------------------- arch/arm/mach-realview/clock.h | 20 --------- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-realview/include/mach/clkdev.h | 9 ++++ arch/arm/mach-realview/realview_eb.c | 1 - arch/arm/mach-realview/realview_pb1176.c | 1 - arch/arm/mach-realview/realview_pb11mp.c | 1 - arch/arm/mach-realview/realview_pba8.c | 1 - arch/arm/mach-versatile/Makefile | 2 +- arch/arm/mach-versatile/clock.c | 65 --------------------------- arch/arm/mach-versatile/clock.h | 21 --------- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-versatile/include/mach/clkdev.h | 9 ++++ arch/arm/plat-versatile/Makefile | 1 + arch/arm/plat-versatile/clock.c | 60 +++++++++++++++++++++++++ 20 files changed, 91 insertions(+), 239 deletions(-) delete mode 100644 arch/arm/mach-integrator/clock.c delete mode 100644 arch/arm/mach-realview/clock.c delete mode 100644 arch/arm/mach-realview/clock.h delete mode 100644 arch/arm/mach-versatile/clock.c delete mode 100644 arch/arm/mach-versatile/clock.h create mode 100644 arch/arm/plat-versatile/Makefile create mode 100644 arch/arm/plat-versatile/clock.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3c436fdbe2a0..e8265f257674 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -243,6 +243,7 @@ config ARCH_INTEGRATOR select ICST select GENERIC_TIME select GENERIC_CLOCKEVENTS + select PLAT_VERSATILE help Support for ARM's Integrator platform. @@ -255,6 +256,7 @@ config ARCH_REALVIEW select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select PLAT_VERSATILE help This enables support for ARM Ltd RealView boards. @@ -268,6 +270,7 @@ config ARCH_VERSATILE select GENERIC_TIME select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select PLAT_VERSATILE help This enables support for ARM Ltd Versatile board. @@ -938,6 +941,9 @@ config PLAT_ORION config PLAT_PXA bool +config PLAT_VERSATILE + bool + source arch/arm/mm/Kconfig config IWMMXT diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ed820e737a8a..1962deb90730 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -192,6 +192,7 @@ plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx samsung plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_VERSATILE) := versatile ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 6a5ef8d30b10..ebeef966e1f5 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := clock.o core.o lm.o +obj-y := core.o lm.o obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c deleted file mode 100644 index 52fc294eac74..000000000000 --- a/arch/arm/mach-integrator/clock.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index e704edb733c0..a01b76b7c956 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c deleted file mode 100644 index 18c545921e41..000000000000 --- a/arch/arm/mach-realview/clock.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * linux/arch/arm/mach-realview/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 "clock.h" - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h deleted file mode 100644 index fa64c854258d..000000000000 --- a/arch/arm/mach-realview/clock.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/arch/arm/mach-realview/clock.h - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 - -struct module; - -struct clk { - unsigned long rate; - const struct icst_params *params; - void *data; - void (*setvco)(struct clk *, struct icst_vco vco); -}; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index a8c215a406a2..17eb7eb780d8 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -48,11 +48,11 @@ #include +#include #include #include #include "core.h" -#include "clock.h" #define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h index 04b37a89801c..fefe4671255c 100644 --- a/arch/arm/mach-realview/include/mach/clkdev.h +++ b/arch/arm/mach-realview/include/mach/clkdev.h @@ -1,6 +1,15 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H +#include + +struct clk { + unsigned long rate; + const struct icst_params *params; + u32 oscoff; + void (*setvco)(struct clk *, struct icst_vco vco); +}; + #define __clk_get(clk) ({ 1; }) #define __clk_put(clk) do { } while (0) diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 39d953c89d9a..006765fd204c 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -43,7 +43,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_eb_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index a93aac5f473e..217f7c19551e 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -43,7 +43,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pb1176_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index c7c656e235cc..9ef2ecc3c098 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -44,7 +44,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pb11mp_io_desc[] __initdata = { { diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 3e3aaa3a2bc0..2fab3a6d566b 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -41,7 +41,6 @@ #include #include "core.h" -#include "clock.h" static struct map_desc realview_pba8_io_desc[] __initdata = { { diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile index ba81e70ed813..97cf4d831b0c 100644 --- a/arch/arm/mach-versatile/Makefile +++ b/arch/arm/mach-versatile/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := core.o clock.o +obj-y := core.o obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c deleted file mode 100644 index adc67d771c78..000000000000 --- a/arch/arm/mach-versatile/clock.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * linux/arch/arm/mach-versatile/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 "clock.h" - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - - if (clk->setvco) { - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->setvco(clk, vco); - ret = 0; - } - return ret; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h deleted file mode 100644 index aed7e22d102b..000000000000 --- a/arch/arm/mach-versatile/clock.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/arch/arm/mach-versatile/clock.h - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * 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 - -struct module; - -struct clk { - unsigned long rate; - const struct icst_params *params; - u32 oscoff; - void *data; - void (*setvco)(struct clk *, struct icst_vco vco); -}; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3c67691d4e72..e9d255f33674 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -47,11 +47,11 @@ #include #include #include +#include #include #include #include "core.h" -#include "clock.h" /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h index 04b37a89801c..fefe4671255c 100644 --- a/arch/arm/mach-versatile/include/mach/clkdev.h +++ b/arch/arm/mach-versatile/include/mach/clkdev.h @@ -1,6 +1,15 @@ #ifndef __ASM_MACH_CLKDEV_H #define __ASM_MACH_CLKDEV_H +#include + +struct clk { + unsigned long rate; + const struct icst_params *params; + u32 oscoff; + void (*setvco)(struct clk *, struct icst_vco vco); +}; + #define __clk_get(clk) ({ 1; }) #define __clk_put(clk) do { } while (0) diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile new file mode 100644 index 000000000000..2228fd1725ac --- /dev/null +++ b/arch/arm/plat-versatile/Makefile @@ -0,0 +1 @@ +obj-y := clock.o diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c new file mode 100644 index 000000000000..2fa34de92325 --- /dev/null +++ b/arch/arm/plat-versatile/clock.c @@ -0,0 +1,60 @@ +/* + * linux/arch/arm/plat-versatile/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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 + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + struct icst_vco vco; + vco = icst_hz_to_vco(clk->params, rate); + return icst_hz(clk->params, vco); +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + + if (clk->setvco) { + struct icst_vco vco; + + vco = icst_hz_to_vco(clk->params, rate); + clk->rate = icst_hz(clk->params, vco); + clk->setvco(clk, vco); + ret = 0; + } + return ret; +} +EXPORT_SYMBOL(clk_set_rate); -- cgit v1.2.3 From e388771458b4ff3ad81ab70e390b24d069647da4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 14 Jan 2010 13:30:16 +0000 Subject: ARM: Realview/Versatile: separate out common SP804 timer code Signed-off-by: Russell King --- arch/arm/Kconfig | 5 + arch/arm/mach-realview/core.c | 139 +------------------- arch/arm/mach-versatile/core.c | 135 +------------------ arch/arm/plat-versatile/Makefile | 1 + arch/arm/plat-versatile/include/plat/timer-sp.h | 2 + arch/arm/plat-versatile/timer-sp.c | 168 ++++++++++++++++++++++++ 6 files changed, 182 insertions(+), 268 deletions(-) create mode 100644 arch/arm/plat-versatile/include/plat/timer-sp.h create mode 100644 arch/arm/plat-versatile/timer-sp.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e8265f257674..553487052772 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -257,6 +257,7 @@ config ARCH_REALVIEW select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE + select ARM_TIMER_SP804 help This enables support for ARM Ltd RealView boards. @@ -271,6 +272,7 @@ config ARCH_VERSATILE select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select PLAT_VERSATILE + select ARM_TIMER_SP804 help This enables support for ARM Ltd Versatile board. @@ -944,6 +946,9 @@ config PLAT_PXA config PLAT_VERSATILE bool +config ARM_TIMER_SP804 + bool + source arch/arm/mm/Kconfig config IWMMXT diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 17eb7eb780d8..80b8142463c1 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include #include @@ -51,6 +49,7 @@ #include #include #include +#include #include "core.h" @@ -645,133 +644,6 @@ void __iomem *timer1_va_base; void __iomem *timer2_va_base; void __iomem *timer3_va_base; -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -static void timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) -{ - unsigned long ctrl; - - switch(mode) { - case CLOCK_EVT_MODE_PERIODIC: - writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD); - - ctrl = TIMER_CTRL_PERIODIC; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set, and timer enabled in 'next_event' hook */ - ctrl = TIMER_CTRL_ONESHOT; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - default: - ctrl = 0; - } - - writel(ctrl, timer0_va_base + TIMER_CTRL); -} - -static int timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL); - - writel(evt, timer0_va_base + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL); - - return 0; -} - -static struct clock_event_device timer0_clockevent = { - .name = "timer0", - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, - .rating = 300, - .cpumask = cpu_all_mask, -}; - -static void __init realview_clockevents_init(unsigned int timer_irq) -{ - timer0_clockevent.irq = timer_irq; - timer0_clockevent.mult = - div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = - clockevent_delta2ns(0xffffffff, &timer0_clockevent); - timer0_clockevent.min_delta_ns = - clockevent_delta2ns(0xf, &timer0_clockevent); - - clockevents_register_device(&timer0_clockevent); -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &timer0_clockevent; - - /* clear the interrupt */ - writel(1, timer0_va_base + TIMER_INTCLR); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction realview_timer_irq = { - .name = "RealView Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = realview_timer_interrupt, -}; - -static cycle_t realview_get_cycles(struct clocksource *cs) -{ - return ~readl(timer3_va_base + TIMER_VALUE); -} - -static struct clocksource clocksource_realview = { - .name = "timer3", - .rating = 200, - .read = realview_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static void __init realview_clocksource_init(void) -{ - /* setup timer 0 as free-running clocksource */ - writel(0, timer3_va_base + TIMER_CTRL); - writel(0xffffffff, timer3_va_base + TIMER_LOAD); - writel(0xffffffff, timer3_va_base + TIMER_VALUE); - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, - timer3_va_base + TIMER_CTRL); - - clocksource_realview.mult = - clocksource_khz2mult(1000, clocksource_realview.shift); - clocksource_register(&clocksource_realview); -} - /* * Set up the clock source and clock events devices */ @@ -799,13 +671,8 @@ void __init realview_timer_init(unsigned int timer_irq) writel(0, timer2_va_base + TIMER_CTRL); writel(0, timer3_va_base + TIMER_CTRL); - /* - * Make irqs happen for the system timer - */ - setup_irq(timer_irq, &realview_timer_irq); - - realview_clocksource_init(); - realview_clockevents_init(timer_irq); + sp804_clocksource_init(timer3_va_base); + sp804_clockevents_init(timer0_va_base, timer_irq); } /* diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index e9d255f33674..b68ddd349f12 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include #include @@ -50,6 +48,7 @@ #include #include #include +#include #include "core.h" @@ -877,120 +876,6 @@ void __init versatile_init(void) #define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20) #define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE) #define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20) -#define VA_IC_BASE __io_address(VERSATILE_VIC_BASE) - -/* - * How long is the timer interval? - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >= 0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) -#endif - -static void timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) -{ - unsigned long ctrl; - - switch(mode) { - case CLOCK_EVT_MODE_PERIODIC: - writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); - - ctrl = TIMER_CTRL_PERIODIC; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set, and timer enabled in 'next_event' hook */ - ctrl = TIMER_CTRL_ONESHOT; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - default: - ctrl = 0; - } - - writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL); -} - -static int timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL); - - writel(evt, TIMER0_VA_BASE + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL); - - return 0; -} - -static struct clock_event_device timer0_clockevent = { - .name = "timer0", - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, -}; - -/* - * IRQ handler for the timer - */ -static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &timer0_clockevent; - - writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction versatile_timer_irq = { - .name = "Versatile Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = versatile_timer_interrupt, -}; - -static cycle_t versatile_get_cycles(struct clocksource *cs) -{ - return ~readl(TIMER3_VA_BASE + TIMER_VALUE); -} - -static struct clocksource clocksource_versatile = { - .name = "timer3", - .rating = 200, - .read = versatile_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init versatile_clocksource_init(void) -{ - /* setup timer3 as free-running clocksource */ - writel(0, TIMER3_VA_BASE + TIMER_CTRL); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, - TIMER3_VA_BASE + TIMER_CTRL); - - clocksource_versatile.mult = - clocksource_khz2mult(1000, clocksource_versatile.shift); - clocksource_register(&clocksource_versatile); - - return 0; -} /* * Set up timer interrupt, and return the current time in seconds. @@ -1019,22 +904,8 @@ static void __init versatile_timer_init(void) writel(0, TIMER2_VA_BASE + TIMER_CTRL); writel(0, TIMER3_VA_BASE + TIMER_CTRL); - /* - * Make irqs happen for the system timer - */ - setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); - - versatile_clocksource_init(); - - timer0_clockevent.mult = - div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = - clockevent_delta2ns(0xffffffff, &timer0_clockevent); - timer0_clockevent.min_delta_ns = - clockevent_delta2ns(0xf, &timer0_clockevent); - - timer0_clockevent.cpumask = cpumask_of(0); - clockevents_register_device(&timer0_clockevent); + sp804_clocksource_init(TIMER3_VA_BASE); + sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1); } struct sys_timer versatile_timer = { diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 2228fd1725ac..334d2f14232c 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1 +1,2 @@ obj-y := clock.o +obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/plat-versatile/include/plat/timer-sp.h new file mode 100644 index 000000000000..21e75e30d497 --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/timer-sp.h @@ -0,0 +1,2 @@ +void sp804_clocksource_init(void __iomem *); +void sp804_clockevents_init(void __iomem *, unsigned int); diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c new file mode 100644 index 000000000000..98722f44640c --- /dev/null +++ b/arch/arm/plat-versatile/timer-sp.c @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/plat-versatile/timer-sp.c + * + * Copyright (C) 1999 - 2003 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 +#include +#include + +#include + +#include + +#include + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) +#elif TIMER_INTERVAL >= 0x10000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) +#else +#define TIMER_RELOAD (TIMER_INTERVAL) +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) +#endif + + +static void __iomem *clksrc_base; + +static cycle_t sp804_read(struct clocksource *cs) +{ + return ~readl(clksrc_base + TIMER_VALUE); +} + +static struct clocksource clocksource_sp804 = { + .name = "timer3", + .rating = 200, + .read = sp804_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void __init sp804_clocksource_init(void __iomem *base) +{ + struct clocksource *cs = &clocksource_sp804; + + clksrc_base = base; + + /* setup timer 0 as free-running clocksource */ + writel(0, clksrc_base + TIMER_CTRL); + writel(0xffffffff, clksrc_base + TIMER_LOAD); + writel(0xffffffff, clksrc_base + TIMER_VALUE); + writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, + clksrc_base + TIMER_CTRL); + + cs->mult = clocksource_khz2mult(1000, cs->shift); + clocksource_register(cs); +} + + +static void __iomem *clkevt_base; + +/* + * IRQ handler for the timer + */ +static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + /* clear the interrupt */ + writel(1, clkevt_base + TIMER_INTCLR); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static void sp804_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; + + writel(ctrl, clkevt_base + TIMER_CTRL); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD); + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* period set, and timer enabled in 'next_event' hook */ + ctrl |= TIMER_CTRL_ONESHOT; + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + default: + break; + } + + writel(ctrl, clkevt_base + TIMER_CTRL); +} + +static int sp804_set_next_event(unsigned long next, + struct clock_event_device *evt) +{ + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); + + writel(next, clkevt_base + TIMER_LOAD); + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); + + return 0; +} + +static struct clock_event_device sp804_clockevent = { + .name = "timer0", + .shift = 32, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = sp804_set_mode, + .set_next_event = sp804_set_next_event, + .rating = 300, + .cpumask = cpu_all_mask, +}; + +static struct irqaction sp804_timer_irq = { + .name = "timer", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = sp804_timer_interrupt, + .dev_id = &sp804_clockevent, +}; + +void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq) +{ + struct clock_event_device *evt = &sp804_clockevent; + + clkevt_base = base; + + evt->irq = timer_irq; + evt->mult = div_sc(1000000, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); + + setup_irq(timer_irq, &sp804_timer_irq); + clockevents_register_device(evt); +} -- cgit v1.2.3 From ceade897f31b8bb66f378cc35859fcfd0d46aaa2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 11 Feb 2010 21:44:53 +0000 Subject: ARM: Add Versatile Express support Signed-off-by: Russell King --- arch/arm/Kconfig | 16 + arch/arm/Makefile | 1 + arch/arm/mach-vexpress/Kconfig | 4 + arch/arm/mach-vexpress/Makefile | 5 + arch/arm/mach-vexpress/Makefile.boot | 3 + arch/arm/mach-vexpress/core.h | 26 ++ arch/arm/mach-vexpress/include/mach/clkdev.h | 15 + arch/arm/mach-vexpress/include/mach/debug-macro.S | 23 ++ arch/arm/mach-vexpress/include/mach/entry-macro.S | 67 ++++ arch/arm/mach-vexpress/include/mach/hardware.h | 1 + arch/arm/mach-vexpress/include/mach/io.h | 28 ++ arch/arm/mach-vexpress/include/mach/irqs.h | 4 + arch/arm/mach-vexpress/include/mach/memory.h | 25 ++ arch/arm/mach-vexpress/include/mach/motherboard.h | 121 ++++++++ arch/arm/mach-vexpress/include/mach/system.h | 37 +++ arch/arm/mach-vexpress/include/mach/timex.h | 23 ++ arch/arm/mach-vexpress/include/mach/uncompress.h | 52 ++++ arch/arm/mach-vexpress/include/mach/vmalloc.h | 21 ++ arch/arm/mach-vexpress/v2m.c | 361 ++++++++++++++++++++++ drivers/i2c/busses/Kconfig | 2 +- 20 files changed, 834 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-vexpress/Kconfig create mode 100644 arch/arm/mach-vexpress/Makefile create mode 100644 arch/arm/mach-vexpress/Makefile.boot create mode 100644 arch/arm/mach-vexpress/core.h create mode 100644 arch/arm/mach-vexpress/include/mach/clkdev.h create mode 100644 arch/arm/mach-vexpress/include/mach/debug-macro.S create mode 100644 arch/arm/mach-vexpress/include/mach/entry-macro.S create mode 100644 arch/arm/mach-vexpress/include/mach/hardware.h create mode 100644 arch/arm/mach-vexpress/include/mach/io.h create mode 100644 arch/arm/mach-vexpress/include/mach/irqs.h create mode 100644 arch/arm/mach-vexpress/include/mach/memory.h create mode 100644 arch/arm/mach-vexpress/include/mach/motherboard.h create mode 100644 arch/arm/mach-vexpress/include/mach/system.h create mode 100644 arch/arm/mach-vexpress/include/mach/timex.h create mode 100644 arch/arm/mach-vexpress/include/mach/uncompress.h create mode 100644 arch/arm/mach-vexpress/include/mach/vmalloc.h create mode 100644 arch/arm/mach-vexpress/v2m.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 553487052772..58080e17c28b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -276,6 +276,20 @@ config ARCH_VERSATILE help This enables support for ARM Ltd Versatile board. +config ARCH_VEXPRESS + bool "ARM Ltd. Versatile Express family" + select ARCH_WANT_OPTIONAL_GPIOLIB + select ARM_AMBA + select ARM_TIMER_SP804 + select COMMON_CLKDEV + select GENERIC_CLOCKEVENTS + select GENERIC_TIME + select HAVE_CLK + select ICST + select PLAT_VERSATILE + help + This enables support for the ARM Ltd Versatile Express boards. + config ARCH_AT91 bool "Atmel AT91" select GENERIC_GPIO @@ -926,6 +940,8 @@ source "arch/arm/mach-ux500/Kconfig" source "arch/arm/mach-versatile/Kconfig" +source "arch/arm/mach-vexpress/Kconfig" + source "arch/arm/mach-w90x900/Kconfig" # Definitions to make life easier diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1962deb90730..67c92efa3112 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -175,6 +175,7 @@ machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_U8500) := ux500 machine-$(CONFIG_ARCH_VERSATILE) := versatile +machine-$(CONFIG_ARCH_VEXPRESS) := vexpress machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_ARCH_NUC93X) := nuc93x machine-$(CONFIG_FOOTBRIDGE) := footbridge diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig new file mode 100644 index 000000000000..751858c97e6a --- /dev/null +++ b/arch/arm/mach-vexpress/Kconfig @@ -0,0 +1,4 @@ +menu "Versatile Express platform type" + depends on ARCH_VEXPRESS + +endmenu diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile new file mode 100644 index 000000000000..b47cf732981f --- /dev/null +++ b/arch/arm/mach-vexpress/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# + +obj-y := v2m.o diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot new file mode 100644 index 000000000000..07c2d9c457ec --- /dev/null +++ b/arch/arm/mach-vexpress/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x60008000 +params_phys-y := 0x60000100 +initrd_phys-y := 0x60800000 diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h new file mode 100644 index 000000000000..57dd95ce41f9 --- /dev/null +++ b/arch/arm/mach-vexpress/core.h @@ -0,0 +1,26 @@ +#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000) +#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x)) + +#define AMBA_DEVICE(name,busid,base,plat) \ +struct amba_device name##_device = { \ + .dev = { \ + .coherent_dma_mask = ~0UL, \ + .init_name = busid, \ + .platform_data = plat, \ + }, \ + .res = { \ + .start = base, \ + .end = base + SZ_4K - 1, \ + .flags = IORESOURCE_MEM, \ + }, \ + .dma_mask = ~0UL, \ + .irq = IRQ_##base, \ + /* .dma = DMA_##base,*/ \ +} + +struct map_desc; + +void v2m_map_io(struct map_desc *tile, size_t num); +extern struct sys_timer v2m_timer; + +extern void __iomem *gic_cpu_base_addr; diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h new file mode 100644 index 000000000000..3f8307d73cad --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/clkdev.h @@ -0,0 +1,15 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#include + +struct clk { + const struct clk_ops *ops; + unsigned long rate; + const struct icst_params *params; +}; + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S new file mode 100644 index 000000000000..5167e2aceeba --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S @@ -0,0 +1,23 @@ +/* arch/arm/mach-realview/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by 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. + */ + +#define DEBUG_LL_UART_OFFSET 0x00009000 + + .macro addruart,rx,tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x10000000 + movne \rx, #0xf8000000 @ virtual base + orr \rx, \rx, #DEBUG_LL_UART_OFFSET + .endm + +#include diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S new file mode 100644 index 000000000000..20e9fb514f0a --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S @@ -0,0 +1,67 @@ +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt if it's + * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ + ldr \tmp, =1021 + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #29 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm + diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h new file mode 100644 index 000000000000..40a8c178f10d --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/hardware.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h new file mode 100644 index 000000000000..748bb524ee71 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/io.h @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-vexpress/include/mach/io.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h new file mode 100644 index 000000000000..7054cbfc9de5 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/irqs.h @@ -0,0 +1,4 @@ +#define IRQ_LOCALTIMER 29 +#define IRQ_LOCALWDOG 30 + +#define NR_IRQS 128 diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h new file mode 100644 index 000000000000..be28232ae639 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/memory.h @@ -0,0 +1,25 @@ +/* + * arch/arm/mach-vexpress/include/mach/memory.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x60000000) + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h new file mode 100644 index 000000000000..98a8ded055bf --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h @@ -0,0 +1,121 @@ +#ifndef __MACH_MOTHERBOARD_H +#define __MACH_MOTHERBOARD_H + +/* + * Physical addresses, offset from V2M_PA_CS0-3 + */ +#define V2M_NOR0 (V2M_PA_CS0) +#define V2M_NOR1 (V2M_PA_CS1) +#define V2M_SRAM (V2M_PA_CS2) +#define V2M_VIDEO_SRAM (V2M_PA_CS3 + 0x00000000) +#define V2M_LAN9118 (V2M_PA_CS3 + 0x02000000) +#define V2M_ISP1761 (V2M_PA_CS3 + 0x03000000) + +/* + * Physical addresses, offset from V2M_PA_CS7 + */ +#define V2M_SYSREGS (V2M_PA_CS7 + 0x00000000) +#define V2M_SYSCTL (V2M_PA_CS7 + 0x00001000) +#define V2M_SERIAL_BUS_PCI (V2M_PA_CS7 + 0x00002000) + +#define V2M_AACI (V2M_PA_CS7 + 0x00004000) +#define V2M_MMCI (V2M_PA_CS7 + 0x00005000) +#define V2M_KMI0 (V2M_PA_CS7 + 0x00006000) +#define V2M_KMI1 (V2M_PA_CS7 + 0x00007000) + +#define V2M_UART0 (V2M_PA_CS7 + 0x00009000) +#define V2M_UART1 (V2M_PA_CS7 + 0x0000a000) +#define V2M_UART2 (V2M_PA_CS7 + 0x0000b000) +#define V2M_UART3 (V2M_PA_CS7 + 0x0000c000) + +#define V2M_WDT (V2M_PA_CS7 + 0x0000f000) + +#define V2M_TIMER01 (V2M_PA_CS7 + 0x00011000) +#define V2M_TIMER23 (V2M_PA_CS7 + 0x00012000) + +#define V2M_SERIAL_BUS_DVI (V2M_PA_CS7 + 0x00016000) +#define V2M_RTC (V2M_PA_CS7 + 0x00017000) + +#define V2M_CF (V2M_PA_CS7 + 0x0001a000) +#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) + +#define V2M_SYS_ID (V2M_SYSREGS + 0x000) +#define V2M_SYS_SW (V2M_SYSREGS + 0x004) +#define V2M_SYS_LED (V2M_SYSREGS + 0x008) +#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024) +#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030) +#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030) +#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034) +#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038) +#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038) +#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c) +#define V2M_SYS_MCI (V2M_SYSREGS + 0x048) +#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c) +#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058) +#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c) +#define V2M_SYS_MISC (V2M_SYSREGS + 0x060) +#define V2M_SYS_DMA (V2M_SYSREGS + 0x064) +#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084) +#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088) +#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0) +#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4) +#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8) + +#define V2M_TIMER0 (V2M_TIMER01 + 0x000) +#define V2M_TIMER1 (V2M_TIMER01 + 0x020) + +#define V2M_TIMER2 (V2M_TIMER23 + 0x000) +#define V2M_TIMER3 (V2M_TIMER23 + 0x020) + + +/* + * Interrupts. Those in {} are for AMBA devices + */ +#define IRQ_V2M_WDT { (32 + 0) } +#define IRQ_V2M_TIMER0 (32 + 2) +#define IRQ_V2M_TIMER1 (32 + 2) +#define IRQ_V2M_TIMER2 (32 + 3) +#define IRQ_V2M_TIMER3 (32 + 3) +#define IRQ_V2M_RTC { (32 + 4) } +#define IRQ_V2M_UART0 { (32 + 5) } +#define IRQ_V2M_UART1 { (32 + 6) } +#define IRQ_V2M_UART2 { (32 + 7) } +#define IRQ_V2M_UART3 { (32 + 8) } +#define IRQ_V2M_MMCI { (32 + 9), (32 + 10) } +#define IRQ_V2M_AACI { (32 + 11) } +#define IRQ_V2M_KMI0 { (32 + 12) } +#define IRQ_V2M_KMI1 { (32 + 13) } +#define IRQ_V2M_CLCD { (32 + 14) } +#define IRQ_V2M_LAN9118 (32 + 15) +#define IRQ_V2M_ISP1761 (32 + 16) +#define IRQ_V2M_PCIE (32 + 17) + + +/* + * Configuration + */ +#define SYS_CFG_START (1 << 31) +#define SYS_CFG_WRITE (1 << 30) +#define SYS_CFG_OSC (1 << 20) +#define SYS_CFG_VOLT (2 << 20) +#define SYS_CFG_AMP (3 << 20) +#define SYS_CFG_TEMP (4 << 20) +#define SYS_CFG_RESET (5 << 20) +#define SYS_CFG_SCC (6 << 20) +#define SYS_CFG_MUXFPGA (7 << 20) +#define SYS_CFG_SHUTDOWN (8 << 20) +#define SYS_CFG_REBOOT (9 << 20) +#define SYS_CFG_DVIMODE (11 << 20) +#define SYS_CFG_POWER (12 << 20) +#define SYS_CFG_SITE_MB (0 << 16) +#define SYS_CFG_SITE_DB1 (1 << 16) +#define SYS_CFG_SITE_DB2 (2 << 16) +#define SYS_CFG_STACK(n) ((n) << 12) + +#define SYS_CFG_ERR (1 << 1) +#define SYS_CFG_COMPLETE (1 << 0) + +int v2m_cfg_write(u32 devfn, u32 data); +int v2m_cfg_read(u32 devfn, u32 *data); + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h new file mode 100644 index 000000000000..899a4e628a4c --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/system.h @@ -0,0 +1,37 @@ +/* + * arch/arm/mach-vexpress/include/mach/system.h + * + * Copyright (C) 2003 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * 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 + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ +} + +#endif diff --git a/arch/arm/mach-vexpress/include/mach/timex.h b/arch/arm/mach-vexpress/include/mach/timex.h new file mode 100644 index 000000000000..00029bacd43c --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/timex.h @@ -0,0 +1,23 @@ +/* + * arch/arm/mach-vexpress/include/mach/timex.h + * + * RealView architecture timex specifications + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ + +#define CLOCK_TICK_RATE (50000000 / 16) diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h new file mode 100644 index 000000000000..7972c5748d0e --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/uncompress.h @@ -0,0 +1,52 @@ +/* + * arch/arm/mach-vexpress/include/mach/uncompress.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00)) +#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c)) +#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) +#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) + +#define get_uart_base() (0x10000000 + 0x00009000) + +/* + * This does not append a newline + */ +static inline void putc(int c) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 5)) + barrier(); + + AMBA_UART_DR(base) = c; +} + +static inline void flush(void) +{ + unsigned long base = get_uart_base(); + + while (AMBA_UART_FR(base) & (1 << 3)) + barrier(); +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/arch/arm/mach-vexpress/include/mach/vmalloc.h b/arch/arm/mach-vexpress/include/mach/vmalloc.h new file mode 100644 index 000000000000..f43a36ef678b --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/vmalloc.h @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-vexpress/include/mach/vmalloc.h + * + * Copyright (C) 2003 ARM Limited + * Copyright (C) 2000 Russell King. + * + * 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 + */ +#define VMALLOC_END 0xf8000000UL diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c new file mode 100644 index 000000000000..d250711b8c7a --- /dev/null +++ b/arch/arm/mach-vexpress/v2m.c @@ -0,0 +1,361 @@ +/* + * Versatile Express V2M Motherboard Support + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "core.h" + +#define V2M_PA_CS0 0x40000000 +#define V2M_PA_CS1 0x44000000 +#define V2M_PA_CS2 0x48000000 +#define V2M_PA_CS3 0x4c000000 +#define V2M_PA_CS7 0x10000000 + +static struct map_desc v2m_io_desc[] __initdata = { + { + .virtual = __MMIO_P2V(V2M_PA_CS7), + .pfn = __phys_to_pfn(V2M_PA_CS7), + .length = SZ_128K, + .type = MT_DEVICE, + }, +}; + +void __init v2m_map_io(struct map_desc *tile, size_t num) +{ + iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + iotable_init(tile, num); +} + + +static void v2m_timer_init(void) +{ + writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); + writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); + + sp804_clocksource_init(MMIO_P2V(V2M_TIMER1)); + sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); +} + +struct sys_timer v2m_timer = { + .init = v2m_timer_init, +}; + + +static DEFINE_SPINLOCK(v2m_cfg_lock); + +int v2m_cfg_write(u32 devfn, u32 data) +{ + /* Configuration interface broken? */ + u32 val; + + printk("%s: writing %08x to %08x\n", __func__, data, devfn); + + devfn |= SYS_CFG_START | SYS_CFG_WRITE; + + spin_lock(&v2m_cfg_lock); + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); + + writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); + writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + + do { + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + } while (val == 0); + spin_unlock(&v2m_cfg_lock); + + return !!(val & SYS_CFG_ERR); +} + +int v2m_cfg_read(u32 devfn, u32 *data) +{ + u32 val; + + devfn |= SYS_CFG_START; + + spin_lock(&v2m_cfg_lock); + writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); + writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + + mb(); + + do { + cpu_relax(); + val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + } while (val == 0); + + *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); + spin_unlock(&v2m_cfg_lock); + + return !!(val & SYS_CFG_ERR); +} + + +static struct resource v2m_pcie_i2c_resource = { + .start = V2M_SERIAL_BUS_PCI, + .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device v2m_pcie_i2c_device = { + .name = "versatile-i2c", + .id = 0, + .num_resources = 1, + .resource = &v2m_pcie_i2c_resource, +}; + +static struct resource v2m_ddc_i2c_resource = { + .start = V2M_SERIAL_BUS_DVI, + .end = V2M_SERIAL_BUS_DVI + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device v2m_ddc_i2c_device = { + .name = "versatile-i2c", + .id = 1, + .num_resources = 1, + .resource = &v2m_ddc_i2c_resource, +}; + +static struct resource v2m_eth_resources[] = { + { + .start = V2M_LAN9118, + .end = V2M_LAN9118 + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_V2M_LAN9118, + .end = IRQ_V2M_LAN9118, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config v2m_eth_config = { + .flags = SMSC911X_USE_32BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device v2m_eth_device = { + .name = "smsc911x", + .id = -1, + .resource = v2m_eth_resources, + .num_resources = ARRAY_SIZE(v2m_eth_resources), + .dev.platform_data = &v2m_eth_config, +}; + +static struct resource v2m_usb_resources[] = { + { + .start = V2M_ISP1761, + .end = V2M_ISP1761 + SZ_128K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_V2M_ISP1761, + .end = IRQ_V2M_ISP1761, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct isp1760_platform_data v2m_usb_config = { + .is_isp1761 = true, + .bus_width_16 = false, + .port1_otg = true, + .analog_oc = false, + .dack_polarity_high = false, + .dreq_polarity_high = false, +}; + +static struct platform_device v2m_usb_device = { + .name = "isp1760", + .id = -1, + .resource = v2m_usb_resources, + .num_resources = ARRAY_SIZE(v2m_usb_resources), + .dev.platform_data = &v2m_usb_config, +}; + +static int v2m_flash_init(void) +{ + writel(0, MMIO_P2V(V2M_SYS_FLASH)); + return 0; +} + +static void v2m_flash_exit(void) +{ + writel(0, MMIO_P2V(V2M_SYS_FLASH)); +} + +static void v2m_flash_set_vpp(int on) +{ + writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); +} + +static struct flash_platform_data v2m_flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = v2m_flash_init, + .exit = v2m_flash_exit, + .set_vpp = v2m_flash_set_vpp, +}; + +static struct resource v2m_flash_resources[] = { + { + .start = V2M_NOR0, + .end = V2M_NOR0 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = V2M_NOR1, + .end = V2M_NOR1 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device v2m_flash_device = { + .name = "armflash", + .id = -1, + .resource = v2m_flash_resources, + .num_resources = ARRAY_SIZE(v2m_flash_resources), + .dev.platform_data = &v2m_flash_data, +}; + + +static unsigned int v2m_mmci_status(struct device *dev) +{ + return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0)); +} + +static struct mmci_platform_data v2m_mmci_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = v2m_mmci_status, +}; + +static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); +static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); +static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); +static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); +static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); +static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); +static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); +static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); +static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); +static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); + +static struct amba_device *v2m_amba_devs[] __initdata = { + &aaci_device, + &mmci_device, + &kmi0_device, + &kmi1_device, + &uart0_device, + &uart1_device, + &uart2_device, + &uart3_device, + &wdt_device, + &rtc_device, +}; + + +static long v2m_osc_round(struct clk *clk, unsigned long rate) +{ + return rate; +} + +static int v2m_osc1_set(struct clk *clk, unsigned long rate) +{ + return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate); +} + +static const struct clk_ops osc1_clk_ops = { + .round = v2m_osc_round, + .set = v2m_osc1_set, +}; + +static struct clk osc1_clk = { + .ops = &osc1_clk_ops, + .rate = 24000000, +}; + +static struct clk osc2_clk = { + .rate = 24000000, +}; + +static struct clk_lookup v2m_lookups[] = { + { /* UART0 */ + .dev_id = "mb:uart0", + .clk = &osc2_clk, + }, { /* UART1 */ + .dev_id = "mb:uart1", + .clk = &osc2_clk, + }, { /* UART2 */ + .dev_id = "mb:uart2", + .clk = &osc2_clk, + }, { /* UART3 */ + .dev_id = "mb:uart3", + .clk = &osc2_clk, + }, { /* KMI0 */ + .dev_id = "mb:kmi0", + .clk = &osc2_clk, + }, { /* KMI1 */ + .dev_id = "mb:kmi1", + .clk = &osc2_clk, + }, { /* MMC0 */ + .dev_id = "mb:mmci", + .clk = &osc2_clk, + }, { /* CLCD */ + .dev_id = "mb:clcd", + .clk = &osc1_clk, + }, +}; + +static void v2m_power_off(void) +{ + if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0)) + printk(KERN_EMERG "Unable to shutdown\n"); +} + +static void v2m_restart(char str, const char *cmd) +{ + if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0)) + printk(KERN_EMERG "Unable to reboot\n"); +} + +static int __init v2m_init(void) +{ + int i; + + clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); + + platform_device_register(&v2m_pcie_i2c_device); + platform_device_register(&v2m_ddc_i2c_device); + platform_device_register(&v2m_flash_device); + platform_device_register(&v2m_eth_device); + platform_device_register(&v2m_usb_device); + + for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) + amba_device_register(v2m_amba_devs[i], &iomem_resource); + + pm_power_off = v2m_power_off; + arm_pm_restart = v2m_restart; + + return 0; +} +arch_initcall(v2m_init); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9c6170cd9aac..87ab0568bb0e 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -564,7 +564,7 @@ config I2C_STU300 config I2C_VERSATILE tristate "ARM Versatile/Realview I2C bus support" - depends on ARCH_VERSATILE || ARCH_REALVIEW + depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS select I2C_ALGOBIT help Say yes if you want to support the I2C serial bus on ARMs Versatile -- cgit v1.2.3 From 59ac59f6f1432aa9417d2592bdfd17c99804dd66 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 11 Feb 2010 21:56:07 +0000 Subject: ARM: Add Versatile Express SMP support Signed-off-by: Russell King --- arch/arm/Kconfig | 5 +- arch/arm/mach-vexpress/Makefile | 2 + arch/arm/mach-vexpress/headsmp.S | 39 ++++++ arch/arm/mach-vexpress/include/mach/smp.h | 21 ++++ arch/arm/mach-vexpress/localtimer.c | 26 ++++ arch/arm/mach-vexpress/platsmp.c | 190 ++++++++++++++++++++++++++++++ 6 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-vexpress/headsmp.S create mode 100644 arch/arm/mach-vexpress/include/mach/smp.h create mode 100644 arch/arm/mach-vexpress/localtimer.c create mode 100644 arch/arm/mach-vexpress/platsmp.c (limited to 'arch/arm/Kconfig') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 58080e17c28b..4bb7730a2682 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1121,10 +1121,11 @@ source "kernel/time/Kconfig" config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ - MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) + MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ + ARCH_U8500 || ARCH_VEXPRESS_CA9X4) depends on GENERIC_CLOCKEVENTS select USE_GENERIC_SMP_HELPERS - select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) + select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 3c5e1609fc4f..1b71b77ade22 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -4,3 +4,5 @@ obj-y := v2m.o obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/mach-vexpress/headsmp.S new file mode 100644 index 000000000000..8a78ff68e1ee --- /dev/null +++ b/arch/arm/mach-vexpress/headsmp.S @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mach-vexpress/headsmp.S + * + * Copyright (c) 2003 ARM Limited + * All Rights Reserved + * + * 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 + + __INIT + +/* + * Versatile Express specific entry point for secondary CPUs. This + * provides a "holding pen" into which all secondary cores are held + * until we're ready for them to initialise. + */ +ENTRY(vexpress_secondary_startup) + mrc p15, 0, r0, c0, c0, 5 + and r0, r0, #15 + adr r4, 1f + ldmia r4, {r5, r6} + sub r4, r4, r5 + add r6, r6, r4 +pen: ldr r7, [r6] + cmp r7, r0 + bne pen + + /* + * we've been released from the holding pen: secondary_stack + * should now contain the SVC stack for this core + */ + b secondary_startup + +1: .long . + .long pen_release diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h new file mode 100644 index 000000000000..72a9621ed087 --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/smp.h @@ -0,0 +1,21 @@ +#ifndef __MACH_SMP_H +#define __MACH_SMP_H + +#include + +#define hard_smp_processor_id() \ + ({ \ + unsigned int cpunum; \ + __asm__("mrc p15, 0, %0, c0, c0, 5" \ + : "=r" (cpunum)); \ + cpunum &= 0x0F; \ + }) + +/* + * We use IRQ1 as the IPI + */ +static inline void smp_cross_call(const struct cpumask *mask) +{ + gic_raise_softirq(mask, 1); +} +#endif diff --git a/arch/arm/mach-vexpress/localtimer.c b/arch/arm/mach-vexpress/localtimer.c new file mode 100644 index 000000000000..c0e3a59a0bfc --- /dev/null +++ b/arch/arm/mach-vexpress/localtimer.c @@ -0,0 +1,26 @@ +/* + * linux/arch/arm/mach-vexpress/localtimer.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * 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 + +/* + * Setup the local clock events for a CPU. + */ +void __cpuinit local_timer_setup(struct clock_event_device *evt) +{ + evt->irq = IRQ_LOCALTIMER; + twd_timer_setup(evt); +} diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c new file mode 100644 index 000000000000..670970699ba9 --- /dev/null +++ b/arch/arm/mach-vexpress/platsmp.c @@ -0,0 +1,190 @@ +/* + * linux/arch/arm/mach-vexpress/platsmp.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * 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 +#define V2M_PA_CS7 0x10000000 + +#include "core.h" + +extern void vexpress_secondary_startup(void); + +/* + * control for which core is the next to come out of the secondary + * boot "holding pen" + */ +volatile int __cpuinitdata pen_release = -1; + +static void __iomem *scu_base_addr(void) +{ + return MMIO_P2V(A9_MPCORE_SCU); +} + +static DEFINE_SPINLOCK(boot_lock); + +void __cpuinit platform_secondary_init(unsigned int cpu) +{ + trace_hardirqs_off(); + + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_cpu_init(0, gic_cpu_base_addr); + + /* + * let the primary processor know we're out of the + * pen, then head off into the C entry point + */ + pen_release = -1; + smp_wmb(); + + /* + * Synchronise with the boot thread. + */ + spin_lock(&boot_lock); + spin_unlock(&boot_lock); +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + + /* + * Set synchronisation state between this boot processor + * and the secondary one + */ + spin_lock(&boot_lock); + + /* + * This is really belt and braces; we hold unintended secondary + * CPUs in the holding pen until we're ready for them. However, + * since we haven't sent them a soft interrupt, they shouldn't + * be there. + */ + pen_release = cpu; + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); + + /* + * Send the secondary CPU a soft interrupt, thereby causing + * the boot monitor to read the system wide flags register, + * and branch to the address found there. + */ + smp_cross_call(cpumask_of(cpu)); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + smp_rmb(); + if (pen_release == -1) + break; + + udelay(10); + } + + /* + * now the secondary core is starting up let it run its + * calibrations, then wait for it to finish + */ + spin_unlock(&boot_lock); + + return pen_release != -1 ? -ENOSYS : 0; +} + +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + void __iomem *scu_base = scu_base_addr(); + unsigned int i, ncores; + + ncores = scu_base ? scu_get_core_count(scu_base) : 1; + + /* sanity check */ + if (ncores == 0) { + printk(KERN_ERR + "vexpress: strange CM count of 0? Default to 1\n"); + + ncores = 1; + } + + if (ncores > NR_CPUS) { + printk(KERN_WARNING + "vexpress: no. of cores (%d) greater than configured " + "maximum of %d - clipping\n", + ncores, NR_CPUS); + ncores = NR_CPUS; + } + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + unsigned int ncores = num_possible_cpus(); + unsigned int cpu = smp_processor_id(); + int i; + + smp_store_cpu_info(cpu); + + /* + * are we trying to boot more cores than exist? + */ + if (max_cpus > ncores) + max_cpus = ncores; + + /* + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. + */ + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); + + /* + * Initialise the SCU if there are more than one CPU and let + * them know where to start. + */ + if (max_cpus > 1) { + /* + * Enable the local timer or broadcast device for the + * boot CPU, but only if we have more than one CPU. + */ + percpu_timer_setup(); + + scu_enable(scu_base_addr()); + + /* + * Write the address of secondary startup into the + * system-wide flags register. The boot monitor waits + * until it receives a soft interrupt, and then the + * secondary CPU branches to this address. + */ + writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); + writel(BSYM(virt_to_phys(vexpress_secondary_startup)), + MMIO_P2V(V2M_SYS_FLAGSSET)); + } +} -- cgit v1.2.3