diff options
| author | Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | 2009-03-26 10:06:08 +0200 | 
|---|---|---|
| committer | Paulius Zaleckas <paulius.zaleckas@teltonika.lt> | 2009-03-26 10:06:08 +0200 | 
| commit | 59d3a193f1ec1639db447aa1ceb39cd1811fb36e (patch) | |
| tree | e5c5572b3b8b654da76f0fa82c3c78449bb53e90 | |
| parent | 6a915af99fc974be8f2180132ddff7d32aad8779 (diff) | |
ARM: Add Gemini architecture v3
Adds support for Cortina Systems Gemini family CPUs:
http://www.cortina-systems.com/products/category/18
v3:
- fixed __io(a) to be defined as __typesafe_io(a)
v2:
- #include <asm/io.h> -> <linux/io.h>
- remove asm/system.h include
- revorked mm.c to use named initializers
- removed "empty" dma.h
- updated copyrights
Signed-off-by: Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
21 files changed, 1033 insertions, 0 deletions
| diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dbfdf87f993f..5686f4074dd0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -275,6 +275,12 @@ config ARCH_EP93XX  	help  	  This enables support for the Cirrus EP93xx series of CPUs. +config ARCH_GEMINI +	bool "Cortina Systems Gemini" +	select CPU_FA526 +	help +	  Support for the Cortina Systems Gemini family SoCs +  config ARCH_FOOTBRIDGE  	bool "FootBridge"  	select CPU_SA110 @@ -598,6 +604,8 @@ source "arch/arm/mach-ep93xx/Kconfig"  source "arch/arm/mach-footbridge/Kconfig" +source "arch/arm/mach-gemini/Kconfig" +  source "arch/arm/mach-integrator/Kconfig"  source "arch/arm/mach-iop32x/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index d29f9260fb1c..56e13bf22027 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -108,6 +108,7 @@ endif   machine-$(CONFIG_ARCH_PXA)	   := pxa   machine-$(CONFIG_ARCH_L7200)	   := l7200   machine-$(CONFIG_ARCH_INTEGRATOR) := integrator + machine-$(CONFIG_ARCH_GEMINI)     := gemini   textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000   machine-$(CONFIG_ARCH_CLPS711X)   := clps711x   machine-$(CONFIG_ARCH_IOP32X)	   := iop32x diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig new file mode 100644 index 000000000000..3aff39abb188 --- /dev/null +++ b/arch/arm/mach-gemini/Kconfig @@ -0,0 +1,12 @@ +if ARCH_GEMINI + +menu "Cortina Systems Gemini Implementations" + +endmenu + +config GEMINI_MEM_SWAP +	bool "Gemini memory is swapped" +	help +	  Say Y here if Gemini memory is swapped by bootloader. + +endif diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile new file mode 100644 index 000000000000..133e2050685e --- /dev/null +++ b/arch/arm/mach-gemini/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y			:= irq.o mm.o time.o devices.o diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot new file mode 100644 index 000000000000..22a52c228d93 --- /dev/null +++ b/arch/arm/mach-gemini/Makefile.boot @@ -0,0 +1,9 @@ +ifeq ($(CONFIG_GEMINI_MEM_SWAP),y) +   zreladdr-y	:= 0x00008000 +params_phys-y	:= 0x00000100 +initrd_phys-y	:= 0x00800000 +else +   zreladdr-y	:= 0x10008000 +params_phys-y	:= 0x10000100 +initrd_phys-y	:= 0x10800000 +endif diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h new file mode 100644 index 000000000000..9c1afa1c5803 --- /dev/null +++ b/arch/arm/mach-gemini/common.h @@ -0,0 +1,27 @@ +/* + * Common Gemini architecture functions + * + * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ + +#ifndef __GEMINI_COMMON_H__ +#define __GEMINI_COMMON_H__ + +struct mtd_partition; + +extern void gemini_map_io(void); +extern void gemini_init_irq(void); +extern void gemini_timer_init(void); + +/* Common platform devices registration functions */ +extern int platform_register_uart(void); +extern int platform_register_pflash(unsigned int size, +				    struct mtd_partition *parts, +				    unsigned int nr_parts); + +#endif /* __GEMINI_COMMON_H__ */ diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c new file mode 100644 index 000000000000..6b525253d027 --- /dev/null +++ b/arch/arm/mach-gemini/devices.c @@ -0,0 +1,92 @@ +/* + * Common devices definition for Gemini + * + * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> + +#include <mach/irqs.h> +#include <mach/hardware.h> +#include <mach/global_reg.h> + +static struct plat_serial8250_port serial_platform_data[] = { +	{ +		.membase	= (void *)IO_ADDRESS(GEMINI_UART_BASE), +		.mapbase	= GEMINI_UART_BASE, +		.irq		= IRQ_UART, +		.uartclk	= UART_CLK, +		.regshift	= 2, +		.iotype		= UPIO_MEM, +		.type		= PORT_16550A, +		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE, +	}, +	{}, +}; + +static struct platform_device serial_device = { +	.name	= "serial8250", +	.id	= PLAT8250_DEV_PLATFORM, +	.dev	= { +		.platform_data = serial_platform_data, +	}, +}; + +int platform_register_uart(void) +{ +	return platform_device_register(&serial_device); +} + +static struct resource flash_resource = { +	.start	= GEMINI_FLASH_BASE, +	.flags	= IORESOURCE_MEM, +}; + +static struct physmap_flash_data pflash_platform_data = {}; + +static struct platform_device pflash_device = { +	.name	= "physmap-flash", +	.id	= 0, +	.dev 	= { +		.platform_data = &pflash_platform_data, +	}, +	.resource = &flash_resource, +	.num_resources = 1, +}; + +int platform_register_pflash(unsigned int size, struct mtd_partition *parts, +			     unsigned int nr_parts) +{ +	unsigned int reg; + +	reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS); + +	if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL) +		return -ENXIO; + +	if (reg & FLASH_WIDTH_16BIT) +		pflash_platform_data.width = 2; +	else +		pflash_platform_data.width = 1; + +	/* enable parallel flash pins and disable others */ +	reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); +	reg &= ~PFLASH_PADS_DISABLE; +	reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE; +	__raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL); + +	flash_resource.end = flash_resource.start + size - 1; + +	pflash_platform_data.parts = parts; +	pflash_platform_data.nr_parts = nr_parts; + +	return platform_device_register(&pflash_device); +} diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S new file mode 100644 index 000000000000..d04a6eaeae14 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/debug-macro.S @@ -0,0 +1,23 @@ +/* + * Debugging macro include header + * + *  Copyright (C) 1994-1999 Russell King + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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 <mach/hardware.h> + +	.macro	addruart,rx +	mrc	p15, 0, \rx, c1, c0 +	tst	\rx, #1					@ MMU enabled? +	ldreq	\rx, =GEMINI_UART_BASE			@ physical +	ldrne	\rx, =IO_ADDRESS(GEMINI_UART_BASE)	@ virtual +	.endm + +#define UART_SHIFT	2 +#define FLOW_CONTROL +#include <asm/hardware/debug-8250.S> diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S new file mode 100644 index 000000000000..1624f91a2b8b --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/entry-macro.S @@ -0,0 +1,39 @@ +/* + * Low-level IRQ helper macros for Gemini platform. + * + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This file is licensed under  the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <mach/hardware.h> + +#define IRQ_STATUS	0x14 + +	.macro  disable_fiq +	.endm + +	.macro  get_irqnr_preamble, base, tmp +	.endm + +	.macro  arch_ret_to_user, tmp1, tmp2 +	.endm + +	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp +	ldr     \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS) +	ldr     \irqnr, [\irqstat] +	cmp     \irqnr, #0 +	beq     2313f +	mov     \tmp, \irqnr +	mov     \irqnr, #0 +2312: +	tst     \tmp, #1 +	bne     2313f +	add     \irqnr, \irqnr, #1 +	mov     \tmp, \tmp, lsr #1 +	cmp     \irqnr, #31 +	bcc     2312b +2313: +	.endm diff --git a/arch/arm/mach-gemini/include/mach/global_reg.h b/arch/arm/mach-gemini/include/mach/global_reg.h new file mode 100644 index 000000000000..de7ff7e849fc --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/global_reg.h @@ -0,0 +1,278 @@ +/* + *  This file contains the hardware definitions for Gemini. + * + *  Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ +#ifndef __MACH_GLOBAL_REG_H +#define __MACH_GLOBAL_REG_H + +/* Global Word ID Register*/ +#define GLOBAL_ID			0x00 + +#define CHIP_ID(reg)			((reg) >> 8) +#define CHIP_REVISION(reg)		((reg) & 0xFF) + +/* Global Status Register */ +#define GLOBAL_STATUS			0x04 + +#define CPU_BIG_ENDIAN			(1 << 31) +#define PLL_OSC_30M			(1 << 30)	/* else 60MHz */ + +#define OPERATION_MODE_MASK		(0xF << 26) +#define OPM_IDDQ			(0xF << 26) +#define OPM_NAND			(0xE << 26) +#define OPM_RING			(0xD << 26) +#define OPM_DIRECT_BOOT			(0xC << 26) +#define OPM_USB1_PHY_TEST		(0xB << 26) +#define OPM_USB0_PHY_TEST		(0xA << 26) +#define OPM_SATA1_PHY_TEST		(0x9 << 26) +#define OPM_SATA0_PHY_TEST		(0x8 << 26) +#define OPM_ICE_ARM			(0x7 << 26) +#define OPM_ICE_FARADAY			(0x6 << 26) +#define OPM_PLL_BYPASS			(0x5 << 26) +#define OPM_DEBUG			(0x4 << 26) +#define OPM_BURN_IN			(0x3 << 26) +#define OPM_MBIST			(0x2 << 26) +#define OPM_SCAN			(0x1 << 26) +#define OPM_REAL			(0x0 << 26) + +#define FLASH_TYPE_MASK			(0x3 << 24) +#define FLASH_TYPE_NAND_2K		(0x3 << 24) +#define FLASH_TYPE_NAND_512		(0x2 << 24) +#define FLASH_TYPE_PARALLEL		(0x1 << 24) +#define FLASH_TYPE_SERIAL		(0x0 << 24) +/* if parallel */ +#define FLASH_WIDTH_16BIT		(1 << 23)	/* else 8 bit */ +/* if serial */ +#define FLASH_ATMEL			(1 << 23)	/* else STM */ + +#define FLASH_SIZE_MASK			(0x3 << 21) +#define NAND_256M			(0x3 << 21)	/* and more */ +#define NAND_128M			(0x2 << 21) +#define NAND_64M			(0x1 << 21) +#define NAND_32M			(0x0 << 21) +#define ATMEL_16M			(0x3 << 21)	/* and more */ +#define ATMEL_8M			(0x2 << 21) +#define ATMEL_4M_2M			(0x1 << 21) +#define ATMEL_1M			(0x0 << 21)	/* and less */ +#define STM_32M				(1 << 22)	/* and more */ +#define STM_16M				(0 << 22)	/* and less */ + +#define FLASH_PARALLEL_HIGH_PIN_CNT	(1 << 20)	/* else low pin cnt */ + +#define CPU_AHB_RATIO_MASK		(0x3 << 18) +#define CPU_AHB_1_1			(0x0 << 18) +#define CPU_AHB_3_2			(0x1 << 18) +#define CPU_AHB_24_13			(0x2 << 18) +#define CPU_AHB_2_1			(0x3 << 18) + +#define REG_TO_AHB_SPEED(reg)		((((reg) >> 15) & 0x7) * 10 + 130) +#define AHB_SPEED_TO_REG(x)		((((x - 130)) / 10) << 15) + +/* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */ +#define OVERRIDE_FLASH_TYPE_SHIFT	16 +#define OVERRIDE_FLASH_WIDTH_SHIFT	16 +#define OVERRIDE_FLASH_SIZE_SHIFT	16 +#define OVERRIDE_CPU_AHB_RATIO_SHIFT	15 +#define OVERRIDE_AHB_SPEED_SHIFT	15 + +/* Global PLL Control Register */ +#define GLOBAL_PLL_CTRL			0x08 + +#define PLL_BYPASS			(1 << 31) +#define PLL_POWER_DOWN			(1 << 8) +#define PLL_CONTROL_Q			(0x1F << 0) + +/* Global Soft Reset Control Register */ +#define GLOBAL_RESET			0x0C + +#define RESET_GLOBAL			(1 << 31) +#define RESET_CPU1			(1 << 30) +#define RESET_TVE			(1 << 28) +#define RESET_SATA1			(1 << 27) +#define RESET_SATA0			(1 << 26) +#define RESET_CIR			(1 << 25) +#define RESET_EXT_DEV			(1 << 24) +#define RESET_WD			(1 << 23) +#define RESET_GPIO2			(1 << 22) +#define RESET_GPIO1			(1 << 21) +#define RESET_GPIO0			(1 << 20) +#define RESET_SSP			(1 << 19) +#define RESET_UART			(1 << 18) +#define RESET_TIMER			(1 << 17) +#define RESET_RTC			(1 << 16) +#define RESET_INT1			(1 << 15) +#define RESET_INT0			(1 << 14) +#define RESET_LCD			(1 << 13) +#define RESET_LPC			(1 << 12) +#define RESET_APB			(1 << 11) +#define RESET_DMA			(1 << 10) +#define RESET_USB1			(1 << 9) +#define RESET_USB0			(1 << 8) +#define RESET_PCI			(1 << 7) +#define RESET_GMAC1			(1 << 6) +#define RESET_GMAC0			(1 << 5) +#define RESET_SECURITY			(1 << 4) +#define RESET_RAID			(1 << 3) +#define RESET_IDE			(1 << 2) +#define RESET_FLASH			(1 << 1) +#define RESET_DRAM			(1 << 0) + +/* Global IO Pad Driving Capability Control Register */ +#define GLOBAL_IO_DRIVING_CTRL		0x10 + +#define DRIVING_CURRENT_MASK		0x3 + +/* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */ +#define GPIO1_PADS_31_28_SHIFT		28 +#define GPIO0_PADS_31_16_SHIFT		26 +#define GPIO0_PADS_15_0_SHIFT		24 +#define PCI_AND_EXT_RESET_PADS_SHIFT	22 +#define IDE_PADS_SHIFT			20 +#define GMAC1_PADS_SHIFT		18 +#define GMAC0_PADS_SHIFT		16 +/* DRAM is not in mA and poorly documented */ +#define DRAM_CLOCK_PADS_SHIFT		8 +#define DRAM_DATA_PADS_SHIFT		4 +#define DRAM_CONTROL_PADS_SHIFT		0 + +/* Global IO Pad Slew Rate Control Register */ +#define GLOBAL_IO_SLEW_RATE_CTRL	0x14 + +#define GPIO1_PADS_31_28_SLOW		(1 << 10) +#define GPIO0_PADS_31_16_SLOW		(1 << 9) +#define GPIO0_PADS_15_0_SLOW		(1 << 8) +#define PCI_PADS_SLOW			(1 << 7) +#define IDE_PADS_SLOW			(1 << 6) +#define GMAC1_PADS_SLOW			(1 << 5) +#define GMAC0_PADS_SLOW			(1 << 4) +#define DRAM_CLOCK_PADS_SLOW		(1 << 1) +#define DRAM_IO_PADS_SLOW		(1 << 0) + +/* + * General skew control defines + * 16 steps, each step is around 0.2ns + */ +#define SKEW_MASK			0xF + +/* Global IDE PAD Skew Control Register */ +#define GLOBAL_IDE_SKEW_CTRL		0x18 + +#define IDE1_HOST_STROBE_DELAY_SHIFT	28 +#define IDE1_DEVICE_STROBE_DELAY_SHIFT	24 +#define IDE1_OUTPUT_IO_SKEW_SHIFT	20 +#define IDE1_INPUT_IO_SKEW_SHIFT	16 +#define IDE0_HOST_STROBE_DELAY_SHIFT	12 +#define IDE0_DEVICE_STROBE_DELAY_SHIFT	8 +#define IDE0_OUTPUT_IO_SKEW_SHIFT	4 +#define IDE0_INPUT_IO_SKEW_SHIFT	0 + +/* Global GMAC Control Pad Skew Control Register */ +#define GLOBAL_GMAC_CTRL_SKEW_CTRL	0x1C + +#define GMAC1_TXC_SKEW_SHIFT		28 +#define GMAC1_TXEN_SKEW_SHIFT		24 +#define GMAC1_RXC_SKEW_SHIFT		20 +#define GMAC1_RXDV_SKEW_SHIFT		16 +#define GMAC0_TXC_SKEW_SHIFT		12 +#define GMAC0_TXEN_SKEW_SHIFT		8 +#define GMAC0_RXC_SKEW_SHIFT		4 +#define GMAC0_RXDV_SKEW_SHIFT		0 + +/* Global GMAC0 Data PAD Skew Control Register */ +#define GLOBAL_GMAC0_DATA_SKEW_CTRL	0x20 +/* Global GMAC1 Data PAD Skew Control Register */ +#define GLOBAL_GMAC1_DATA_SKEW_CTRL	0x24 + +#define GMAC_TXD_SKEW_SHIFT(x)		(((x) * 4) + 16) +#define GMAC_RXD_SKEW_SHIFT(x)		((x) * 4) + +/* CPU has two AHB busses. */ + +/* Global Arbitration0 Control Register */ +#define GLOBAL_ARBITRATION0_CTRL	0x28 + +#define BOOT_CONTROLLER_HIGH_PRIO	(1 << 3) +#define DMA_BUS1_HIGH_PRIO		(1 << 2) +#define CPU0_HIGH_PRIO			(1 << 0) + +/* Global Arbitration1 Control Register */ +#define GLOBAL_ARBITRATION1_CTRL	0x2C + +#define TVE_HIGH_PRIO			(1 << 9) +#define PCI_HIGH_PRIO			(1 << 8) +#define USB1_HIGH_PRIO			(1 << 7) +#define USB0_HIGH_PRIO			(1 << 6) +#define GMAC1_HIGH_PRIO			(1 << 5) +#define GMAC0_HIGH_PRIO			(1 << 4) +#define SECURITY_HIGH_PRIO		(1 << 3) +#define RAID_HIGH_PRIO			(1 << 2) +#define IDE_HIGH_PRIO			(1 << 1) +#define DMA_BUS2_HIGH_PRIO		(1 << 0) + +/* Common bits for both arbitration registers */ +#define BURST_LENGTH_SHIFT		16 +#define BURST_LENGTH_MASK		(0x3F << 16) + +/* Miscellaneous Control Register */ +#define GLOBAL_MISC_CTRL		0x30 + +#define MEMORY_SPACE_SWAP		(1 << 31) +#define USB1_PLUG_MINIB			(1 << 30) /* else plug is mini-A */ +#define USB0_PLUG_MINIB			(1 << 29) +#define GMAC_GMII			(1 << 28) +#define GMAC_1_ENABLE			(1 << 27) +/* TODO: define ATA/SATA bits */ +#define USB1_VBUS_ON			(1 << 23) +#define USB0_VBUS_ON			(1 << 22) +#define APB_CLKOUT_ENABLE		(1 << 21) +#define TVC_CLKOUT_ENABLE		(1 << 20) +#define EXT_CLKIN_ENABLE		(1 << 19) +#define PCI_66MHZ			(1 << 18) /* else 33 MHz */ +#define PCI_CLKOUT_ENABLE		(1 << 17) +#define LPC_CLKOUT_ENABLE		(1 << 16) +#define USB1_WAKEUP_ON			(1 << 15) +#define USB0_WAKEUP_ON			(1 << 14) +/* TODO: define PCI idle detect bits */ +#define TVC_PADS_ENABLE			(1 << 9) +#define SSP_PADS_ENABLE			(1 << 8) +#define LCD_PADS_ENABLE			(1 << 7) +#define LPC_PADS_ENABLE			(1 << 6) +#define PCI_PADS_ENABLE			(1 << 5) +#define IDE_PADS_ENABLE			(1 << 4) +#define DRAM_PADS_POWER_DOWN		(1 << 3) +#define NAND_PADS_DISABLE		(1 << 2) +#define PFLASH_PADS_DISABLE		(1 << 1) +#define SFLASH_PADS_DISABLE		(1 << 0) + +/* Global Clock Control Register */ +#define GLOBAL_CLOCK_CTRL		0x34 + +#define POWER_STATE_G0			(1 << 31) +#define POWER_STATE_S1			(1 << 30) /* else it is S3/S4 state */ +#define SECURITY_APB_AHB		(1 << 29) +/* else Security APB clk will be 0.75xAHB */ +/* TODO: TVC clock divider */ +#define PCI_CLKRUN_ENABLE		(1 << 16) +#define BOOT_CLK_DISABLE		(1 << 13) +#define TVC_CLK_DISABLE			(1 << 12) +#define FLASH_CLK_DISABLE		(1 << 11) +#define DDR_CLK_DISABLE			(1 << 10) +#define PCI_CLK_DISABLE			(1 << 9) +#define IDE_CLK_DISABLE			(1 << 8) +#define USB1_CLK_DISABLE		(1 << 7) +#define USB0_CLK_DISABLE		(1 << 6) +#define SATA1_CLK_DISABLE		(1 << 5) +#define SATA0_CLK_DISABLE		(1 << 4) +#define GMAC1_CLK_DISABLE		(1 << 3) +#define GMAC0_CLK_DISABLE		(1 << 2) +#define SECURITY_CLK_DISABLE		(1 << 1) + +/* TODO: other registers definitions if needed */ + +#endif /* __MACH_GLOBAL_REG_H */ diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h new file mode 100644 index 000000000000..de6752674c05 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/hardware.h @@ -0,0 +1,75 @@ +/* + *  This file contains the hardware definitions for Gemini. + * + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ +#ifndef __MACH_HARDWARE_H +#define __MACH_HARDWARE_H + +/* + * Memory Map definitions + */ +/* FIXME: Does it really swap SRAM like this? */ +#ifdef CONFIG_GEMINI_MEM_SWAP +# define GEMINI_DRAM_BASE	0x00000000 +# define GEMINI_SRAM_BASE	0x20000000 +#else +# define GEMINI_SRAM_BASE	0x00000000 +# define GEMINI_DRAM_BASE	0x10000000 +#endif +#define GEMINI_FLASH_BASE	0x30000000 +#define GEMINI_GLOBAL_BASE	0x40000000 +#define GEMINI_WAQTCHDOG_BASE	0x41000000 +#define GEMINI_UART_BASE	0x42000000 +#define GEMINI_TIMER_BASE	0x43000000 +#define GEMINI_LCD_BASE		0x44000000 +#define GEMINI_RTC_BASE		0x45000000 +#define GEMINI_SATA_BASE	0x46000000 +#define GEMINI_LPC_HOST_BASE	0x47000000 +#define GEMINI_LPC_IO_BASE	0x47800000 +#define GEMINI_INTERRUPT_BASE	0x48000000 +/* TODO: Different interrupt controlers when SMP + * #define GEMINI_INTERRUPT0_BASE	0x48000000 + * #define GEMINI_INTERRUPT1_BASE	0x49000000 + */ +#define GEMINI_SSP_CTRL_BASE	0x4A000000 +#define GEMINI_POWER_CTRL_BASE	0x4B000000 +#define GEMINI_CIR_BASE		0x4C000000 +#define GEMINI_GPIO_BASE(x)	(0x4D000000 + (x) * 0x1000000) +#define GEMINI_PCI_IO_BASE	0x50000000 +#define GEMINI_PCI_MEM_BASE	0x58000000 +#define GEMINI_TOE_BASE		0x60000000 +#define GEMINI_GMAC0_BASE	0x6000A000 +#define GEMINI_GMAC1_BASE	0x6000E000 +#define GEMINI_SECURITY_BASE	0x62000000 +#define GEMINI_IDE0_BASE	0x63000000 +#define GEMINI_IDE1_BASE	0x63400000 +#define GEMINI_RAID_BASE	0x64000000 +#define GEMINI_FLASH_CTRL_BASE	0x65000000 +#define GEMINI_DRAM_CTRL_BASE	0x66000000 +#define GEMINI_GENERAL_DMA_BASE	0x67000000 +#define GEMINI_USB0_BASE	0x68000000 +#define GEMINI_USB1_BASE	0x69000000 +#define GEMINI_BIG_ENDIAN_BASE	0x80000000 + +#define GEMINI_TIMER1_BASE	GEMINI_TIMER_BASE +#define GEMINI_TIMER2_BASE	(GEMINI_TIMER_BASE + 0x10) +#define GEMINI_TIMER3_BASE	(GEMINI_TIMER_BASE + 0x20) + +/* + * UART Clock when System clk is 150MHz + */ +#define UART_CLK	48000000 + +/* + * macro to get at IO space when running virtually + */ +#define IO_ADDRESS(x)	((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000) + +#endif diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h new file mode 100644 index 000000000000..c548056b98b2 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/io.h @@ -0,0 +1,18 @@ +/* + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#define IO_SPACE_LIMIT	0xffffffff + +#define __io(a)		__typesafe_io(a) +#define __mem_pci(a)	(a) + +#endif /* __MACH_IO_H */ diff --git a/arch/arm/mach-gemini/include/mach/irqs.h b/arch/arm/mach-gemini/include/mach/irqs.h new file mode 100644 index 000000000000..c7728ac458f3 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/irqs.h @@ -0,0 +1,50 @@ +/* + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ + +#ifndef __MACH_IRQS_H__ +#define __MACH_IRQS_H__ + +#define IRQ_SERIRQ1	31 +#define IRQ_SERIRQ0	30 +#define IRQ_PCID	29 +#define IRQ_PCIC	28 +#define IRQ_PCIB	27 +#define IRQ_PWR		26 +#define IRQ_CIR		25 +#define IRQ_GPIO(x)	(22 + (x)) +#define IRQ_SSP		21 +#define IRQ_LPC		20 +#define IRQ_LCD		19 +#define IRQ_UART	18 +#define IRQ_RTC		17 +#define IRQ_TIMER3	16 +#define IRQ_TIMER2	15 +#define IRQ_TIMER1	14 +#define IRQ_FLASH	12 +#define IRQ_USB1	11 +#define IRQ_USB0	10 +#define IRQ_DMA		9 +#define IRQ_PCI		8 +#define IRQ_IPSEC	7 +#define IRQ_RAID	6 +#define IRQ_IDE1	5 +#define IRQ_IDE0	4 +#define IRQ_WATCHDOG	3 +#define IRQ_GMAC1	2 +#define IRQ_GMAC0	1 +#define IRQ_IPI		0 + +#define NORMAL_IRQ_NUM	32 + +#define ARCH_TIMER_IRQ	IRQ_TIMER2 + +#define NR_IRQS		NORMAL_IRQ_NUM + +#endif /* __MACH_IRQS_H__ */ diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h new file mode 100644 index 000000000000..2d14d5bf1f9f --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/memory.h @@ -0,0 +1,19 @@ +/* + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +#ifdef CONFIG_GEMINI_MEM_SWAP +# define PHYS_OFFSET	UL(0x00000000) +#else +# define PHYS_OFFSET	UL(0x10000000) +#endif + +#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h new file mode 100644 index 000000000000..bbbd72767a02 --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/system.h @@ -0,0 +1,37 @@ +/* + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ +#ifndef __MACH_SYSTEM_H +#define __MACH_SYSTEM_H + +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/global_reg.h> + +static inline void arch_idle(void) +{ +	/* +	 * Because of broken hardware we have to enable interrupts or the CPU +	 * will never wakeup... Acctualy it is not very good to enable +	 * interrupts here since scheduler can miss a tick, but there is +	 * no other way around this. Platforms that needs it for power saving +	 * should call enable_hlt() in init code, since by default it is +	 * disabled. +	 */ +	local_irq_enable(); +	cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ +	__raw_writel(RESET_GLOBAL | RESET_CPU1, +		     IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET); +} + +#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h new file mode 100644 index 000000000000..dc5690ba975c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/timex.h @@ -0,0 +1,13 @@ +/* + * Gemini timex specifications + * + * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ + +/* When AHB bus frequency is 150MHz */ +#define CLOCK_TICK_RATE	38000000 diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h new file mode 100644 index 000000000000..59c5df7e716c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/uncompress.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * Based on mach-pxa/include/mach/uncompress.h: + * Copyright:	(C) 2001 MontaVista Software Inc. + * + * 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. + */ + +#ifndef __MACH_UNCOMPRESS_H +#define __MACH_UNCOMPRESS_H + +#include <linux/serial_reg.h> +#include <mach/hardware.h> + +static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE; + +/* + * The following code assumes the serial port has already been + * initialized by the bootloader.  If you didn't setup a port in + * your bootloader then nothing will appear (which might be desired). + */ +static inline void putc(char c) +{ +	while (!(UART[UART_LSR] & UART_LSR_THRE)) +		barrier(); +	UART[UART_TX] = c; +} + +#define flush() do { } while (0) + +/* + * nothing to do + */ +#define arch_decomp_setup() + +#define arch_decomp_wdog() + +#endif /* __MACH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-gemini/include/mach/vmalloc.h b/arch/arm/mach-gemini/include/mach/vmalloc.h new file mode 100644 index 000000000000..83e536d9436c --- /dev/null +++ b/arch/arm/mach-gemini/include/mach/vmalloc.h @@ -0,0 +1,10 @@ +/* + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * 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. + */ + +#define VMALLOC_END	0xF0000000 diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c new file mode 100644 index 000000000000..9e613ca8120d --- /dev/null +++ b/arch/arm/mach-gemini/irq.c @@ -0,0 +1,102 @@ +/* + *  Interrupt routines for Gemini + * + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/stddef.h> +#include <linux/list.h> +#include <linux/sched.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <mach/hardware.h> + +#define IRQ_SOURCE(base_addr)	(base_addr + 0x00) +#define IRQ_MASK(base_addr)	(base_addr + 0x04) +#define IRQ_CLEAR(base_addr)	(base_addr + 0x08) +#define IRQ_TMODE(base_addr)	(base_addr + 0x0C) +#define IRQ_TLEVEL(base_addr)	(base_addr + 0x10) +#define IRQ_STATUS(base_addr)	(base_addr + 0x14) +#define FIQ_SOURCE(base_addr)	(base_addr + 0x20) +#define FIQ_MASK(base_addr)	(base_addr + 0x24) +#define FIQ_CLEAR(base_addr)	(base_addr + 0x28) +#define FIQ_TMODE(base_addr)	(base_addr + 0x2C) +#define FIQ_LEVEL(base_addr)	(base_addr + 0x30) +#define FIQ_STATUS(base_addr)	(base_addr + 0x34) + +static void gemini_ack_irq(unsigned int irq) +{ +	__raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +} + +static void gemini_mask_irq(unsigned int irq) +{ +	unsigned int mask; + +	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +	mask &= ~(1 << irq); +	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +} + +static void gemini_unmask_irq(unsigned int irq) +{ +	unsigned int mask; + +	mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +	mask |= (1 << irq); +	__raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +} + +static struct irq_chip gemini_irq_chip = { +	.name	= "INTC", +	.ack	= gemini_ack_irq, +	.mask	= gemini_mask_irq, +	.unmask	= gemini_unmask_irq, +}; + +static struct resource irq_resource = { +	.name	= "irq_handler", +	.start	= IO_ADDRESS(GEMINI_INTERRUPT_BASE), +	.end	= IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4, +}; + +void __init gemini_init_irq(void) +{ +	unsigned int i, mode = 0, level = 0; + +	/* +	 * Disable arch_idle() by default since it is buggy +	 * For more info see arch/arm/mach-gemini/include/mach/system.h +	 */ +	disable_hlt(); + +	request_resource(&iomem_resource, &irq_resource); + +	for (i = 0; i < NR_IRQS; i++) { +		set_irq_chip(i, &gemini_irq_chip); +		if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) { +			set_irq_handler(i, handle_edge_irq); +			mode |= 1 << i; +			level |= 1 << i; +		} else {			 +			set_irq_handler(i, handle_level_irq); +		} +		set_irq_flags(i, IRQF_VALID | IRQF_PROBE); +	} + +	/* Disable all interrupts */ +	__raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +	__raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); + +	/* Set interrupt mode */ +	__raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +	__raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE))); +} diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c new file mode 100644 index 000000000000..51948242ec09 --- /dev/null +++ b/arch/arm/mach-gemini/mm.c @@ -0,0 +1,82 @@ +/* + *  Static mappings for Gemini + * + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/mach/map.h> + +#include <mach/hardware.h> + +/* Page table mapping for I/O region */ +static struct map_desc gemini_io_desc[] __initdata = { +	{ +		.virtual	= IO_ADDRESS(GEMINI_GLOBAL_BASE), +		.pfn		=__phys_to_pfn(GEMINI_GLOBAL_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_UART_BASE), +		.pfn		= __phys_to_pfn(GEMINI_UART_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_TIMER_BASE), +		.pfn		= __phys_to_pfn(GEMINI_TIMER_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_INTERRUPT_BASE), +		.pfn		= __phys_to_pfn(GEMINI_INTERRUPT_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_POWER_CTRL_BASE), +		.pfn		= __phys_to_pfn(GEMINI_POWER_CTRL_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(0)), +		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(0)), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(1)), +		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(1)), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_GPIO_BASE(2)), +		.pfn		= __phys_to_pfn(GEMINI_GPIO_BASE(2)), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_FLASH_CTRL_BASE), +		.pfn		= __phys_to_pfn(GEMINI_FLASH_CTRL_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_DRAM_CTRL_BASE), +		.pfn		= __phys_to_pfn(GEMINI_DRAM_CTRL_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, { +		.virtual	= IO_ADDRESS(GEMINI_GENERAL_DMA_BASE), +		.pfn		= __phys_to_pfn(GEMINI_GENERAL_DMA_BASE), +		.length		= SZ_512K, +		.type 		= MT_DEVICE, +	}, +}; + +void __init gemini_map_io(void) +{ +	iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc)); +} diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c new file mode 100644 index 000000000000..21dc5a89d1c4 --- /dev/null +++ b/arch/arm/mach-gemini/time.c @@ -0,0 +1,89 @@ +/* + *  Copyright (C) 2001-2006 Storlink, Corp. + *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/global_reg.h> +#include <asm/mach/time.h> + +/* + * Register definitions for the timers + */ +#define TIMER_COUNT(BASE_ADDR)		(BASE_ADDR  + 0x00) +#define TIMER_LOAD(BASE_ADDR)		(BASE_ADDR  + 0x04) +#define TIMER_MATCH1(BASE_ADDR)		(BASE_ADDR  + 0x08) +#define TIMER_MATCH2(BASE_ADDR)		(BASE_ADDR  + 0x0C) +#define TIMER_CR(BASE_ADDR)		(BASE_ADDR  + 0x30) + +#define TIMER_1_CR_ENABLE		(1 << 0) +#define TIMER_1_CR_CLOCK		(1 << 1) +#define TIMER_1_CR_INT			(1 << 2) +#define TIMER_2_CR_ENABLE		(1 << 3) +#define TIMER_2_CR_CLOCK		(1 << 4) +#define TIMER_2_CR_INT			(1 << 5) +#define TIMER_3_CR_ENABLE		(1 << 6) +#define TIMER_3_CR_CLOCK		(1 << 7) +#define TIMER_3_CR_INT			(1 << 8) + +/* + * IRQ handler for the timer + */ +static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) +{ +	timer_tick(); + +	return IRQ_HANDLED; +} + +static struct irqaction gemini_timer_irq = { +	.name		= "Gemini Timer Tick", +	.flags		= IRQF_DISABLED | IRQF_TIMER, +	.handler	= gemini_timer_interrupt, +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init gemini_timer_init(void) +{ +	unsigned int tick_rate, reg_v; + +	reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS)); +	tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000; + +	printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000); + +	tick_rate /= 6;		/* APB bus run AHB*(1/6) */ + +	switch(reg_v & CPU_AHB_RATIO_MASK) { +	case CPU_AHB_1_1: +		printk(KERN_CONT "(1/1)\n"); +		break; +	case CPU_AHB_3_2: +		printk(KERN_CONT "(3/2)\n"); +		break; +	case CPU_AHB_24_13: +		printk(KERN_CONT "(24/13)\n"); +		break; +	case CPU_AHB_2_1: +		printk(KERN_CONT "(2/1)\n"); +		break; +	} + +	/* +	 * Make irqs happen for the system timer +	 */ +	setup_irq(IRQ_TIMER2, &gemini_timer_irq); +	/* Start the timer */ +	__raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE))); +	__raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE))); +	__raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE))); +} | 
