config GENERIC_GPIO
bool
- default n
config GENERIC_TIME
bool
- default n
config GENERIC_CLOCKEVENTS
bool
- default n
config GENERIC_CLOCKEVENTS_BROADCAST
bool
config NO_IOPORT
bool
- default n
config EISA
bool
config ARCH_HAS_ILOG2_U32
bool
- default n
config ARCH_HAS_ILOG2_U64
bool
- default n
config GENERIC_HWEIGHT
bool
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_HOLES_MEMORYMODEL
help
This enables support for the Cirrus EP93xx series of CPUs.
select ARCH_MTD_XIP
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
help
Support for Freescale MXC/iMX-based family of processors
+config ARCH_STMP3XXX
+ bool "Freescale STMP3xxx"
+ select CPU_ARM926T
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select USB_ARCH_HAS_EHCI
+ help
+ Support for systems based on the Freescale 3xxx CPUs.
+
config ARCH_NETX
bool "Hilscher NetX based"
select CPU_ARM926T
help
This enables support for systems based on the Hynix HMS720x
-config ARCH_IMX
- bool "IMX"
- select CPU_ARM920T
- select GENERIC_GPIO
- select GENERIC_TIME
- select GENERIC_CLOCKEVENTS
- help
- Support for Motorola's i.MX family of processors (MX1, MXL).
-
config ARCH_IOP13XX
bool "IOP13xx-based"
depends on MMU
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
config ARCH_W90X900
bool "Nuvoton W90X900 CPU"
select CPU_ARM926T
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_GPIO
+ select COMMON_CLKDEV
help
Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
can login www.mcuos.com or www.nuvoton.com to know more.
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
- select HAVE_CLK
- select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
core with a wide array of integrated devices for
hand-held and low-power applications.
+ config ARCH_U300
+ bool "ST-Ericsson U300 Series"
+ depends on MMU
+ select CPU_ARM926T
+ select ARM_AMBA
+ select ARM_VIC
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_GPIO
+ help
+ Support for ST-Ericsson U300 series mobile platforms.
+
config ARCH_DAVINCI
bool "TI DaVinci"
select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select ZONE_DMA
+ select HAVE_IDE
+ select COMMON_CLKDEV
+ select GENERIC_ALLOCATOR
help
Support for TI's DaVinci platform.
source "arch/arm/mach-s3c6410/Kconfig"
endif
-source "arch/arm/mach-lh7a40x/Kconfig"
+source "arch/arm/plat-stmp3xxx/Kconfig"
-source "arch/arm/mach-imx/Kconfig"
+source "arch/arm/mach-lh7a40x/Kconfig"
source "arch/arm/mach-h720x/Kconfig"
source "arch/arm/mach-msm/Kconfig"
+ source "arch/arm/mach-u300/Kconfig"
+
source "arch/arm/mach-w90x900/Kconfig"
# Definitions to make life easier
source "arch/arm/Kconfig-nommu"
endif
+config ARM_ERRATA_411920
+ bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
+ depends on CPU_V6 && !SMP
+ help
+ Invalidation of the Instruction Cache operation can
+ fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
+ It does not affect the MPCore. This option enables the ARM Ltd.
+ recommended workaround.
+
+config ARM_ERRATA_430973
+ bool "ARM errata: Stale prediction on replaced interworking branch"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 430973 Cortex-A8
+ (r1p0..r1p2) erratum. If a code sequence containing an ARM/Thumb
+ interworking branch is replaced with another code sequence at the
+ same virtual address, whether due to self-modifying code or virtual
+ to physical address re-mapping, Cortex-A8 does not recover from the
+ stale interworking branch prediction. This results in Cortex-A8
+ executing the new code sequence in the incorrect ARM or Thumb state.
+ The workaround enables the BTB/BTAC operations by setting ACTLR.IBE
+ and also flushes the branch target cache at every context switch.
+ Note that setting specific bits in the ACTLR register may not be
+ available in non-secure mode.
+
+config ARM_ERRATA_458693
+ bool "ARM errata: Processor deadlock when a false hazard is created"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 458693 Cortex-A8 (r2p0)
+ erratum. For very specific sequences of memory operations, it is
+ possible for a hazard condition intended for a cache line to instead
+ be incorrectly associated with a different cache line. This false
+ hazard might then cause a processor deadlock. The workaround enables
+ the L1 caching of the NEON accesses and disables the PLD instruction
+ in the ACTLR register. Note that setting specific bits in the ACTLR
+ register may not be available in non-secure mode.
+
+config ARM_ERRATA_460075
+ bool "ARM errata: Data written to the L2 cache can be overwritten with stale data"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 460075 Cortex-A8 (r2p0)
+ erratum. Any asynchronous access to the L2 cache may encounter a
+ situation in which recent store transactions to the L2 cache are lost
+ and overwritten with stale memory contents from external memory. The
+ workaround disables the write-allocate mode for the L2 cache via the
+ ACTLR register. Note that setting specific bits in the ACTLR register
+ may not be available in non-secure mode.
+
endmenu
source "arch/arm/common/Kconfig"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
- depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP)
+ depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
+ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
+ depends on GENERIC_CLOCKEVENTS
select USE_GENERIC_SMP_HELPERS
+ select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4)
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
If you don't know what to do here, say N.
+config HAVE_ARM_SCU
+ bool
+ depends on SMP
+ help
+ This option enables support for the ARM system coherency unit
+
+config HAVE_ARM_TWD
+ bool
+ depends on SMP
+ help
+ This options enables support for the ARM timer and watchdog unit
+
choice
prompt "Memory split"
default VMSPLIT_3G
config LOCAL_TIMERS
bool "Use local timer interrupts"
- depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || REALVIEW_EB_A9MP)
+ depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
+ REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
default y
+ select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4)
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
UNPREDICTABLE (in fact it can be predicted that it won't work
at all). If in doubt say Y.
-config ARCH_FLATMEM_HAS_HOLES
+config ARCH_HAS_HOLES_MEMORYMODEL
bool
- default y
- depends on FLATMEM
# Discontigmem is deprecated
config ARCH_DISCONTIGMEM_ENABLE
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_EBSA110 || \
- ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
+ ARCH_EBSA285 || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91 || ARCH_DAVINCI || \
- ARCH_KS8695 || MACH_RD88F5182
+ ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
correct operation of some network protocols. With an IP-only
configuration it is safe to say N, otherwise say Y.
+config UACCESS_WITH_MEMCPY
+ bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)"
+ depends on MMU && EXPERIMENTAL
+ default y if CPU_FEROCEON
+ help
+ Implement faster copy_to_user and clear_user methods for CPU
+ cores where a 8-word STM instruction give significantly higher
+ memory write throughput than a sequence of individual 32bit stores.
+
+ A possible side effect is a slight increase in scheduling latency
+ between threads sharing the same address space if they invoke
+ such copy operations with large buffers.
+
+ However, if the CPU data cache is using a write-allocate mode,
+ this option is unlikely to provide any performance gain.
+
endmenu
menu "Boot options"
menu "CPU Power Management"
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA)
source "drivers/cpufreq/Kconfig"
If in doubt, say Y.
-config CPU_FREQ_IMX
- tristate "CPUfreq driver for i.MX CPUs"
- depends on ARCH_IMX && CPU_FREQ
- default n
- help
- This enables the CPUfreq driver for i.MX CPUs.
-
- If in doubt, say N.
-
config CPU_FREQ_PXA
bool
depends on CPU_FREQ && ARCH_PXA && PXA25x
# Copyright (C) 1995-2001 by Russell King
LDFLAGS_vmlinux :=-p --no-undefined -X
+ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+LDFLAGS_vmlinux += --be8
+endif
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_GEMINI) := gemini
machine-$(CONFIG_ARCH_H720X) := h720x
-machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
machine-$(CONFIG_ARCH_IOP32X) := iop32x
machine-$(CONFIG_ARCH_OMAP1) := omap1
machine-$(CONFIG_ARCH_OMAP2) := omap2
machine-$(CONFIG_ARCH_OMAP3) := omap2
+machine-$(CONFIG_ARCH_OMAP4) := omap2
machine-$(CONFIG_ARCH_ORION5X) := orion5x
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
+machine-$(CONFIG_ARCH_STMP378X) := stmp378x
+machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+ machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_W90X900) := w90x900
machine-$(CONFIG_FOOTBRIDGE) := footbridge
plat-$(CONFIG_PLAT_PXA) := pxa
plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
+plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
--- /dev/null
- vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0]);
- vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1]);
+ /*
+ *
+ * arch/arm/mach-u300/core.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Core platform support, IRQ handling and device definitions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+ #include <linux/bitops.h>
+ #include <linux/device.h>
+ #include <linux/mm.h>
+ #include <linux/termios.h>
+ #include <linux/amba/bus.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
+
+ #include <asm/types.h>
+ #include <asm/setup.h>
+ #include <asm/memory.h>
+ #include <asm/hardware/vic.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/irq.h>
+
+ #include <mach/hardware.h>
+ #include <mach/syscon.h>
+
+ #include "clock.h"
+ #include "mmc.h"
+
+ /*
+ * Static I/O mappings that are needed for booting the U300 platforms. The
+ * only things we need are the areas where we find the timer, syscon and
+ * intcon, since the remaining device drivers will map their own memory
+ * physical to virtual as the need arise.
+ */
+ static struct map_desc u300_io_desc[] __initdata = {
+ {
+ .virtual = U300_SLOW_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_AHB_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_FAST_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = 0xffff2000, /* TCM memory */
+ .pfn = __phys_to_pfn(0xffff2000),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+
+ /*
+ * This overlaps with the IRQ vectors etc at 0xffff0000, so these
+ * may have to be moved to 0x00000000 in order to use the ROM.
+ */
+ /*
+ {
+ .virtual = U300_BOOTROM_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_BOOTROM_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_ROM,
+ },
+ */
+ };
+
+ void __init u300_map_io(void)
+ {
+ iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
+ }
+
+ /*
+ * Declaration of devices found on the U300 board and
+ * their respective memory locations.
+ */
+ static struct amba_device uart0_device = {
+ .dev = {
+ .init_name = "uart0", /* Slow device at 0x3000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_UART0_BASE,
+ .end = U300_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART0, NO_IRQ },
+ };
+
+ /* The U335 have an additional UART1 on the APP CPU */
+ #ifdef CONFIG_MACH_U300_BS335
+ static struct amba_device uart1_device = {
+ .dev = {
+ .init_name = "uart1", /* Fast device at 0x7000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_UART1_BASE,
+ .end = U300_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART1, NO_IRQ },
+ };
+ #endif
+
+ static struct amba_device pl172_device = {
+ .dev = {
+ .init_name = "pl172", /* AHB device at 0x4000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_EMIF_CFG_BASE,
+ .end = U300_EMIF_CFG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+
+ /*
+ * Everything within this next ifdef deals with external devices connected to
+ * the APP SPI bus.
+ */
+ static struct amba_device pl022_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "pl022", /* Fast device at 0x6000 offset */
+ },
+ .res = {
+ .start = U300_SPI_BASE,
+ .end = U300_SPI_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_SPI, NO_IRQ },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+ };
+
+ static struct amba_device mmcsd_device = {
+ .dev = {
+ .init_name = "mmci", /* Fast device at 0x1000 offset */
+ .platform_data = NULL, /* Added later */
+ },
+ .res = {
+ .start = U300_MMCSD_BASE,
+ .end = U300_MMCSD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+ };
+
+ /*
+ * The order of device declaration may be important, since some devices
+ * have dependencies on other devices being initialized first.
+ */
+ static struct amba_device *amba_devs[] __initdata = {
+ &uart0_device,
+ #ifdef CONFIG_MACH_U300_BS335
+ &uart1_device,
+ #endif
+ &pl022_device,
+ &pl172_device,
+ &mmcsd_device,
+ };
+
+ /* Here follows a list of all hw resources that the platform devices
+ * allocate. Note, clock dependencies are not included
+ */
+
+ static struct resource gpio_resources[] = {
+ {
+ .start = U300_GPIO_BASE,
+ .end = (U300_GPIO_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gpio0",
+ .start = IRQ_U300_GPIO_PORT0,
+ .end = IRQ_U300_GPIO_PORT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio1",
+ .start = IRQ_U300_GPIO_PORT1,
+ .end = IRQ_U300_GPIO_PORT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio2",
+ .start = IRQ_U300_GPIO_PORT2,
+ .end = IRQ_U300_GPIO_PORT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ #ifdef U300_COH901571_3
+ {
+ .name = "gpio3",
+ .start = IRQ_U300_GPIO_PORT3,
+ .end = IRQ_U300_GPIO_PORT3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio4",
+ .start = IRQ_U300_GPIO_PORT4,
+ .end = IRQ_U300_GPIO_PORT4,
+ .flags = IORESOURCE_IRQ,
+ },
+ #ifdef CONFIG_MACH_U300_BS335
+ {
+ .name = "gpio5",
+ .start = IRQ_U300_GPIO_PORT5,
+ .end = IRQ_U300_GPIO_PORT5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio6",
+ .start = IRQ_U300_GPIO_PORT6,
+ .end = IRQ_U300_GPIO_PORT6,
+ .flags = IORESOURCE_IRQ,
+ },
+ #endif /* CONFIG_MACH_U300_BS335 */
+ #endif /* U300_COH901571_3 */
+ };
+
+ static struct resource keypad_resources[] = {
+ {
+ .start = U300_KEYPAD_BASE,
+ .end = U300_KEYPAD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "coh901461-press",
+ .start = IRQ_U300_KEYPAD_KEYBF,
+ .end = IRQ_U300_KEYPAD_KEYBF,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "coh901461-release",
+ .start = IRQ_U300_KEYPAD_KEYBR,
+ .end = IRQ_U300_KEYPAD_KEYBR,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ static struct resource rtc_resources[] = {
+ {
+ .start = U300_RTC_BASE,
+ .end = U300_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_RTC,
+ .end = IRQ_U300_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ /*
+ * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
+ * but these are not yet used by the driver.
+ */
+ static struct resource fsmc_resources[] = {
+ {
+ .start = U300_NAND_IF_PHYS_BASE,
+ .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ static struct resource i2c0_resources[] = {
+ {
+ .start = U300_I2C0_BASE,
+ .end = U300_I2C0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C0,
+ .end = IRQ_U300_I2C0,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ static struct resource i2c1_resources[] = {
+ {
+ .start = U300_I2C1_BASE,
+ .end = U300_I2C1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C1,
+ .end = IRQ_U300_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+
+ };
+
+ static struct resource wdog_resources[] = {
+ {
+ .start = U300_WDOG_BASE,
+ .end = U300_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_WDOG,
+ .end = IRQ_U300_WDOG,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ /* TODO: These should be protected by suitable #ifdef's */
+ static struct resource ave_resources[] = {
+ {
+ .name = "AVE3e I/O Area",
+ .start = U300_VIDEOENC_BASE,
+ .end = U300_VIDEOENC_BASE + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e IRQ0",
+ .start = IRQ_U300_VIDEO_ENC_0,
+ .end = IRQ_U300_VIDEO_ENC_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e IRQ1",
+ .start = IRQ_U300_VIDEO_ENC_1,
+ .end = IRQ_U300_VIDEO_ENC_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e Physmem Area",
+ .start = 0, /* 0 will be remapped to reserved memory */
+ .end = SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ * The AVE3e requires two regions of 256MB that it considers
+ * "invisible". The hardware will not be able to access these
+ * adresses, so they should never point to system RAM.
+ */
+ {
+ .name = "AVE3e Reserved 0",
+ .start = 0xd0000000,
+ .end = 0xd0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e Reserved 1",
+ .start = 0xe0000000,
+ .end = 0xe0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ static struct platform_device wdog_device = {
+ .name = "wdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdog_resources),
+ .resource = wdog_resources,
+ };
+
+ static struct platform_device i2c0_device = {
+ .name = "stddci2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+ .resource = i2c0_resources,
+ };
+
+ static struct platform_device i2c1_device = {
+ .name = "stddci2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+ .resource = i2c1_resources,
+ };
+
+ static struct platform_device gpio_device = {
+ .name = "u300-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ .resource = gpio_resources,
+ };
+
+ static struct platform_device keypad_device = {
+ .name = "keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+ };
+
+ static struct platform_device rtc_device = {
+ .name = "rtc0",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+ };
+
+ static struct platform_device fsmc_device = {
+ .name = "nandif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsmc_resources),
+ .resource = fsmc_resources,
+ };
+
+ static struct platform_device ave_device = {
+ .name = "video_enc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ave_resources),
+ .resource = ave_resources,
+ };
+
+ /*
+ * Notice that AMBA devices are initialized before platform devices.
+ *
+ */
+ static struct platform_device *platform_devs[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &keypad_device,
+ &rtc_device,
+ &gpio_device,
+ &fsmc_device,
+ &wdog_device,
+ &ave_device
+ };
+
+
+ /*
+ * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
+ * together so some interrupts are connected to the first one and some
+ * to the second one.
+ */
+ void __init u300_init_irq(void)
+ {
+ u32 mask[2] = {0, 0};
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++)
+ set_bit(i, (unsigned long *) &mask[0]);
+ u300_enable_intcon_clock();
++ vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], 0);
++ vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], 0);
+ }
+
+
+ /*
+ * U300 platforms peripheral handling
+ */
+ struct db_chip {
+ u16 chipid;
+ const char *name;
+ };
+
+ /*
+ * This is a list of the Digital Baseband chips used in the U300 platform.
+ */
+ static struct db_chip db_chips[] __initdata = {
+ {
+ .chipid = 0xb800,
+ .name = "DB3000",
+ },
+ {
+ .chipid = 0xc000,
+ .name = "DB3100",
+ },
+ {
+ .chipid = 0xc800,
+ .name = "DB3150",
+ },
+ {
+ .chipid = 0xd800,
+ .name = "DB3200",
+ },
+ {
+ .chipid = 0xe000,
+ .name = "DB3250",
+ },
+ {
+ .chipid = 0xe800,
+ .name = "DB3210",
+ },
+ {
+ .chipid = 0xf000,
+ .name = "DB3350 P1x",
+ },
+ {
+ .chipid = 0xf100,
+ .name = "DB3350 P2x",
+ },
+ {
+ .chipid = 0x0000, /* List terminator */
+ .name = NULL,
+ }
+ };
+
+ static void u300_init_check_chip(void)
+ {
+
+ u16 val;
+ struct db_chip *chip;
+ const char *chipname;
+ const char unknown[] = "UNKNOWN";
+
+ /* Read out and print chip ID */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
+ /* This is in funky bigendian order... */
+ val = (val & 0xFFU) << 8 | (val >> 8);
+ chip = db_chips;
+ chipname = unknown;
+
+ for ( ; chip->chipid; chip++) {
+ if (chip->chipid == (val & 0xFF00U)) {
+ chipname = chip->name;
+ break;
+ }
+ }
+ printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
+ "(chip ID 0x%04x)\n", chipname, val);
+
+ #ifdef CONFIG_MACH_U300_BS26
+ if ((val & 0xFF00U) != 0xc800) {
+ printk(KERN_ERR "Platform configured for BS25/BS26 " \
+ "with DB3150 but %s detected, expect problems!",
+ chipname);
+ }
+ #endif
+ #ifdef CONFIG_MACH_U300_BS330
+ if ((val & 0xFF00U) != 0xd800) {
+ printk(KERN_ERR "Platform configured for BS330 " \
+ "with DB3200 but %s detected, expect problems!",
+ chipname);
+ }
+ #endif
+ #ifdef CONFIG_MACH_U300_BS335
+ if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
+ printk(KERN_ERR "Platform configured for BS365 " \
+ " with DB3350 but %s detected, expect problems!",
+ chipname);
+ }
+ #endif
+ #ifdef CONFIG_MACH_U300_BS365
+ if ((val & 0xFF00U) != 0xe800) {
+ printk(KERN_ERR "Platform configured for BS365 " \
+ "with DB3210 but %s detected, expect problems!",
+ chipname);
+ }
+ #endif
+
+
+ }
+
+ /*
+ * Some devices and their resources require reserved physical memory from
+ * the end of the available RAM. This function traverses the list of devices
+ * and assigns actual adresses to these.
+ */
+ static void __init u300_assign_physmem(void)
+ {
+ unsigned long curr_start = __pa(high_memory);
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
+ for (j = 0; j < platform_devs[i]->num_resources; j++) {
+ struct resource *const res =
+ &platform_devs[i]->resource[j];
+
+ if (IORESOURCE_MEM == res->flags &&
+ 0 == res->start) {
+ res->start = curr_start;
+ res->end += curr_start;
+ curr_start += (res->end - res->start + 1);
+
+ printk(KERN_INFO "core.c: Mapping RAM " \
+ "%#x-%#x to device %s:%s\n",
+ res->start, res->end,
+ platform_devs[i]->name, res->name);
+ }
+ }
+ }
+ }
+
+ void __init u300_init_devices(void)
+ {
+ int i;
+ u16 val;
+
+ /* Check what platform we run and print some status information */
+ u300_init_check_chip();
+
+ /* Set system to run at PLL208, max performance, a known state. */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Wait for the PLL208 to lock if not locked in yet */
+ while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
+ U300_SYSCON_CSR_PLL208_LOCK_IND));
+
+ /* Register the AMBA devices in the AMBA bus abstraction layer */
+ u300_clock_primecells();
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+ u300_unclock_primecells();
+
+ u300_assign_physmem();
+
+ /* Register the platform devices */
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+ #ifndef CONFIG_MACH_U300_SEMI_IS_SHARED
+ /*
+ * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when
+ * both subsystems are requesting this mode.
+ * If we not share the Acc SDRAM, this is never the case. Therefore
+ * enable it here from the App side.
+ */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
+ U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
+ #endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */
+ }
+
+ static int core_module_init(void)
+ {
+ /*
+ * This needs to be initialized later: it needs the input framework
+ * to be initialized first.
+ */
+ return mmc_init(&mmcsd_device);
+ }
+ module_init(core_module_init);
--- /dev/null
-static cycle_t u300_get_cycles(void)
+ /*
+ *
+ * arch/arm/mach-u300/timer.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Timer COH 901 328, runs the OS timer interrupt.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+ #include <linux/interrupt.h>
+ #include <linux/time.h>
+ #include <linux/timex.h>
+ #include <linux/clockchips.h>
+ #include <linux/clocksource.h>
+ #include <linux/types.h>
+ #include <linux/io.h>
+
+ #include <mach/hardware.h>
+
+ /* Generic stuff */
+ #include <asm/mach/map.h>
+ #include <asm/mach/time.h>
+ #include <asm/mach/irq.h>
+
+ #include "clock.h"
+
+ /*
+ * APP side special timer registers
+ * This timer contains four timers which can fire an interrupt each.
+ * OS (operating system) timer @ 32768 Hz
+ * DD (device driver) timer @ 1 kHz
+ * GP1 (general purpose 1) timer @ 1MHz
+ * GP2 (general purpose 2) timer @ 1MHz
+ */
+
+ /* Reset OS Timer 32bit (-/W) */
+ #define U300_TIMER_APP_ROST (0x0000)
+ #define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000)
+ /* Enable OS Timer 32bit (-/W) */
+ #define U300_TIMER_APP_EOST (0x0004)
+ #define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000)
+ /* Disable OS Timer 32bit (-/W) */
+ #define U300_TIMER_APP_DOST (0x0008)
+ #define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000)
+ /* OS Timer Mode Register 32bit (-/W) */
+ #define U300_TIMER_APP_SOSTM (0x000c)
+ #define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001)
+ /* OS Timer Status Register 32bit (R/-) */
+ #define U300_TIMER_APP_OSTS (0x0010)
+ #define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F)
+ #define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001)
+ #define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002)
+ #define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010)
+ #define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020)
+ #define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020)
+ #define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040)
+ #define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080)
+ /* OS Timer Current Count Register 32bit (R/-) */
+ #define U300_TIMER_APP_OSTCC (0x0014)
+ /* OS Timer Terminal Count Register 32bit (R/W) */
+ #define U300_TIMER_APP_OSTTC (0x0018)
+ /* OS Timer Interrupt Enable Register 32bit (-/W) */
+ #define U300_TIMER_APP_OSTIE (0x001c)
+ #define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000)
+ #define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001)
+ /* OS Timer Interrupt Acknowledge Register 32bit (-/W) */
+ #define U300_TIMER_APP_OSTIA (0x0020)
+ #define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080)
+
+ /* Reset DD Timer 32bit (-/W) */
+ #define U300_TIMER_APP_RDDT (0x0040)
+ #define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000)
+ /* Enable DD Timer 32bit (-/W) */
+ #define U300_TIMER_APP_EDDT (0x0044)
+ #define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000)
+ /* Disable DD Timer 32bit (-/W) */
+ #define U300_TIMER_APP_DDDT (0x0048)
+ #define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000)
+ /* DD Timer Mode Register 32bit (-/W) */
+ #define U300_TIMER_APP_SDDTM (0x004c)
+ #define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001)
+ /* DD Timer Status Register 32bit (R/-) */
+ #define U300_TIMER_APP_DDTS (0x0050)
+ #define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F)
+ #define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001)
+ #define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002)
+ #define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010)
+ #define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020)
+ #define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020)
+ #define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040)
+ #define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080)
+ /* DD Timer Current Count Register 32bit (R/-) */
+ #define U300_TIMER_APP_DDTCC (0x0054)
+ /* DD Timer Terminal Count Register 32bit (R/W) */
+ #define U300_TIMER_APP_DDTTC (0x0058)
+ /* DD Timer Interrupt Enable Register 32bit (-/W) */
+ #define U300_TIMER_APP_DDTIE (0x005c)
+ #define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000)
+ #define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001)
+ /* DD Timer Interrupt Acknowledge Register 32bit (-/W) */
+ #define U300_TIMER_APP_DDTIA (0x0060)
+ #define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080)
+
+ /* Reset GP1 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_RGPT1 (0x0080)
+ #define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000)
+ /* Enable GP1 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_EGPT1 (0x0084)
+ #define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000)
+ /* Disable GP1 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_DGPT1 (0x0088)
+ #define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000)
+ /* GP1 Timer Mode Register 32bit (-/W) */
+ #define U300_TIMER_APP_SGPT1M (0x008c)
+ #define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001)
+ /* GP1 Timer Status Register 32bit (R/-) */
+ #define U300_TIMER_APP_GPT1S (0x0090)
+ #define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F)
+ #define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001)
+ #define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002)
+ #define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010)
+ #define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020)
+ #define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020)
+ #define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040)
+ #define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080)
+ /* GP1 Timer Current Count Register 32bit (R/-) */
+ #define U300_TIMER_APP_GPT1CC (0x0094)
+ /* GP1 Timer Terminal Count Register 32bit (R/W) */
+ #define U300_TIMER_APP_GPT1TC (0x0098)
+ /* GP1 Timer Interrupt Enable Register 32bit (-/W) */
+ #define U300_TIMER_APP_GPT1IE (0x009c)
+ #define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000)
+ #define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001)
+ /* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */
+ #define U300_TIMER_APP_GPT1IA (0x00a0)
+ #define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080)
+
+ /* Reset GP2 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_RGPT2 (0x00c0)
+ #define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000)
+ /* Enable GP2 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_EGPT2 (0x00c4)
+ #define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000)
+ /* Disable GP2 Timer 32bit (-/W) */
+ #define U300_TIMER_APP_DGPT2 (0x00c8)
+ #define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000)
+ /* GP2 Timer Mode Register 32bit (-/W) */
+ #define U300_TIMER_APP_SGPT2M (0x00cc)
+ #define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001)
+ /* GP2 Timer Status Register 32bit (R/-) */
+ #define U300_TIMER_APP_GPT2S (0x00d0)
+ #define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F)
+ #define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001)
+ #define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002)
+ #define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010)
+ #define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020)
+ #define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000)
+ #define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020)
+ #define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040)
+ #define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080)
+ /* GP2 Timer Current Count Register 32bit (R/-) */
+ #define U300_TIMER_APP_GPT2CC (0x00d4)
+ /* GP2 Timer Terminal Count Register 32bit (R/W) */
+ #define U300_TIMER_APP_GPT2TC (0x00d8)
+ /* GP2 Timer Interrupt Enable Register 32bit (-/W) */
+ #define U300_TIMER_APP_GPT2IE (0x00dc)
+ #define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000)
+ #define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001)
+ /* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */
+ #define U300_TIMER_APP_GPT2IA (0x00e0)
+ #define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080)
+
+ /* Clock request control register - all four timers */
+ #define U300_TIMER_APP_CRC (0x100)
+ #define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
+
+ #define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
+ #define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
+
+ /*
+ * The u300_set_mode() function is always called first, if we
+ * have oneshot timer active, the oneshot scheduling function
+ * u300_set_next_event() is called immediately after.
+ */
+ static void u300_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+ {
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Set the periodic mode to a certain number of ticks per
+ * jiffy.
+ */
+ writel(TICKS_PER_JIFFY,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * Set continuous mode, so the timer keeps triggering
+ * interrupts.
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Just break; here? */
+ /*
+ * The actual event will be programmed by the next event hook,
+ * so we just set a dummy value somewhere at the end of the
+ * universe here.
+ */
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Expire far in the future, u300_set_next_event() will be
+ * called soon...
+ */
+ writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /* We run one shot per tick here! */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable interrupts for this timer */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Enable timer */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* Disable interrupts on GP1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ /* Ignore this call */
+ break;
+ }
+ }
+
+ /*
+ * The app timer in one shot mode obviously has to be reprogrammed
+ * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace
+ * the interrupt disable + timer disable commands with a reset command,
+ * it will fail miserably. Apparently (and I found this the hard way)
+ * the timer is very sensitive to the instruction order, though you don't
+ * get that impression from the data sheet.
+ */
+ static int u300_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+
+ {
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+ /* IRQ in n * cycles */
+ writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * We run one shot per tick here! (This is necessary to reconfigure,
+ * the timer will tilt if you don't!)
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ return 0;
+ }
+
+
+ /* Use general purpose timer 1 as clock event */
+ static struct clock_event_device clockevent_u300_1mhz = {
+ .name = "GPT1",
+ .rating = 300, /* Reasonably fast and accurate clock event */
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
+ .shift = 22,
+ .set_next_event = u300_set_next_event,
+ .set_mode = u300_set_mode,
+ };
+
+ /* Clock event timer interrupt handler */
+ static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
+ {
+ struct clock_event_device *evt = &clockevent_u300_1mhz;
+ /* ACK/Clear timer IRQ for the APP GPT1 Timer */
+ writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+ }
+
+ static struct irqaction u300_timer_irq = {
+ .name = "U300 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = u300_timer_interrupt,
+ };
+
+ /* Use general purpose timer 2 as clock source */
++static cycle_t u300_get_cycles(struct clocksource *cs)
+ {
+ return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+ }
+
+ static struct clocksource clocksource_u300_1mhz = {
+ .name = "GPT2",
+ .rating = 300, /* Reasonably fast and accurate clock source */
+ .read = u300_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32), /* 32 bits */
+ /* 22 calculated using the algorithm in arch/mips/kernel/time.c */
+ .shift = 22,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ };
+
+
+ /*
+ * This sets up the system timers, clock source and clock event.
+ */
+ static void __init u300_timer_init(void)
+ {
+ u300_enable_timer_clock();
+ /*
+ * Disable the "OS" and "DD" timers - these are designed for Symbian!
+ * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
+ */
+ writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC);
+ writel(U300_TIMER_APP_ROST_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST);
+ writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST);
+ writel(U300_TIMER_APP_RDDT_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT);
+ writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT);
+
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+
+ /* Set up the IRQ handler */
+ setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq);
+
+ /* Reset the General Purpose timer 2 */
+ writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2);
+ /* Set this timer to run around forever */
+ writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC);
+ /* Set continuous mode so it wraps around */
+ writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M);
+ /* Disable timer interrupts */
+ writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE);
+ /* Then enable the GP2 timer to use as a free running us counter */
+ writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
+
+ /* This is a pure microsecond clock source */
+ clocksource_u300_1mhz.mult =
+ clocksource_khz2mult(1000, clocksource_u300_1mhz.shift);
+ if (clocksource_register(&clocksource_u300_1mhz))
+ printk(KERN_ERR "timer: failed to initialize clock "
+ "source %s\n", clocksource_u300_1mhz.name);
+
+ clockevent_u300_1mhz.mult =
+ div_sc(1000000, NSEC_PER_SEC, clockevent_u300_1mhz.shift);
+ /* 32bit counter, so 32bits delta is max */
+ clockevent_u300_1mhz.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz);
+ /* This timer is slow enough to set for 1 cycle == 1 MHz */
+ clockevent_u300_1mhz.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_u300_1mhz);
+ clockevent_u300_1mhz.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_u300_1mhz);
+ /*
+ * TODO: init and register the rest of the timers too, they can be
+ * used by hrtimers!
+ */
+ }
+
+ /*
+ * Very simple system timer that only register the clock event and
+ * clock source.
+ */
+ struct sys_timer u300_timer = {
+ .init = u300_timer_init,
+ };
{
return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL;
}
+EXPORT_SYMBOL(get_mem_type);
/*
* Adjust the PMD section entries according to the CPU in use.
reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
BOOTMEM_EXCLUSIVE);
+ /*
+ * U300 - This platform family can share physical memory
+ * between two ARM cpus, one running Linux and the other
+ * running another OS.
+ */
+ if (machine_is_u300()) {
+ #ifdef CONFIG_MACH_U300_SINGLE_RAM
+ #if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+ res_size = 0x00100000;
+ #endif
+ #endif
+ }
+
#ifdef CONFIG_SA1111
/*
* Because of the SA1111 DMA bug, we want to preserve our