diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 11 | ||||
-rw-r--r-- | arch/arm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-davinci/Kconfig | 23 | ||||
-rw-r--r-- | arch/arm/mach-davinci/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/mach-davinci/Makefile.boot | 3 | ||||
-rw-r--r-- | arch/arm/mach-davinci/board-evm.c | 131 | ||||
-rw-r--r-- | arch/arm/mach-davinci/id.c | 94 | ||||
-rw-r--r-- | arch/arm/mach-davinci/io.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-davinci/irq.c | 226 | ||||
-rw-r--r-- | arch/arm/mach-davinci/psc.c | 113 | ||||
-rw-r--r-- | arch/arm/mach-davinci/serial.c | 96 | ||||
-rw-r--r-- | arch/arm/mach-davinci/time.c | 372 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 4 |
13 files changed, 1132 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d7c0984d4a86..34d1462e4341 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -384,6 +384,13 @@ config ARCH_OMAP | |||
384 | help | 384 | help |
385 | Support for TI's OMAP platform (OMAP1 and OMAP2). | 385 | Support for TI's OMAP platform (OMAP1 and OMAP2). |
386 | 386 | ||
387 | config ARCH_DAVINCI | ||
388 | bool "TI DaVinci" | ||
389 | select GENERIC_TIME | ||
390 | select GENERIC_CLOCKEVENTS | ||
391 | help | ||
392 | Support for TI's DaVinci platform. | ||
393 | |||
387 | endchoice | 394 | endchoice |
388 | 395 | ||
389 | source "arch/arm/mach-clps711x/Kconfig" | 396 | source "arch/arm/mach-clps711x/Kconfig" |
@@ -445,6 +452,8 @@ source "arch/arm/mach-netx/Kconfig" | |||
445 | 452 | ||
446 | source "arch/arm/mach-ns9xxx/Kconfig" | 453 | source "arch/arm/mach-ns9xxx/Kconfig" |
447 | 454 | ||
455 | source "arch/arm/mach-davinci/Kconfig" | ||
456 | |||
448 | # Definitions to make life easier | 457 | # Definitions to make life easier |
449 | config ARCH_ACORN | 458 | config ARCH_ACORN |
450 | bool | 459 | bool |
@@ -674,7 +683,7 @@ config LEDS | |||
674 | ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ | 683 | ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ |
675 | ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ | 684 | ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ |
676 | ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ | 685 | ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ |
677 | ARCH_AT91 || MACH_TRIZEPS4 | 686 | ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI |
678 | help | 687 | help |
679 | If you say Y here, the LEDs on your machine will be used | 688 | If you say Y here, the LEDs on your machine will be used |
680 | to provide useful information about your current system status. | 689 | to provide useful information about your current system status. |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 00ea4305ad5d..d568d86b0729 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -135,6 +135,7 @@ endif | |||
135 | machine-$(CONFIG_ARCH_NETX) := netx | 135 | machine-$(CONFIG_ARCH_NETX) := netx |
136 | machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx | 136 | machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx |
137 | textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000 | 137 | textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000 |
138 | machine-$(CONFIG_ARCH_DAVINCI) := davinci | ||
138 | 139 | ||
139 | ifeq ($(CONFIG_ARCH_EBSA110),y) | 140 | ifeq ($(CONFIG_ARCH_EBSA110),y) |
140 | # This is what happens if you forget the IOCS16 line. | 141 | # This is what happens if you forget the IOCS16 line. |
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig new file mode 100644 index 000000000000..bac988e7a4c3 --- /dev/null +++ b/arch/arm/mach-davinci/Kconfig | |||
@@ -0,0 +1,23 @@ | |||
1 | if ARCH_DAVINCI | ||
2 | |||
3 | menu "TI DaVinci Implementations" | ||
4 | |||
5 | comment "DaVinci Core Type" | ||
6 | |||
7 | config ARCH_DAVINCI644x | ||
8 | default y | ||
9 | bool "DaVinci 644x based system" | ||
10 | |||
11 | comment "DaVinci Board Type" | ||
12 | |||
13 | config MACH_DAVINCI_EVM | ||
14 | bool "TI DaVinci EVM" | ||
15 | default y | ||
16 | depends on ARCH_DAVINCI644x | ||
17 | help | ||
18 | Configure this option to specify the whether the board used | ||
19 | for development is a DaVinci EVM | ||
20 | |||
21 | endmenu | ||
22 | |||
23 | endif | ||
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile new file mode 100644 index 000000000000..a8f88cd29905 --- /dev/null +++ b/arch/arm/mach-davinci/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | # | ||
5 | |||
6 | # Common objects | ||
7 | obj-y := time.o irq.o serial.o io.o id.o psc.o | ||
8 | |||
9 | # Board specific | ||
10 | obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o | ||
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot new file mode 100644 index 000000000000..e1dd366f836b --- /dev/null +++ b/arch/arm/mach-davinci/Makefile.boot | |||
@@ -0,0 +1,3 @@ | |||
1 | zreladdr-y := 0x80008000 | ||
2 | params_phys-y := 0x80000100 | ||
3 | initrd_phys-y := 0x80800000 | ||
diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c new file mode 100644 index 000000000000..633c12e43044 --- /dev/null +++ b/arch/arm/mach-davinci/board-evm.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * TI DaVinci EVM board support | ||
3 | * | ||
4 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mtd/mtd.h> | ||
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/mtd/physmap.h> | ||
19 | |||
20 | #include <asm/setup.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/hardware.h> | ||
24 | |||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | #include <asm/mach/flash.h> | ||
28 | |||
29 | #include <asm/arch/common.h> | ||
30 | |||
31 | /* other misc. init functions */ | ||
32 | void __init davinci_psc_init(void); | ||
33 | void __init davinci_irq_init(void); | ||
34 | void __init davinci_map_common_io(void); | ||
35 | |||
36 | /* NOR Flash base address set to CS0 by default */ | ||
37 | #define NOR_FLASH_PHYS 0x02000000 | ||
38 | |||
39 | static struct mtd_partition davinci_evm_partitions[] = { | ||
40 | /* bootloader (U-Boot, etc) in first 4 sectors */ | ||
41 | { | ||
42 | .name = "bootloader", | ||
43 | .offset = 0, | ||
44 | .size = 4 * SZ_64K, | ||
45 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
46 | }, | ||
47 | /* bootloader params in the next 1 sectors */ | ||
48 | { | ||
49 | .name = "params", | ||
50 | .offset = MTDPART_OFS_APPEND, | ||
51 | .size = SZ_64K, | ||
52 | .mask_flags = 0, | ||
53 | }, | ||
54 | /* kernel */ | ||
55 | { | ||
56 | .name = "kernel", | ||
57 | .offset = MTDPART_OFS_APPEND, | ||
58 | .size = SZ_2M, | ||
59 | .mask_flags = 0 | ||
60 | }, | ||
61 | /* file system */ | ||
62 | { | ||
63 | .name = "filesystem", | ||
64 | .offset = MTDPART_OFS_APPEND, | ||
65 | .size = MTDPART_SIZ_FULL, | ||
66 | .mask_flags = 0 | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | static struct physmap_flash_data davinci_evm_flash_data = { | ||
71 | .width = 2, | ||
72 | .parts = davinci_evm_partitions, | ||
73 | .nr_parts = ARRAY_SIZE(davinci_evm_partitions), | ||
74 | }; | ||
75 | |||
76 | /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF | ||
77 | * limits addresses to 16M, so using addresses past 16M will wrap */ | ||
78 | static struct resource davinci_evm_flash_resource = { | ||
79 | .start = NOR_FLASH_PHYS, | ||
80 | .end = NOR_FLASH_PHYS + SZ_16M - 1, | ||
81 | .flags = IORESOURCE_MEM, | ||
82 | }; | ||
83 | |||
84 | static struct platform_device davinci_evm_flash_device = { | ||
85 | .name = "physmap-flash", | ||
86 | .id = 0, | ||
87 | .dev = { | ||
88 | .platform_data = &davinci_evm_flash_data, | ||
89 | }, | ||
90 | .num_resources = 1, | ||
91 | .resource = &davinci_evm_flash_resource, | ||
92 | }; | ||
93 | |||
94 | static struct platform_device *davinci_evm_devices[] __initdata = { | ||
95 | &davinci_evm_flash_device, | ||
96 | }; | ||
97 | |||
98 | static void __init | ||
99 | davinci_evm_map_io(void) | ||
100 | { | ||
101 | davinci_map_common_io(); | ||
102 | } | ||
103 | |||
104 | static __init void davinci_evm_init(void) | ||
105 | { | ||
106 | davinci_psc_init(); | ||
107 | |||
108 | #if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE) | ||
109 | printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, " | ||
110 | "but share pins.\n\t Disable IDE for NOR support.\n"); | ||
111 | #endif | ||
112 | |||
113 | platform_add_devices(davinci_evm_devices, | ||
114 | ARRAY_SIZE(davinci_evm_devices)); | ||
115 | } | ||
116 | |||
117 | static __init void davinci_evm_irq_init(void) | ||
118 | { | ||
119 | davinci_irq_init(); | ||
120 | } | ||
121 | |||
122 | MACHINE_START(DAVINCI_EVM, "DaVinci EVM") | ||
123 | /* Maintainer: MontaVista Software <source@mvista.com> */ | ||
124 | .phys_io = IO_PHYS, | ||
125 | .io_pg_offst = (io_p2v(IO_PHYS) >> 18) & 0xfffc, | ||
126 | .boot_params = (DAVINCI_DDR_BASE + 0x100), | ||
127 | .map_io = davinci_evm_map_io, | ||
128 | .init_irq = davinci_evm_irq_init, | ||
129 | .timer = &davinci_timer, | ||
130 | .init_machine = davinci_evm_init, | ||
131 | MACHINE_END | ||
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c new file mode 100644 index 000000000000..70608f76aed8 --- /dev/null +++ b/arch/arm/mach-davinci/id.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Davinci CPU identification code | ||
3 | * | ||
4 | * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com> | ||
5 | * | ||
6 | * Derived from OMAP1 CPU identification code. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | |||
17 | #include <asm/io.h> | ||
18 | |||
19 | #define JTAG_ID_BASE 0x01c40028 | ||
20 | |||
21 | struct davinci_id { | ||
22 | u8 variant; /* JTAG ID bits 31:28 */ | ||
23 | u16 part_no; /* JTAG ID bits 27:12 */ | ||
24 | u32 manufacturer; /* JTAG ID bits 11:1 */ | ||
25 | u32 type; /* Cpu id bits [31:8], cpu class bits [7:0] */ | ||
26 | }; | ||
27 | |||
28 | /* Register values to detect the DaVinci version */ | ||
29 | static struct davinci_id davinci_ids[] __initdata = { | ||
30 | { | ||
31 | /* DM6446 */ | ||
32 | .part_no = 0xb700, | ||
33 | .variant = 0x0, | ||
34 | .manufacturer = 0x017, | ||
35 | .type = 0x64460000, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * Get Device Part No. from JTAG ID register | ||
41 | */ | ||
42 | static u16 __init davinci_get_part_no(void) | ||
43 | { | ||
44 | u32 dev_id, part_no; | ||
45 | |||
46 | dev_id = davinci_readl(JTAG_ID_BASE); | ||
47 | |||
48 | part_no = ((dev_id >> 12) & 0xffff); | ||
49 | |||
50 | return part_no; | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | * Get Device Revision from JTAG ID register | ||
55 | */ | ||
56 | static u8 __init davinci_get_variant(void) | ||
57 | { | ||
58 | u32 variant; | ||
59 | |||
60 | variant = davinci_readl(JTAG_ID_BASE); | ||
61 | |||
62 | variant = (variant >> 28) & 0xf; | ||
63 | |||
64 | return variant; | ||
65 | } | ||
66 | |||
67 | void __init davinci_check_revision(void) | ||
68 | { | ||
69 | int i; | ||
70 | u16 part_no; | ||
71 | u8 variant; | ||
72 | |||
73 | part_no = davinci_get_part_no(); | ||
74 | variant = davinci_get_variant(); | ||
75 | |||
76 | /* First check only the major version in a safe way */ | ||
77 | for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) { | ||
78 | if (part_no == (davinci_ids[i].part_no)) { | ||
79 | system_rev = davinci_ids[i].type; | ||
80 | break; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | /* Check if we can find the dev revision */ | ||
85 | for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) { | ||
86 | if (part_no == davinci_ids[i].part_no && | ||
87 | variant == davinci_ids[i].variant) { | ||
88 | system_rev = davinci_ids[i].type; | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | printk("DaVinci DM%04x variant 0x%x\n", system_rev >> 16, variant); | ||
94 | } | ||
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c new file mode 100644 index 000000000000..87fae6fb6ecf --- /dev/null +++ b/arch/arm/mach-davinci/io.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * DaVinci I/O mapping code | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/tlb.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/memory.h> | ||
18 | |||
19 | #include <asm/mach/map.h> | ||
20 | |||
21 | extern void davinci_check_revision(void); | ||
22 | |||
23 | /* | ||
24 | * The machine specific code may provide the extra mapping besides the | ||
25 | * default mapping provided here. | ||
26 | */ | ||
27 | static struct map_desc davinci_io_desc[] __initdata = { | ||
28 | { | ||
29 | .virtual = IO_VIRT, | ||
30 | .pfn = __phys_to_pfn(IO_PHYS), | ||
31 | .length = IO_SIZE, | ||
32 | .type = MT_DEVICE | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | void __init davinci_map_common_io(void) | ||
37 | { | ||
38 | iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc)); | ||
39 | |||
40 | /* Normally devicemaps_init() would flush caches and tlb after | ||
41 | * mdesc->map_io(), but we must also do it here because of the CPU | ||
42 | * revision check below. | ||
43 | */ | ||
44 | local_flush_tlb_all(); | ||
45 | flush_cache_all(); | ||
46 | |||
47 | /* We want to check CPU revision early for cpu_is_xxxx() macros. | ||
48 | * IO space mapping must be initialized before we can do that. | ||
49 | */ | ||
50 | davinci_check_revision(); | ||
51 | } | ||
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c new file mode 100644 index 000000000000..1333d84d2e45 --- /dev/null +++ b/arch/arm/mach-davinci/irq.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * Interrupt handler for DaVinci boards. | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/irq.h> | ||
25 | |||
26 | #include <asm/hardware.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/mach/irq.h> | ||
29 | |||
30 | #define IRQ_BIT(irq) ((irq) & 0x1f) | ||
31 | |||
32 | #define FIQ_REG0_OFFSET 0x0000 | ||
33 | #define FIQ_REG1_OFFSET 0x0004 | ||
34 | #define IRQ_REG0_OFFSET 0x0008 | ||
35 | #define IRQ_REG1_OFFSET 0x000C | ||
36 | #define IRQ_ENT_REG0_OFFSET 0x0018 | ||
37 | #define IRQ_ENT_REG1_OFFSET 0x001C | ||
38 | #define IRQ_INCTL_REG_OFFSET 0x0020 | ||
39 | #define IRQ_EABASE_REG_OFFSET 0x0024 | ||
40 | #define IRQ_INTPRI0_REG_OFFSET 0x0030 | ||
41 | #define IRQ_INTPRI7_REG_OFFSET 0x004C | ||
42 | |||
43 | static inline unsigned int davinci_irq_readl(int offset) | ||
44 | { | ||
45 | return davinci_readl(DAVINCI_ARM_INTC_BASE + offset); | ||
46 | } | ||
47 | |||
48 | static inline void davinci_irq_writel(unsigned long value, int offset) | ||
49 | { | ||
50 | davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset); | ||
51 | } | ||
52 | |||
53 | /* Disable interrupt */ | ||
54 | static void davinci_mask_irq(unsigned int irq) | ||
55 | { | ||
56 | unsigned int mask; | ||
57 | u32 l; | ||
58 | |||
59 | mask = 1 << IRQ_BIT(irq); | ||
60 | |||
61 | if (irq > 31) { | ||
62 | l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET); | ||
63 | l &= ~mask; | ||
64 | davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET); | ||
65 | } else { | ||
66 | l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET); | ||
67 | l &= ~mask; | ||
68 | davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | /* Enable interrupt */ | ||
73 | static void davinci_unmask_irq(unsigned int irq) | ||
74 | { | ||
75 | unsigned int mask; | ||
76 | u32 l; | ||
77 | |||
78 | mask = 1 << IRQ_BIT(irq); | ||
79 | |||
80 | if (irq > 31) { | ||
81 | l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET); | ||
82 | l |= mask; | ||
83 | davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET); | ||
84 | } else { | ||
85 | l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET); | ||
86 | l |= mask; | ||
87 | davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* EOI interrupt */ | ||
92 | static void davinci_ack_irq(unsigned int irq) | ||
93 | { | ||
94 | unsigned int mask; | ||
95 | |||
96 | mask = 1 << IRQ_BIT(irq); | ||
97 | |||
98 | if (irq > 31) | ||
99 | davinci_irq_writel(mask, IRQ_REG1_OFFSET); | ||
100 | else | ||
101 | davinci_irq_writel(mask, IRQ_REG0_OFFSET); | ||
102 | } | ||
103 | |||
104 | static struct irq_chip davinci_irq_chip_0 = { | ||
105 | .name = "AINTC", | ||
106 | .ack = davinci_ack_irq, | ||
107 | .mask = davinci_mask_irq, | ||
108 | .unmask = davinci_unmask_irq, | ||
109 | }; | ||
110 | |||
111 | |||
112 | /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ | ||
113 | static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = { | ||
114 | [IRQ_VDINT0] = 2, | ||
115 | [IRQ_VDINT1] = 6, | ||
116 | [IRQ_VDINT2] = 6, | ||
117 | [IRQ_HISTINT] = 6, | ||
118 | [IRQ_H3AINT] = 6, | ||
119 | [IRQ_PRVUINT] = 6, | ||
120 | [IRQ_RSZINT] = 6, | ||
121 | [7] = 7, | ||
122 | [IRQ_VENCINT] = 6, | ||
123 | [IRQ_ASQINT] = 6, | ||
124 | [IRQ_IMXINT] = 6, | ||
125 | [IRQ_VLCDINT] = 6, | ||
126 | [IRQ_USBINT] = 4, | ||
127 | [IRQ_EMACINT] = 4, | ||
128 | [14] = 7, | ||
129 | [15] = 7, | ||
130 | [IRQ_CCINT0] = 5, /* dma */ | ||
131 | [IRQ_CCERRINT] = 5, /* dma */ | ||
132 | [IRQ_TCERRINT0] = 5, /* dma */ | ||
133 | [IRQ_TCERRINT] = 5, /* dma */ | ||
134 | [IRQ_PSCIN] = 7, | ||
135 | [21] = 7, | ||
136 | [IRQ_IDE] = 4, | ||
137 | [23] = 7, | ||
138 | [IRQ_MBXINT] = 7, | ||
139 | [IRQ_MBRINT] = 7, | ||
140 | [IRQ_MMCINT] = 7, | ||
141 | [IRQ_SDIOINT] = 7, | ||
142 | [28] = 7, | ||
143 | [IRQ_DDRINT] = 7, | ||
144 | [IRQ_AEMIFINT] = 7, | ||
145 | [IRQ_VLQINT] = 4, | ||
146 | [IRQ_TINT0_TINT12] = 2, /* clockevent */ | ||
147 | [IRQ_TINT0_TINT34] = 2, /* clocksource */ | ||
148 | [IRQ_TINT1_TINT12] = 7, /* DSP timer */ | ||
149 | [IRQ_TINT1_TINT34] = 7, /* system tick */ | ||
150 | [IRQ_PWMINT0] = 7, | ||
151 | [IRQ_PWMINT1] = 7, | ||
152 | [IRQ_PWMINT2] = 7, | ||
153 | [IRQ_I2C] = 3, | ||
154 | [IRQ_UARTINT0] = 3, | ||
155 | [IRQ_UARTINT1] = 3, | ||
156 | [IRQ_UARTINT2] = 3, | ||
157 | [IRQ_SPINT0] = 3, | ||
158 | [IRQ_SPINT1] = 3, | ||
159 | [45] = 7, | ||
160 | [IRQ_DSP2ARM0] = 4, | ||
161 | [IRQ_DSP2ARM1] = 4, | ||
162 | [IRQ_GPIO0] = 7, | ||
163 | [IRQ_GPIO1] = 7, | ||
164 | [IRQ_GPIO2] = 7, | ||
165 | [IRQ_GPIO3] = 7, | ||
166 | [IRQ_GPIO4] = 7, | ||
167 | [IRQ_GPIO5] = 7, | ||
168 | [IRQ_GPIO6] = 7, | ||
169 | [IRQ_GPIO7] = 7, | ||
170 | [IRQ_GPIOBNK0] = 7, | ||
171 | [IRQ_GPIOBNK1] = 7, | ||
172 | [IRQ_GPIOBNK2] = 7, | ||
173 | [IRQ_GPIOBNK3] = 7, | ||
174 | [IRQ_GPIOBNK4] = 7, | ||
175 | [IRQ_COMMTX] = 7, | ||
176 | [IRQ_COMMRX] = 7, | ||
177 | [IRQ_EMUINT] = 7, | ||
178 | }; | ||
179 | |||
180 | /* ARM Interrupt Controller Initialization */ | ||
181 | void __init davinci_irq_init(void) | ||
182 | { | ||
183 | unsigned i; | ||
184 | const u8 *priority = default_priorities; | ||
185 | |||
186 | /* Clear all interrupt requests */ | ||
187 | davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); | ||
188 | davinci_irq_writel(~0x0, FIQ_REG1_OFFSET); | ||
189 | davinci_irq_writel(~0x0, IRQ_REG0_OFFSET); | ||
190 | davinci_irq_writel(~0x0, IRQ_REG1_OFFSET); | ||
191 | |||
192 | /* Disable all interrupts */ | ||
193 | davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET); | ||
194 | davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET); | ||
195 | |||
196 | /* Interrupts disabled immediately, IRQ entry reflects all */ | ||
197 | davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET); | ||
198 | |||
199 | /* we don't use the hardware vector table, just its entry addresses */ | ||
200 | davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET); | ||
201 | |||
202 | /* Clear all interrupt requests */ | ||
203 | davinci_irq_writel(~0x0, FIQ_REG0_OFFSET); | ||
204 | davinci_irq_writel(~0x0, FIQ_REG1_OFFSET); | ||
205 | davinci_irq_writel(~0x0, IRQ_REG0_OFFSET); | ||
206 | davinci_irq_writel(~0x0, IRQ_REG1_OFFSET); | ||
207 | |||
208 | for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) { | ||
209 | unsigned j; | ||
210 | u32 pri; | ||
211 | |||
212 | for (j = 0, pri = 0; j < 32; j += 4, priority++) | ||
213 | pri |= (*priority & 0x07) << j; | ||
214 | davinci_irq_writel(pri, i); | ||
215 | } | ||
216 | |||
217 | /* set up genirq dispatch for ARM INTC */ | ||
218 | for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) { | ||
219 | set_irq_chip(i, &davinci_irq_chip_0); | ||
220 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
221 | if (i != IRQ_TINT1_TINT34) | ||
222 | set_irq_handler(i, handle_edge_irq); | ||
223 | else | ||
224 | set_irq_handler(i, handle_level_irq); | ||
225 | } | ||
226 | } | ||
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c new file mode 100644 index 000000000000..e1b0050283a6 --- /dev/null +++ b/arch/arm/mach-davinci/psc.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * TI DaVinci Power and Sleep Controller (PSC) | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | |||
25 | #include <asm/io.h> | ||
26 | #include <asm/hardware.h> | ||
27 | #include <asm/arch/psc.h> | ||
28 | |||
29 | #define PTCMD __REG(0x01C41120) | ||
30 | #define PDSTAT __REG(0x01C41200) | ||
31 | #define PDCTL1 __REG(0x01C41304) | ||
32 | #define EPCPR __REG(0x01C41070) | ||
33 | #define PTSTAT __REG(0x01C41128) | ||
34 | |||
35 | #define MDSTAT IO_ADDRESS(0x01C41800) | ||
36 | #define MDCTL IO_ADDRESS(0x01C41A00) | ||
37 | |||
38 | #define PINMUX0 __REG(0x01c40000) | ||
39 | #define PINMUX1 __REG(0x01c40004) | ||
40 | #define VDD3P3V_PWDN __REG(0x01C40048) | ||
41 | |||
42 | static void davinci_psc_mux(unsigned int id) | ||
43 | { | ||
44 | switch (id) { | ||
45 | case DAVINCI_LPSC_ATA: | ||
46 | PINMUX0 |= (1 << 17) | (1 << 16); | ||
47 | break; | ||
48 | case DAVINCI_LPSC_MMC_SD: | ||
49 | /* VDD power manupulations are done in U-Boot for CPMAC | ||
50 | * so applies to MMC as well | ||
51 | */ | ||
52 | /*Set up the pull regiter for MMC */ | ||
53 | VDD3P3V_PWDN = 0x0; | ||
54 | PINMUX1 &= (~(1 << 9)); | ||
55 | break; | ||
56 | case DAVINCI_LPSC_I2C: | ||
57 | PINMUX1 |= (1 << 7); | ||
58 | break; | ||
59 | case DAVINCI_LPSC_McBSP: | ||
60 | PINMUX1 |= (1 << 10); | ||
61 | break; | ||
62 | default: | ||
63 | break; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | /* Enable or disable a PSC domain */ | ||
68 | void davinci_psc_config(unsigned int domain, unsigned int id, char enable) | ||
69 | { | ||
70 | volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id); | ||
71 | volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id); | ||
72 | |||
73 | if (id < 0) | ||
74 | return; | ||
75 | |||
76 | if (enable) | ||
77 | *mdctl |= 0x00000003; /* Enable Module */ | ||
78 | else | ||
79 | *mdctl &= 0xFFFFFFF2; /* Disable Module */ | ||
80 | |||
81 | if ((PDSTAT & 0x00000001) == 0) { | ||
82 | PDCTL1 |= 0x1; | ||
83 | PTCMD = (1 << domain); | ||
84 | while ((((EPCPR >> domain) & 1) == 0)); | ||
85 | |||
86 | PDCTL1 |= 0x100; | ||
87 | while (!(((PTSTAT >> domain) & 1) == 0)); | ||
88 | } else { | ||
89 | PTCMD = (1 << domain); | ||
90 | while (!(((PTSTAT >> domain) & 1) == 0)); | ||
91 | } | ||
92 | |||
93 | if (enable) | ||
94 | while (!((*mdstat & 0x0000001F) == 0x3)); | ||
95 | else | ||
96 | while (!((*mdstat & 0x0000001F) == 0x2)); | ||
97 | |||
98 | if (enable) | ||
99 | davinci_psc_mux(id); | ||
100 | } | ||
101 | |||
102 | void __init davinci_psc_init(void) | ||
103 | { | ||
104 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1); | ||
105 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1); | ||
106 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1); | ||
107 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1); | ||
108 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1); | ||
109 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1); | ||
110 | |||
111 | /* Turn on WatchDog timer LPSC. Needed for RESET to work */ | ||
112 | davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1); | ||
113 | } | ||
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c new file mode 100644 index 000000000000..8368c93c788d --- /dev/null +++ b/arch/arm/mach-davinci/serial.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * TI DaVinci serial driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | #include <linux/serial_reg.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/clk.h> | ||
29 | |||
30 | #include <asm/io.h> | ||
31 | #include <asm/irq.h> | ||
32 | #include <asm/hardware.h> | ||
33 | #include <asm/arch/serial.h> | ||
34 | #include <asm/arch/irqs.h> | ||
35 | |||
36 | #define UART_DAVINCI_PWREMU 0x0c | ||
37 | |||
38 | static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up, | ||
39 | int offset) | ||
40 | { | ||
41 | offset <<= up->regshift; | ||
42 | return (unsigned int)__raw_readb(up->membase + offset); | ||
43 | } | ||
44 | |||
45 | static inline void davinci_serial_outp(struct plat_serial8250_port *p, | ||
46 | int offset, int value) | ||
47 | { | ||
48 | offset <<= p->regshift; | ||
49 | __raw_writeb(value, p->membase + offset); | ||
50 | } | ||
51 | |||
52 | static struct plat_serial8250_port serial_platform_data[] = { | ||
53 | { | ||
54 | .membase = (char *)IO_ADDRESS(DAVINCI_UART0_BASE), | ||
55 | .mapbase = (unsigned long)DAVINCI_UART0_BASE, | ||
56 | .irq = IRQ_UARTINT0, | ||
57 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | ||
58 | .iotype = UPIO_MEM, | ||
59 | .regshift = 2, | ||
60 | .uartclk = 27000000, | ||
61 | }, | ||
62 | { | ||
63 | .flags = 0 | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static struct platform_device serial_device = { | ||
68 | .name = "serial8250", | ||
69 | .id = PLAT8250_DEV_PLATFORM, | ||
70 | .dev = { | ||
71 | .platform_data = serial_platform_data, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | static void __init davinci_serial_reset(struct plat_serial8250_port *p) | ||
76 | { | ||
77 | /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */ | ||
78 | unsigned int pwremu = 0; | ||
79 | |||
80 | davinci_serial_outp(p, UART_IER, 0); /* disable all interrupts */ | ||
81 | |||
82 | davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu); | ||
83 | mdelay(10); | ||
84 | |||
85 | pwremu |= (0x3 << 13); | ||
86 | pwremu |= 0x1; | ||
87 | davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu); | ||
88 | } | ||
89 | |||
90 | static int __init davinci_init(void) | ||
91 | { | ||
92 | davinci_serial_reset(&serial_platform_data[0]); | ||
93 | return platform_device_register(&serial_device); | ||
94 | } | ||
95 | |||
96 | arch_initcall(davinci_init); | ||
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c new file mode 100644 index 000000000000..4d8425de6922 --- /dev/null +++ b/arch/arm/mach-davinci/time.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | * DaVinci timer subsystem | ||
3 | * | ||
4 | * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/clocksource.h> | ||
16 | #include <linux/clockchips.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | |||
19 | #include <asm/io.h> | ||
20 | #include <asm/hardware.h> | ||
21 | #include <asm/system.h> | ||
22 | #include <asm/irq.h> | ||
23 | #include <asm/mach/irq.h> | ||
24 | #include <asm/mach/time.h> | ||
25 | #include <asm/errno.h> | ||
26 | #include <asm/arch/io.h> | ||
27 | |||
28 | static struct clock_event_device clockevent_davinci; | ||
29 | |||
30 | #define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400) | ||
31 | #define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800) | ||
32 | #define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00) | ||
33 | |||
34 | enum { | ||
35 | T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS, | ||
36 | }; | ||
37 | |||
38 | #define IS_TIMER1(id) (id & 0x2) | ||
39 | #define IS_TIMER0(id) (!IS_TIMER1(id)) | ||
40 | #define IS_TIMER_TOP(id) ((id & 0x1)) | ||
41 | #define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id)) | ||
42 | |||
43 | static int timer_irqs[NUM_TIMERS] = { | ||
44 | IRQ_TINT0_TINT12, | ||
45 | IRQ_TINT0_TINT34, | ||
46 | IRQ_TINT1_TINT12, | ||
47 | IRQ_TINT1_TINT34, | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * This driver configures the 2 64-bit count-up timers as 4 independent | ||
52 | * 32-bit count-up timers used as follows: | ||
53 | * | ||
54 | * T0_BOT: Timer 0, bottom: clockevent source for hrtimers | ||
55 | * T0_TOP: Timer 0, top : clocksource for generic timekeeping | ||
56 | * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code) | ||
57 | * T1_TOP: Timer 1, top : <unused> | ||
58 | */ | ||
59 | #define TID_CLOCKEVENT T0_BOT | ||
60 | #define TID_CLOCKSOURCE T0_TOP | ||
61 | |||
62 | /* Timer register offsets */ | ||
63 | #define PID12 0x0 | ||
64 | #define TIM12 0x10 | ||
65 | #define TIM34 0x14 | ||
66 | #define PRD12 0x18 | ||
67 | #define PRD34 0x1c | ||
68 | #define TCR 0x20 | ||
69 | #define TGCR 0x24 | ||
70 | #define WDTCR 0x28 | ||
71 | |||
72 | /* Timer register bitfields */ | ||
73 | #define TCR_ENAMODE_DISABLE 0x0 | ||
74 | #define TCR_ENAMODE_ONESHOT 0x1 | ||
75 | #define TCR_ENAMODE_PERIODIC 0x2 | ||
76 | #define TCR_ENAMODE_MASK 0x3 | ||
77 | |||
78 | #define TGCR_TIMMODE_SHIFT 2 | ||
79 | #define TGCR_TIMMODE_64BIT_GP 0x0 | ||
80 | #define TGCR_TIMMODE_32BIT_UNCHAINED 0x1 | ||
81 | #define TGCR_TIMMODE_64BIT_WDOG 0x2 | ||
82 | #define TGCR_TIMMODE_32BIT_CHAINED 0x3 | ||
83 | |||
84 | #define TGCR_TIM12RS_SHIFT 0 | ||
85 | #define TGCR_TIM34RS_SHIFT 1 | ||
86 | #define TGCR_RESET 0x0 | ||
87 | #define TGCR_UNRESET 0x1 | ||
88 | #define TGCR_RESET_MASK 0x3 | ||
89 | |||
90 | #define WDTCR_WDEN_SHIFT 14 | ||
91 | #define WDTCR_WDEN_DISABLE 0x0 | ||
92 | #define WDTCR_WDEN_ENABLE 0x1 | ||
93 | #define WDTCR_WDKEY_SHIFT 16 | ||
94 | #define WDTCR_WDKEY_SEQ0 0xa5c6 | ||
95 | #define WDTCR_WDKEY_SEQ1 0xda7e | ||
96 | |||
97 | struct timer_s { | ||
98 | char *name; | ||
99 | unsigned int id; | ||
100 | unsigned long period; | ||
101 | unsigned long opts; | ||
102 | unsigned long reg_base; | ||
103 | unsigned long tim_reg; | ||
104 | unsigned long prd_reg; | ||
105 | unsigned long enamode_shift; | ||
106 | struct irqaction irqaction; | ||
107 | }; | ||
108 | static struct timer_s timers[]; | ||
109 | |||
110 | /* values for 'opts' field of struct timer_s */ | ||
111 | #define TIMER_OPTS_DISABLED 0x00 | ||
112 | #define TIMER_OPTS_ONESHOT 0x01 | ||
113 | #define TIMER_OPTS_PERIODIC 0x02 | ||
114 | |||
115 | static int timer32_config(struct timer_s *t) | ||
116 | { | ||
117 | u32 tcr = davinci_readl(t->reg_base + TCR); | ||
118 | |||
119 | /* disable timer */ | ||
120 | tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift); | ||
121 | davinci_writel(tcr, t->reg_base + TCR); | ||
122 | |||
123 | /* reset counter to zero, set new period */ | ||
124 | davinci_writel(0, t->tim_reg); | ||
125 | davinci_writel(t->period, t->prd_reg); | ||
126 | |||
127 | /* Set enable mode */ | ||
128 | if (t->opts & TIMER_OPTS_ONESHOT) { | ||
129 | tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift; | ||
130 | } else if (t->opts & TIMER_OPTS_PERIODIC) { | ||
131 | tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift; | ||
132 | } | ||
133 | |||
134 | davinci_writel(tcr, t->reg_base + TCR); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static inline u32 timer32_read(struct timer_s *t) | ||
139 | { | ||
140 | return davinci_readl(t->tim_reg); | ||
141 | } | ||
142 | |||
143 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | ||
144 | { | ||
145 | struct clock_event_device *evt = &clockevent_davinci; | ||
146 | |||
147 | evt->event_handler(evt); | ||
148 | return IRQ_HANDLED; | ||
149 | } | ||
150 | |||
151 | /* called when 32-bit counter wraps */ | ||
152 | static irqreturn_t freerun_interrupt(int irq, void *dev_id) | ||
153 | { | ||
154 | return IRQ_HANDLED; | ||
155 | } | ||
156 | |||
157 | static struct timer_s timers[] = { | ||
158 | [TID_CLOCKEVENT] = { | ||
159 | .name = "clockevent", | ||
160 | .opts = TIMER_OPTS_DISABLED, | ||
161 | .irqaction = { | ||
162 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
163 | .handler = timer_interrupt, | ||
164 | } | ||
165 | }, | ||
166 | [TID_CLOCKSOURCE] = { | ||
167 | .name = "free-run counter", | ||
168 | .period = ~0, | ||
169 | .opts = TIMER_OPTS_PERIODIC, | ||
170 | .irqaction = { | ||
171 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
172 | .handler = freerun_interrupt, | ||
173 | } | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | static void __init timer_init(void) | ||
178 | { | ||
179 | u32 bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE}; | ||
180 | int i; | ||
181 | |||
182 | /* Global init of each 64-bit timer as a whole */ | ||
183 | for(i=0; i<2; i++) { | ||
184 | u32 tgcr, base = bases[i]; | ||
185 | |||
186 | /* Disabled, Internal clock source */ | ||
187 | davinci_writel(0, base + TCR); | ||
188 | |||
189 | /* reset both timers, no pre-scaler for timer34 */ | ||
190 | tgcr = 0; | ||
191 | davinci_writel(tgcr, base + TGCR); | ||
192 | |||
193 | /* Set both timers to unchained 32-bit */ | ||
194 | tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT; | ||
195 | davinci_writel(tgcr, base + TGCR); | ||
196 | |||
197 | /* Unreset timers */ | ||
198 | tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | | ||
199 | (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); | ||
200 | davinci_writel(tgcr, base + TGCR); | ||
201 | |||
202 | /* Init both counters to zero */ | ||
203 | davinci_writel(0, base + TIM12); | ||
204 | davinci_writel(0, base + TIM34); | ||
205 | } | ||
206 | |||
207 | /* Init of each timer as a 32-bit timer */ | ||
208 | for (i=0; i< ARRAY_SIZE(timers); i++) { | ||
209 | struct timer_s *t = &timers[i]; | ||
210 | |||
211 | if (t->name) { | ||
212 | t->id = i; | ||
213 | t->reg_base = (IS_TIMER1(t->id) ? | ||
214 | DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE); | ||
215 | |||
216 | if (IS_TIMER_BOT(t->id)) { | ||
217 | t->enamode_shift = 6; | ||
218 | t->tim_reg = t->reg_base + TIM12; | ||
219 | t->prd_reg = t->reg_base + PRD12; | ||
220 | } else { | ||
221 | t->enamode_shift = 22; | ||
222 | t->tim_reg = t->reg_base + TIM34; | ||
223 | t->prd_reg = t->reg_base + PRD34; | ||
224 | } | ||
225 | |||
226 | /* Register interrupt */ | ||
227 | t->irqaction.name = t->name; | ||
228 | t->irqaction.dev_id = (void *)t; | ||
229 | if (t->irqaction.handler != NULL) { | ||
230 | setup_irq(timer_irqs[t->id], &t->irqaction); | ||
231 | } | ||
232 | |||
233 | timer32_config(&timers[i]); | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * clocksource | ||
240 | */ | ||
241 | static cycle_t read_cycles(void) | ||
242 | { | ||
243 | struct timer_s *t = &timers[TID_CLOCKSOURCE]; | ||
244 | |||
245 | return (cycles_t)timer32_read(t); | ||
246 | } | ||
247 | |||
248 | static struct clocksource clocksource_davinci = { | ||
249 | .name = "timer0_1", | ||
250 | .rating = 300, | ||
251 | .read = read_cycles, | ||
252 | .mask = CLOCKSOURCE_MASK(32), | ||
253 | .shift = 24, | ||
254 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
255 | }; | ||
256 | |||
257 | /* | ||
258 | * clockevent | ||
259 | */ | ||
260 | static int davinci_set_next_event(unsigned long cycles, | ||
261 | struct clock_event_device *evt) | ||
262 | { | ||
263 | struct timer_s *t = &timers[TID_CLOCKEVENT]; | ||
264 | |||
265 | t->period = cycles; | ||
266 | timer32_config(t); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void davinci_set_mode(enum clock_event_mode mode, | ||
271 | struct clock_event_device *evt) | ||
272 | { | ||
273 | struct timer_s *t = &timers[TID_CLOCKEVENT]; | ||
274 | |||
275 | switch (mode) { | ||
276 | case CLOCK_EVT_MODE_PERIODIC: | ||
277 | t->period = CLOCK_TICK_RATE / (HZ); | ||
278 | t->opts = TIMER_OPTS_PERIODIC; | ||
279 | timer32_config(t); | ||
280 | break; | ||
281 | case CLOCK_EVT_MODE_ONESHOT: | ||
282 | t->opts = TIMER_OPTS_ONESHOT; | ||
283 | break; | ||
284 | case CLOCK_EVT_MODE_UNUSED: | ||
285 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
286 | t->opts = TIMER_OPTS_DISABLED; | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | static struct clock_event_device clockevent_davinci = { | ||
292 | .name = "timer0_0", | ||
293 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
294 | .shift = 32, | ||
295 | .set_next_event = davinci_set_next_event, | ||
296 | .set_mode = davinci_set_mode, | ||
297 | }; | ||
298 | |||
299 | |||
300 | static void __init davinci_timer_init(void) | ||
301 | { | ||
302 | static char err[] __initdata = KERN_ERR | ||
303 | "%s: can't register clocksource!\n"; | ||
304 | |||
305 | /* init timer hw */ | ||
306 | timer_init(); | ||
307 | |||
308 | /* setup clocksource */ | ||
309 | clocksource_davinci.mult = | ||
310 | clocksource_khz2mult(CLOCK_TICK_RATE/1000, | ||
311 | clocksource_davinci.shift); | ||
312 | if (clocksource_register(&clocksource_davinci)) | ||
313 | printk(err, clocksource_davinci.name); | ||
314 | |||
315 | /* setup clockevent */ | ||
316 | clockevent_davinci.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, | ||
317 | clockevent_davinci.shift); | ||
318 | clockevent_davinci.max_delta_ns = | ||
319 | clockevent_delta2ns(0xfffffffe, &clockevent_davinci); | ||
320 | clockevent_davinci.min_delta_ns = | ||
321 | clockevent_delta2ns(1, &clockevent_davinci); | ||
322 | |||
323 | clockevent_davinci.cpumask = cpumask_of_cpu(0); | ||
324 | clockevents_register_device(&clockevent_davinci); | ||
325 | } | ||
326 | |||
327 | struct sys_timer davinci_timer = { | ||
328 | .init = davinci_timer_init, | ||
329 | }; | ||
330 | |||
331 | |||
332 | /* reset board using watchdog timer */ | ||
333 | void davinci_watchdog_reset(void) { | ||
334 | u32 tgcr, wdtcr, base = DAVINCI_WDOG_BASE; | ||
335 | |||
336 | /* disable, internal clock source */ | ||
337 | davinci_writel(0, base + TCR); | ||
338 | |||
339 | /* reset timer, set mode to 64-bit watchdog, and unreset */ | ||
340 | tgcr = 0; | ||
341 | davinci_writel(tgcr, base + TCR); | ||
342 | tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT; | ||
343 | tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | | ||
344 | (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); | ||
345 | davinci_writel(tgcr, base + TCR); | ||
346 | |||
347 | /* clear counter and period regs */ | ||
348 | davinci_writel(0, base + TIM12); | ||
349 | davinci_writel(0, base + TIM34); | ||
350 | davinci_writel(0, base + PRD12); | ||
351 | davinci_writel(0, base + PRD34); | ||
352 | |||
353 | /* enable */ | ||
354 | wdtcr = davinci_readl(base + WDTCR); | ||
355 | wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT; | ||
356 | davinci_writel(wdtcr, base + WDTCR); | ||
357 | |||
358 | /* put watchdog in pre-active state */ | ||
359 | wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) | | ||
360 | (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); | ||
361 | davinci_writel(wdtcr, base + WDTCR); | ||
362 | |||
363 | /* put watchdog in active state */ | ||
364 | wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) | | ||
365 | (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); | ||
366 | davinci_writel(wdtcr, base + WDTCR); | ||
367 | |||
368 | /* write an invalid value to the WDKEY field to trigger | ||
369 | * a watchdog reset */ | ||
370 | wdtcr = 0x00004000; | ||
371 | davinci_writel(wdtcr, base + WDTCR); | ||
372 | } | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index b81391a4e374..2900e59395a5 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -171,8 +171,8 @@ config CPU_ARM925T | |||
171 | # ARM926T | 171 | # ARM926T |
172 | config CPU_ARM926T | 172 | config CPU_ARM926T |
173 | bool "Support ARM926T processor" | 173 | bool "Support ARM926T processor" |
174 | depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX | 174 | depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX || ARCH_DAVINCI |
175 | default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX | 175 | default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX || ARCH_DAVINCI |
176 | select CPU_32v5 | 176 | select CPU_32v5 |
177 | select CPU_ABRT_EV5TJ | 177 | select CPU_ABRT_EV5TJ |
178 | select CPU_CACHE_VIVT | 178 | select CPU_CACHE_VIVT |