diff options
Diffstat (limited to 'arch')
40 files changed, 1669 insertions, 2 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5ba00358e805..fdcd2d54e939 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -478,6 +478,8 @@ config ARCH_PXA | |||
478 | select HAVE_CLK | 478 | select HAVE_CLK |
479 | select COMMON_CLKDEV | 479 | select COMMON_CLKDEV |
480 | select ARCH_REQUIRE_GPIOLIB | 480 | select ARCH_REQUIRE_GPIOLIB |
481 | select HAVE_CLK | ||
482 | select COMMON_CLKDEV | ||
481 | select GENERIC_TIME | 483 | select GENERIC_TIME |
482 | select GENERIC_CLOCKEVENTS | 484 | select GENERIC_CLOCKEVENTS |
483 | select TICK_ONESHOT | 485 | select TICK_ONESHOT |
@@ -485,6 +487,18 @@ config ARCH_PXA | |||
485 | help | 487 | help |
486 | Support for Intel/Marvell's PXA2xx/PXA3xx processor line. | 488 | Support for Intel/Marvell's PXA2xx/PXA3xx processor line. |
487 | 489 | ||
490 | config ARCH_MMP | ||
491 | bool "Marvell PXA168" | ||
492 | depends on MMU | ||
493 | select HAVE_CLK | ||
494 | select COMMON_CLKDEV | ||
495 | select GENERIC_TIME | ||
496 | select GENERIC_CLOCKEVENTS | ||
497 | select TICK_ONESHOT | ||
498 | select PLAT_PXA | ||
499 | help | ||
500 | Support for Marvell's PXA168 processor line. | ||
501 | |||
488 | config ARCH_RPC | 502 | config ARCH_RPC |
489 | bool "RiscPC" | 503 | bool "RiscPC" |
490 | select ARCH_ACORN | 504 | select ARCH_ACORN |
@@ -621,6 +635,8 @@ source "arch/arm/mach-mv78xx0/Kconfig" | |||
621 | source "arch/arm/mach-pxa/Kconfig" | 635 | source "arch/arm/mach-pxa/Kconfig" |
622 | source "arch/arm/plat-pxa/Kconfig" | 636 | source "arch/arm/plat-pxa/Kconfig" |
623 | 637 | ||
638 | source "arch/arm/mach-mmp/Kconfig" | ||
639 | |||
624 | source "arch/arm/mach-sa1100/Kconfig" | 640 | source "arch/arm/mach-sa1100/Kconfig" |
625 | 641 | ||
626 | source "arch/arm/plat-omap/Kconfig" | 642 | source "arch/arm/plat-omap/Kconfig" |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 897f2830bc4d..95186ef17e17 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -109,6 +109,7 @@ ifeq ($(CONFIG_ARCH_SA1100),y) | |||
109 | textofs-$(CONFIG_SA1111) := 0x00208000 | 109 | textofs-$(CONFIG_SA1111) := 0x00208000 |
110 | endif | 110 | endif |
111 | machine-$(CONFIG_ARCH_PXA) := pxa | 111 | machine-$(CONFIG_ARCH_PXA) := pxa |
112 | machine-$(CONFIG_ARCH_MMP) := mmp | ||
112 | plat-$(CONFIG_PLAT_PXA) := pxa | 113 | plat-$(CONFIG_PLAT_PXA) := pxa |
113 | machine-$(CONFIG_ARCH_L7200) := l7200 | 114 | machine-$(CONFIG_ARCH_L7200) := l7200 |
114 | machine-$(CONFIG_ARCH_INTEGRATOR) := integrator | 115 | machine-$(CONFIG_ARCH_INTEGRATOR) := integrator |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index d1b678dc120b..d14b827adcd6 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -636,6 +636,18 @@ proc_types: | |||
636 | b __armv4_mmu_cache_off | 636 | b __armv4_mmu_cache_off |
637 | b __armv4_mmu_cache_flush | 637 | b __armv4_mmu_cache_flush |
638 | 638 | ||
639 | .word 0x56158000 @ PXA168 | ||
640 | .word 0xfffff000 | ||
641 | b __armv4_mmu_cache_on | ||
642 | b __armv4_mmu_cache_off | ||
643 | b __armv5tej_mmu_cache_flush | ||
644 | |||
645 | .word 0x56056930 | ||
646 | .word 0xff0ffff0 @ PXA935 | ||
647 | b __armv4_mmu_cache_on | ||
648 | b __armv4_mmu_cache_off | ||
649 | b __armv4_mmu_cache_flush | ||
650 | |||
639 | .word 0x56050000 @ Feroceon | 651 | .word 0x56050000 @ Feroceon |
640 | .word 0xff0f0000 | 652 | .word 0xff0f0000 |
641 | b __armv4_mmu_cache_on | 653 | b __armv4_mmu_cache_on |
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 6cbd8fdc9f1f..bfb0cb9aaa97 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -94,6 +94,14 @@ | |||
94 | # endif | 94 | # endif |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | #if defined(CONFIG_CPU_MOHAWK) | ||
98 | # ifdef _CACHE | ||
99 | # define MULTI_CACHE 1 | ||
100 | # else | ||
101 | # define _CACHE mohawk | ||
102 | # endif | ||
103 | #endif | ||
104 | |||
97 | #if defined(CONFIG_CPU_FEROCEON) | 105 | #if defined(CONFIG_CPU_FEROCEON) |
98 | # define MULTI_CACHE 1 | 106 | # define MULTI_CACHE 1 |
99 | #endif | 107 | #endif |
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index db80203b68e0..c6250311550b 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h | |||
@@ -185,6 +185,14 @@ | |||
185 | # define CPU_NAME cpu_xsc3 | 185 | # define CPU_NAME cpu_xsc3 |
186 | # endif | 186 | # endif |
187 | # endif | 187 | # endif |
188 | # ifdef CONFIG_CPU_MOHAWK | ||
189 | # ifdef CPU_NAME | ||
190 | # undef MULTI_CPU | ||
191 | # define MULTI_CPU | ||
192 | # else | ||
193 | # define CPU_NAME cpu_mohawk | ||
194 | # endif | ||
195 | # endif | ||
188 | # ifdef CONFIG_CPU_FEROCEON | 196 | # ifdef CONFIG_CPU_FEROCEON |
189 | # ifdef CPU_NAME | 197 | # ifdef CPU_NAME |
190 | # undef MULTI_CPU | 198 | # undef MULTI_CPU |
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig new file mode 100644 index 000000000000..b52326763556 --- /dev/null +++ b/arch/arm/mach-mmp/Kconfig | |||
@@ -0,0 +1,27 @@ | |||
1 | if ARCH_MMP | ||
2 | |||
3 | menu "Marvell PXA168 Implmentations" | ||
4 | |||
5 | config MACH_ASPENITE | ||
6 | bool "Marvell's PXA168 Aspenite Development Board" | ||
7 | select CPU_PXA168 | ||
8 | help | ||
9 | Say 'Y' here if you want to support the Marvell PXA168-based | ||
10 | Aspenite Development Board. | ||
11 | |||
12 | config MACH_ZYLONITE2 | ||
13 | bool "Marvell's PXA168 Zylonite2 Development Board" | ||
14 | select CPU_PXA168 | ||
15 | help | ||
16 | Say 'Y' here if you want to support the Marvell PXA168-based | ||
17 | Zylonite2 Development Board. | ||
18 | |||
19 | endmenu | ||
20 | |||
21 | config CPU_PXA168 | ||
22 | bool | ||
23 | select CPU_MOHAWK | ||
24 | help | ||
25 | Select code specific to PXA168 | ||
26 | |||
27 | endif | ||
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile new file mode 100644 index 000000000000..0ac7644ec99d --- /dev/null +++ b/arch/arm/mach-mmp/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | # | ||
2 | # Makefile for Marvell's PXA168 processors line | ||
3 | # | ||
4 | |||
5 | obj-y += common.o clock.o devices.o irq.o time.o | ||
6 | |||
7 | # SoC support | ||
8 | obj-$(CONFIG_CPU_PXA168) += pxa168.o | ||
9 | |||
10 | # board support | ||
11 | obj-$(CONFIG_MACH_ASPENITE) += aspenite.o | ||
12 | obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o | ||
diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot new file mode 100644 index 000000000000..574a4aa8321a --- /dev/null +++ b/arch/arm/mach-mmp/Makefile.boot | |||
@@ -0,0 +1 @@ | |||
zreladdr-y := 0x00008000 | |||
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c new file mode 100644 index 000000000000..e8caf58e004c --- /dev/null +++ b/arch/arm/mach-mmp/aspenite.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/aspenite.c | ||
3 | * | ||
4 | * Support for the Marvell PXA168-based Aspenite and Zylonite2 | ||
5 | * Development Platform. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * publishhed by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | |||
14 | #include <asm/mach-types.h> | ||
15 | #include <asm/mach/arch.h> | ||
16 | #include <mach/addr-map.h> | ||
17 | |||
18 | #include "common.h" | ||
19 | |||
20 | static void __init common_init(void) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") | ||
25 | .phys_io = APB_PHYS_BASE, | ||
26 | .boot_params = 0x00000100, | ||
27 | .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, | ||
28 | .map_io = pxa_map_io, | ||
29 | .init_irq = pxa168_init_irq, | ||
30 | .timer = &pxa168_timer, | ||
31 | .init_machine = common_init, | ||
32 | MACHINE_END | ||
33 | |||
34 | MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") | ||
35 | .phys_io = APB_PHYS_BASE, | ||
36 | .boot_params = 0x00000100, | ||
37 | .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, | ||
38 | .map_io = pxa_map_io, | ||
39 | .init_irq = pxa168_init_irq, | ||
40 | .timer = &pxa168_timer, | ||
41 | .init_machine = common_init, | ||
42 | MACHINE_END | ||
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c new file mode 100644 index 000000000000..2d9cc5a7122f --- /dev/null +++ b/arch/arm/mach-mmp/clock.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/clock.c | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/io.h> | ||
15 | |||
16 | #include <mach/regs-apbc.h> | ||
17 | #include "clock.h" | ||
18 | |||
19 | static void apbc_clk_enable(struct clk *clk) | ||
20 | { | ||
21 | uint32_t clk_rst; | ||
22 | |||
23 | clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel); | ||
24 | __raw_writel(clk_rst, clk->clk_rst); | ||
25 | } | ||
26 | |||
27 | static void apbc_clk_disable(struct clk *clk) | ||
28 | { | ||
29 | __raw_writel(0, clk->clk_rst); | ||
30 | } | ||
31 | |||
32 | struct clkops apbc_clk_ops = { | ||
33 | .enable = apbc_clk_enable, | ||
34 | .disable = apbc_clk_disable, | ||
35 | }; | ||
36 | |||
37 | static DEFINE_SPINLOCK(clocks_lock); | ||
38 | |||
39 | int clk_enable(struct clk *clk) | ||
40 | { | ||
41 | unsigned long flags; | ||
42 | |||
43 | spin_lock_irqsave(&clocks_lock, flags); | ||
44 | if (clk->enabled++ == 0) | ||
45 | clk->ops->enable(clk); | ||
46 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
47 | return 0; | ||
48 | } | ||
49 | EXPORT_SYMBOL(clk_enable); | ||
50 | |||
51 | void clk_disable(struct clk *clk) | ||
52 | { | ||
53 | unsigned long flags; | ||
54 | |||
55 | WARN_ON(clk->enabled == 0); | ||
56 | |||
57 | spin_lock_irqsave(&clocks_lock, flags); | ||
58 | if (--clk->enabled == 0) | ||
59 | clk->ops->disable(clk); | ||
60 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
61 | } | ||
62 | EXPORT_SYMBOL(clk_disable); | ||
63 | |||
64 | unsigned long clk_get_rate(struct clk *clk) | ||
65 | { | ||
66 | unsigned long rate; | ||
67 | |||
68 | if (clk->ops->getrate) | ||
69 | rate = clk->ops->getrate(clk); | ||
70 | else | ||
71 | rate = clk->rate; | ||
72 | |||
73 | return rate; | ||
74 | } | ||
75 | EXPORT_SYMBOL(clk_get_rate); | ||
76 | |||
77 | void clks_register(struct clk_lookup *clks, size_t num) | ||
78 | { | ||
79 | int i; | ||
80 | |||
81 | for (i = 0; i < num; i++) | ||
82 | clkdev_add(&clks[i]); | ||
83 | } | ||
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h new file mode 100644 index 000000000000..ed967e78e6a8 --- /dev/null +++ b/arch/arm/mach-mmp/clock.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/clock.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <asm/clkdev.h> | ||
10 | |||
11 | struct clkops { | ||
12 | void (*enable)(struct clk *); | ||
13 | void (*disable)(struct clk *); | ||
14 | unsigned long (*getrate)(struct clk *); | ||
15 | }; | ||
16 | |||
17 | struct clk { | ||
18 | const struct clkops *ops; | ||
19 | |||
20 | void __iomem *clk_rst; /* clock reset control register */ | ||
21 | int fnclksel; /* functional clock select (APBC) */ | ||
22 | uint32_t enable_val; /* value for clock enable (APMU) */ | ||
23 | unsigned long rate; | ||
24 | int enabled; | ||
25 | }; | ||
26 | |||
27 | extern struct clkops apbc_clk_ops; | ||
28 | |||
29 | #define APBC_CLK(_name, _reg, _fnclksel, _rate) \ | ||
30 | struct clk clk_##_name = { \ | ||
31 | .clk_rst = (void __iomem *)APBC_##_reg, \ | ||
32 | .fnclksel = _fnclksel, \ | ||
33 | .rate = _rate, \ | ||
34 | .ops = &apbc_clk_ops, \ | ||
35 | } | ||
36 | |||
37 | #define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops) \ | ||
38 | struct clk clk_##_name = { \ | ||
39 | .clk_rst = (void __iomem *)APBC_##_reg, \ | ||
40 | .fnclksel = _fnclksel, \ | ||
41 | .rate = _rate, \ | ||
42 | .ops = _ops, \ | ||
43 | } | ||
44 | |||
45 | #define APMU_CLK(_name, _reg, _eval, _rate) \ | ||
46 | struct clk clk_##_name = { \ | ||
47 | .clk_rst = (void __iomem *)APMU_##_reg, \ | ||
48 | .enable_val = _eval, \ | ||
49 | .rate = _rate, \ | ||
50 | .ops = &apmu_clk_ops, \ | ||
51 | } | ||
52 | |||
53 | #define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops) \ | ||
54 | struct clk clk_##_name = { \ | ||
55 | .clk_rst = (void __iomem *)APMU_##_reg, \ | ||
56 | .enable_val = _eval, \ | ||
57 | .rate = _rate, \ | ||
58 | .ops = _ops, \ | ||
59 | } | ||
60 | |||
61 | #define INIT_CLKREG(_clk, _devname, _conname) \ | ||
62 | { \ | ||
63 | .clk = _clk, \ | ||
64 | .dev_id = _devname, \ | ||
65 | .con_id = _conname, \ | ||
66 | } | ||
67 | |||
68 | extern struct clk clk_pxa168_gpio; | ||
69 | extern struct clk clk_pxa168_timers; | ||
70 | |||
71 | extern void clks_register(struct clk_lookup *, size_t); | ||
diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c new file mode 100644 index 000000000000..e1e66c18b446 --- /dev/null +++ b/arch/arm/mach-mmp/common.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/common.c | ||
3 | * | ||
4 | * Code common to PXA168 processor lines | ||
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/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | |||
14 | #include <asm/page.h> | ||
15 | #include <asm/mach/map.h> | ||
16 | #include <mach/addr-map.h> | ||
17 | |||
18 | #include "common.h" | ||
19 | |||
20 | static struct map_desc standard_io_desc[] __initdata = { | ||
21 | { | ||
22 | .pfn = __phys_to_pfn(APB_PHYS_BASE), | ||
23 | .virtual = APB_VIRT_BASE, | ||
24 | .length = APB_PHYS_SIZE, | ||
25 | .type = MT_DEVICE, | ||
26 | }, { | ||
27 | .pfn = __phys_to_pfn(AXI_PHYS_BASE), | ||
28 | .virtual = AXI_VIRT_BASE, | ||
29 | .length = AXI_PHYS_SIZE, | ||
30 | .type = MT_DEVICE, | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | void __init pxa_map_io(void) | ||
35 | { | ||
36 | iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); | ||
37 | } | ||
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h new file mode 100644 index 000000000000..bf7a6a492de6 --- /dev/null +++ b/arch/arm/mach-mmp/common.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | ||
2 | |||
3 | struct sys_timer; | ||
4 | |||
5 | extern void timer_init(int irq); | ||
6 | |||
7 | extern struct sys_timer pxa168_timer; | ||
8 | extern void __init pxa168_init_irq(void); | ||
9 | |||
10 | extern void __init icu_init_irq(void); | ||
11 | extern void __init pxa_map_io(void); | ||
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c new file mode 100644 index 000000000000..191d9dea8731 --- /dev/null +++ b/arch/arm/mach-mmp/devices.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/devices.c | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/dma-mapping.h> | ||
12 | |||
13 | #include <asm/irq.h> | ||
14 | #include <mach/devices.h> | ||
15 | |||
16 | int __init pxa_register_device(struct pxa_device_desc *desc, | ||
17 | void *data, size_t size) | ||
18 | { | ||
19 | struct platform_device *pdev; | ||
20 | struct resource res[2 + MAX_RESOURCE_DMA]; | ||
21 | int i, ret = 0, nres = 0; | ||
22 | |||
23 | pdev = platform_device_alloc(desc->drv_name, desc->id); | ||
24 | if (pdev == NULL) | ||
25 | return -ENOMEM; | ||
26 | |||
27 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
28 | |||
29 | memset(res, 0, sizeof(res)); | ||
30 | |||
31 | if (desc->start != -1ul && desc->size > 0) { | ||
32 | res[nres].start = desc->start; | ||
33 | res[nres].end = desc->start + desc->size - 1; | ||
34 | res[nres].flags = IORESOURCE_MEM; | ||
35 | nres++; | ||
36 | } | ||
37 | |||
38 | if (desc->irq != NO_IRQ) { | ||
39 | res[nres].start = desc->irq; | ||
40 | res[nres].end = desc->irq; | ||
41 | res[nres].flags = IORESOURCE_IRQ; | ||
42 | nres++; | ||
43 | } | ||
44 | |||
45 | for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) { | ||
46 | if (desc->dma[i] == 0) | ||
47 | break; | ||
48 | |||
49 | res[nres].start = desc->dma[i]; | ||
50 | res[nres].end = desc->dma[i]; | ||
51 | res[nres].flags = IORESOURCE_DMA; | ||
52 | } | ||
53 | |||
54 | ret = platform_device_add_resources(pdev, res, nres); | ||
55 | if (ret) { | ||
56 | platform_device_put(pdev); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | if (data && size) { | ||
61 | ret = platform_device_add_data(pdev, data, size); | ||
62 | if (ret) { | ||
63 | platform_device_put(pdev); | ||
64 | return ret; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | return platform_device_add(pdev); | ||
69 | } | ||
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h new file mode 100644 index 000000000000..3254089a644d --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/addr-map.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/addr-map.h | ||
3 | * | ||
4 | * Common address map definitions | ||
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 | #ifndef __ASM_MACH_ADDR_MAP_H | ||
12 | #define __ASM_MACH_ADDR_MAP_H | ||
13 | |||
14 | /* APB - Application Subsystem Peripheral Bus | ||
15 | * | ||
16 | * NOTE: the DMA controller registers are actually on the AXI fabric #1 | ||
17 | * slave port to AHB/APB bridge, due to its close relationship to those | ||
18 | * peripherals on APB, let's count it into the ABP mapping area. | ||
19 | */ | ||
20 | #define APB_PHYS_BASE 0xd4000000 | ||
21 | #define APB_VIRT_BASE 0xfe000000 | ||
22 | #define APB_PHYS_SIZE 0x00200000 | ||
23 | |||
24 | #define AXI_PHYS_BASE 0xd4200000 | ||
25 | #define AXI_VIRT_BASE 0xfe200000 | ||
26 | #define AXI_PHYS_SIZE 0x00200000 | ||
27 | |||
28 | /* Static Memory Controller - Chip Select 0 and 1 */ | ||
29 | #define SMC_CS0_PHYS_BASE 0x80000000 | ||
30 | #define SMC_CS0_PHYS_SIZE 0x10000000 | ||
31 | #define SMC_CS1_PHYS_BASE 0x90000000 | ||
32 | #define SMC_CS1_PHYS_SIZE 0x10000000 | ||
33 | |||
34 | #endif /* __ASM_MACH_ADDR_MAP_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/clkdev.h b/arch/arm/mach-mmp/include/mach/clkdev.h new file mode 100644 index 000000000000..2fb354e54e0d --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/clkdev.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_CLKDEV_H | ||
2 | #define __ASM_MACH_CLKDEV_H | ||
3 | |||
4 | #define __clk_get(clk) ({ 1; }) | ||
5 | #define __clk_put(clk) do { } while (0) | ||
6 | |||
7 | #endif /* __ASM_MACH_CLKDEV_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h new file mode 100644 index 000000000000..4ceed7a50755 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/cputype.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef __ASM_MACH_CPUTYPE_H | ||
2 | #define __ASM_MACH_CPUTYPE_H | ||
3 | |||
4 | #include <asm/cputype.h> | ||
5 | |||
6 | /* | ||
7 | * CPU Stepping OLD_ID CPU_ID CHIP_ID | ||
8 | * | ||
9 | * PXA168 A0 0x41159263 0x56158400 0x00A0A333 | ||
10 | */ | ||
11 | |||
12 | #ifdef CONFIG_CPU_PXA168 | ||
13 | # define __cpu_is_pxa168(id) \ | ||
14 | ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; }) | ||
15 | #else | ||
16 | # define __cpu_is_pxa168(id) (0) | ||
17 | #endif | ||
18 | |||
19 | #define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); }) | ||
20 | |||
21 | #endif /* __ASM_MACH_CPUTYPE_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/debug-macro.S b/arch/arm/mach-mmp/include/mach/debug-macro.S new file mode 100644 index 000000000000..a850f87de51d --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/debug-macro.S | |||
@@ -0,0 +1,23 @@ | |||
1 | /* arch/arm/mach-mmp/include/mach/debug-macro.S | ||
2 | * | ||
3 | * Debugging macro include header | ||
4 | * | ||
5 | * Copied from arch/arm/mach-pxa/include/mach/debug.S | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <mach/addr-map.h> | ||
13 | |||
14 | .macro addruart,rx | ||
15 | mrc p15, 0, \rx, c1, c0 | ||
16 | tst \rx, #1 @ MMU enabled? | ||
17 | ldreq \rx, =APB_PHYS_BASE @ physical | ||
18 | ldrne \rx, =APB_VIRT_BASE @ virtual | ||
19 | orr \rx, \rx, #0x00017000 | ||
20 | .endm | ||
21 | |||
22 | #define UART_SHIFT 2 | ||
23 | #include <asm/hardware/debug-8250.S> | ||
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/include/mach/devices.h new file mode 100644 index 000000000000..bc03388d5fde --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/devices.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #include <linux/types.h> | ||
2 | |||
3 | #define MAX_RESOURCE_DMA 2 | ||
4 | |||
5 | /* structure for describing the on-chip devices */ | ||
6 | struct pxa_device_desc { | ||
7 | const char *dev_name; | ||
8 | const char *drv_name; | ||
9 | int id; | ||
10 | int irq; | ||
11 | unsigned long start; | ||
12 | unsigned long size; | ||
13 | int dma[MAX_RESOURCE_DMA]; | ||
14 | }; | ||
15 | |||
16 | #define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \ | ||
17 | struct pxa_device_desc pxa168_device_##_name __initdata = { \ | ||
18 | .dev_name = "pxa168-" #_name, \ | ||
19 | .drv_name = _drv, \ | ||
20 | .id = _id, \ | ||
21 | .irq = IRQ_PXA168_##_irq, \ | ||
22 | .start = _start, \ | ||
23 | .size = _size, \ | ||
24 | .dma = { _dma }, \ | ||
25 | }; | ||
26 | |||
27 | extern int pxa_register_device(struct pxa_device_desc *, void *, size_t); | ||
diff --git a/arch/arm/mach-mmp/include/mach/dma.h b/arch/arm/mach-mmp/include/mach/dma.h new file mode 100644 index 000000000000..1d6914544da4 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/dma.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/dma.h | ||
3 | */ | ||
4 | |||
5 | #ifndef __ASM_MACH_DMA_H | ||
6 | #define __ASM_MACH_DMA_H | ||
7 | |||
8 | #include <mach/addr-map.h> | ||
9 | |||
10 | #define DMAC_REGS_VIRT (APB_VIRT_BASE + 0x00000) | ||
11 | |||
12 | #include <plat/dma.h> | ||
13 | #endif /* __ASM_MACH_DMA_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S new file mode 100644 index 000000000000..6d3cd35478b5 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/entry-macro.S | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <mach/regs-icu.h> | ||
10 | |||
11 | .macro disable_fiq | ||
12 | .endm | ||
13 | |||
14 | .macro arch_ret_to_user, tmp1, tmp2 | ||
15 | .endm | ||
16 | |||
17 | .macro get_irqnr_preamble, base, tmp | ||
18 | ldr \base, =ICU_AP_IRQ_SEL_INT_NUM | ||
19 | .endm | ||
20 | |||
21 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
22 | ldr \tmp, [\base, #0] | ||
23 | and \irqnr, \tmp, #0x3f | ||
24 | tst \tmp, #(1 << 6) | ||
25 | .endm | ||
diff --git a/arch/arm/mach-mmp/include/mach/hardware.h b/arch/arm/mach-mmp/include/mach/hardware.h new file mode 100644 index 000000000000..99264a5ce5e4 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/hardware.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef __ASM_MACH_HARDWARE_H | ||
2 | #define __ASM_MACH_HARDWARE_H | ||
3 | |||
4 | #endif /* __ASM_MACH_HARDWARE_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/io.h b/arch/arm/mach-mmp/include/mach/io.h new file mode 100644 index 000000000000..e7adf3d012c1 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/io.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/io.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_MACH_IO_H | ||
10 | #define __ASM_MACH_IO_H | ||
11 | |||
12 | #define IO_SPACE_LIMIT 0xffffffff | ||
13 | |||
14 | /* | ||
15 | * We don't actually have real ISA nor PCI buses, but there is so many | ||
16 | * drivers out there that might just work if we fake them... | ||
17 | */ | ||
18 | #define __io(a) __typesafe_io(a) | ||
19 | #define __mem_pci(a) (a) | ||
20 | |||
21 | #endif /* __ASM_MACH_IO_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h new file mode 100644 index 000000000000..91ecb3fbca06 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/irqs.h | |||
@@ -0,0 +1,58 @@ | |||
1 | #ifndef __ASM_MACH_IRQS_H | ||
2 | #define __ASM_MACH_IRQS_H | ||
3 | |||
4 | /* | ||
5 | * Interrupt numbers for PXA168 | ||
6 | */ | ||
7 | #define IRQ_PXA168_NONE (-1) | ||
8 | #define IRQ_PXA168_SSP3 0 | ||
9 | #define IRQ_PXA168_SSP2 1 | ||
10 | #define IRQ_PXA168_SSP1 2 | ||
11 | #define IRQ_PXA168_SSP0 3 | ||
12 | #define IRQ_PXA168_PMIC_INT 4 | ||
13 | #define IRQ_PXA168_RTC_INT 5 | ||
14 | #define IRQ_PXA168_RTC_ALARM 6 | ||
15 | #define IRQ_PXA168_TWSI0 7 | ||
16 | #define IRQ_PXA168_GPU 8 | ||
17 | #define IRQ_PXA168_KEYPAD 9 | ||
18 | #define IRQ_PXA168_ONEWIRE 12 | ||
19 | #define IRQ_PXA168_TIMER1 13 | ||
20 | #define IRQ_PXA168_TIMER2 14 | ||
21 | #define IRQ_PXA168_TIMER3 15 | ||
22 | #define IRQ_PXA168_CMU 16 | ||
23 | #define IRQ_PXA168_SSP4 17 | ||
24 | #define IRQ_PXA168_MSP_WAKEUP 19 | ||
25 | #define IRQ_PXA168_CF_WAKEUP 20 | ||
26 | #define IRQ_PXA168_XD_WAKEUP 21 | ||
27 | #define IRQ_PXA168_MFU 22 | ||
28 | #define IRQ_PXA168_MSP 23 | ||
29 | #define IRQ_PXA168_CF 24 | ||
30 | #define IRQ_PXA168_XD 25 | ||
31 | #define IRQ_PXA168_DDR_INT 26 | ||
32 | #define IRQ_PXA168_UART1 27 | ||
33 | #define IRQ_PXA168_UART2 28 | ||
34 | #define IRQ_PXA168_WDT 35 | ||
35 | #define IRQ_PXA168_FRQ_CHANGE 38 | ||
36 | #define IRQ_PXA168_SDH1 39 | ||
37 | #define IRQ_PXA168_SDH2 40 | ||
38 | #define IRQ_PXA168_LCD 41 | ||
39 | #define IRQ_PXA168_CI 42 | ||
40 | #define IRQ_PXA168_USB1 44 | ||
41 | #define IRQ_PXA168_NAND 45 | ||
42 | #define IRQ_PXA168_HIFI_DMA 46 | ||
43 | #define IRQ_PXA168_DMA_INT0 47 | ||
44 | #define IRQ_PXA168_DMA_INT1 48 | ||
45 | #define IRQ_PXA168_GPIOX 49 | ||
46 | #define IRQ_PXA168_USB2 51 | ||
47 | #define IRQ_PXA168_AC97 57 | ||
48 | #define IRQ_PXA168_TWSI1 58 | ||
49 | #define IRQ_PXA168_PMU 60 | ||
50 | #define IRQ_PXA168_SM_INT 63 | ||
51 | |||
52 | #define IRQ_GPIO_START 64 | ||
53 | #define IRQ_GPIO_NUM 128 | ||
54 | #define IRQ_GPIO(x) (IRQ_GPIO_START + (x)) | ||
55 | |||
56 | #define NR_IRQS (IRQ_GPIO_START + IRQ_GPIO_NUM) | ||
57 | |||
58 | #endif /* __ASM_MACH_IRQS_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h new file mode 100644 index 000000000000..bdb21d70714c --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/memory.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/memory.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_MACH_MEMORY_H | ||
10 | #define __ASM_MACH_MEMORY_H | ||
11 | |||
12 | #define PHYS_OFFSET UL(0x00000000) | ||
13 | |||
14 | #endif /* __ASM_MACH_MEMORY_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h new file mode 100644 index 000000000000..ef0a8a2076e9 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/pxa168.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef __ASM_MACH_PXA168_H | ||
2 | #define __ASM_MACH_PXA168_H | ||
3 | |||
4 | #include <mach/devices.h> | ||
5 | |||
6 | extern struct pxa_device_desc pxa168_device_uart1; | ||
7 | extern struct pxa_device_desc pxa168_device_uart2; | ||
8 | |||
9 | static inline int pxa168_add_uart(int id) | ||
10 | { | ||
11 | struct pxa_device_desc *d = NULL; | ||
12 | |||
13 | switch (id) { | ||
14 | case 1: d = &pxa168_device_uart1; break; | ||
15 | case 2: d = &pxa168_device_uart2; break; | ||
16 | } | ||
17 | |||
18 | if (d == NULL) | ||
19 | return -EINVAL; | ||
20 | |||
21 | return pxa_register_device(d, NULL, 0); | ||
22 | } | ||
23 | #endif /* __ASM_MACH_PXA168_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h new file mode 100644 index 000000000000..e0ffae594873 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/regs-apbc.h | ||
3 | * | ||
4 | * Application Peripheral Bus Clock Unit | ||
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 | #ifndef __ASM_MACH_REGS_APBC_H | ||
12 | #define __ASM_MACH_REGS_APBC_H | ||
13 | |||
14 | #include <mach/addr-map.h> | ||
15 | |||
16 | #define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000) | ||
17 | #define APBC_REG(x) (APBC_VIRT_BASE + (x)) | ||
18 | |||
19 | /* | ||
20 | * APB clock register offsets for PXA168 | ||
21 | */ | ||
22 | #define APBC_PXA168_UART1 APBC_REG(0x000) | ||
23 | #define APBC_PXA168_UART2 APBC_REG(0x004) | ||
24 | #define APBC_PXA168_GPIO APBC_REG(0x008) | ||
25 | #define APBC_PXA168_PWM0 APBC_REG(0x00c) | ||
26 | #define APBC_PXA168_PWM1 APBC_REG(0x010) | ||
27 | #define APBC_PXA168_SSP1 APBC_REG(0x01c) | ||
28 | #define APBC_PXA168_SSP2 APBC_REG(0x020) | ||
29 | #define APBC_PXA168_RTC APBC_REG(0x028) | ||
30 | #define APBC_PXA168_TWSI0 APBC_REG(0x02c) | ||
31 | #define APBC_PXA168_KPC APBC_REG(0x030) | ||
32 | #define APBC_PXA168_TIMERS APBC_REG(0x034) | ||
33 | #define APBC_PXA168_AIB APBC_REG(0x03c) | ||
34 | #define APBC_PXA168_SW_JTAG APBC_REG(0x040) | ||
35 | #define APBC_PXA168_ONEWIRE APBC_REG(0x048) | ||
36 | #define APBC_PXA168_SSP3 APBC_REG(0x04c) | ||
37 | #define APBC_PXA168_ASFAR APBC_REG(0x050) | ||
38 | #define APBC_PXA168_ASSAR APBC_REG(0x054) | ||
39 | #define APBC_PXA168_SSP4 APBC_REG(0x058) | ||
40 | #define APBC_PXA168_SSP5 APBC_REG(0x05c) | ||
41 | #define APBC_PXA168_TWSI1 APBC_REG(0x06c) | ||
42 | #define APBC_PXA168_UART3 APBC_REG(0x070) | ||
43 | #define APBC_PXA168_AC97 APBC_REG(0x084) | ||
44 | |||
45 | /* Common APB clock register bit definitions */ | ||
46 | #define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */ | ||
47 | #define APBC_FNCLK (1 << 1) /* Functional Clock Enable */ | ||
48 | #define APBC_RST (1 << 2) /* Reset Generation */ | ||
49 | |||
50 | /* Functional Clock Selection Mask */ | ||
51 | #define APBC_FNCLKSEL(x) (((x) & 0xf) << 4) | ||
52 | |||
53 | #endif /* __ASM_MACH_REGS_APBC_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h new file mode 100644 index 000000000000..919030514120 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/regs-apmu.h | ||
3 | * | ||
4 | * Application Subsystem Power Management Unit | ||
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 | #ifndef __ASM_MACH_REGS_APMU_H | ||
12 | #define __ASM_MACH_REGS_APMU_H | ||
13 | |||
14 | #include <mach/addr-map.h> | ||
15 | |||
16 | #define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800) | ||
17 | #define APMU_REG(x) (APMU_VIRT_BASE + (x)) | ||
18 | |||
19 | /* Clock Reset Control */ | ||
20 | #define APMU_IRE APMU_REG(0x048) | ||
21 | #define APMU_LCD APMU_REG(0x04c) | ||
22 | #define APMU_CCIC APMU_REG(0x050) | ||
23 | #define APMU_SDH0 APMU_REG(0x054) | ||
24 | #define APMU_SDH1 APMU_REG(0x058) | ||
25 | #define APMU_USB APMU_REG(0x05c) | ||
26 | #define APMU_NAND APMU_REG(0x060) | ||
27 | #define APMU_DMA APMU_REG(0x064) | ||
28 | #define APMU_GEU APMU_REG(0x068) | ||
29 | #define APMU_BUS APMU_REG(0x06c) | ||
30 | |||
31 | #define APMU_FNCLK_EN (1 << 4) | ||
32 | #define APMU_AXICLK_EN (1 << 3) | ||
33 | #define APMU_FNRST_DIS (1 << 1) | ||
34 | #define APMU_AXIRST_DIS (1 << 0) | ||
35 | |||
36 | #endif /* __ASM_MACH_REGS_APMU_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/regs-icu.h b/arch/arm/mach-mmp/include/mach/regs-icu.h new file mode 100644 index 000000000000..e5f08723e0cc --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-icu.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/regs-icu.h | ||
3 | * | ||
4 | * Interrupt Control Unit | ||
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 | #ifndef __ASM_MACH_ICU_H | ||
12 | #define __ASM_MACH_ICU_H | ||
13 | |||
14 | #include <mach/addr-map.h> | ||
15 | |||
16 | #define ICU_VIRT_BASE (AXI_VIRT_BASE + 0x82000) | ||
17 | #define ICU_REG(x) (ICU_VIRT_BASE + (x)) | ||
18 | |||
19 | #define ICU_INT_CONF(n) ICU_REG((n) << 2) | ||
20 | #define ICU_INT_CONF_AP_INT (1 << 6) | ||
21 | #define ICU_INT_CONF_CP_INT (1 << 5) | ||
22 | #define ICU_INT_CONF_IRQ (1 << 4) | ||
23 | #define ICU_INT_CONF_MASK (0xf) | ||
24 | |||
25 | #define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108) /* AP FIQ Selected Interrupt */ | ||
26 | #define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C) /* AP IRQ Selected Interrupt */ | ||
27 | #define ICU_AP_GBL_IRQ_MSK ICU_REG(0x114) /* AP Global Interrupt Mask */ | ||
28 | #define ICU_INT_STATUS_0 ICU_REG(0x128) /* Interrupt Stuats 0 */ | ||
29 | #define ICU_INT_STATUS_1 ICU_REG(0x12C) /* Interrupt Status 1 */ | ||
30 | |||
31 | #endif /* __ASM_MACH_ICU_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/regs-timers.h b/arch/arm/mach-mmp/include/mach/regs-timers.h new file mode 100644 index 000000000000..45589fec9fc7 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-timers.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/regs-timers.h | ||
3 | * | ||
4 | * Timers Module | ||
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 | #ifndef __ASM_MACH_REGS_TIMERS_H | ||
12 | #define __ASM_MACH_REGS_TIMERS_H | ||
13 | |||
14 | #include <mach/addr-map.h> | ||
15 | |||
16 | #define TIMERS1_VIRT_BASE (APB_VIRT_BASE + 0x14000) | ||
17 | #define TIMERS2_VIRT_BASE (APB_VIRT_BASE + 0x16000) | ||
18 | |||
19 | #define TMR_CCR (0x0000) | ||
20 | #define TMR_TN_MM(n, m) (0x0004 + ((n) << 3) + (((n) + (m)) << 2)) | ||
21 | #define TMR_CR(n) (0x0028 + ((n) << 2)) | ||
22 | #define TMR_SR(n) (0x0034 + ((n) << 2)) | ||
23 | #define TMR_IER(n) (0x0040 + ((n) << 2)) | ||
24 | #define TMR_PLVR(n) (0x004c + ((n) << 2)) | ||
25 | #define TMR_PLCR(n) (0x0058 + ((n) << 2)) | ||
26 | #define TMR_WMER (0x0064) | ||
27 | #define TMR_WMR (0x0068) | ||
28 | #define TMR_WVR (0x006c) | ||
29 | #define TMR_WSR (0x0070) | ||
30 | #define TMR_ICR(n) (0x0074 + ((n) << 2)) | ||
31 | #define TMR_WICR (0x0080) | ||
32 | #define TMR_CER (0x0084) | ||
33 | #define TMR_CMR (0x0088) | ||
34 | #define TMR_ILR(n) (0x008c + ((n) << 2)) | ||
35 | #define TMR_WCR (0x0098) | ||
36 | #define TMR_WFAR (0x009c) | ||
37 | #define TMR_WSAR (0x00A0) | ||
38 | #define TMR_CVWR(n) (0x00A4 + ((n) << 2)) | ||
39 | |||
40 | #define TMR_CCR_CS_0(x) (((x) & 0x3) << 0) | ||
41 | #define TMR_CCR_CS_1(x) (((x) & 0x7) << 2) | ||
42 | #define TMR_CCR_CS_2(x) (((x) & 0x3) << 5) | ||
43 | |||
44 | #endif /* __ASM_MACH_REGS_TIMERS_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h new file mode 100644 index 000000000000..001edfefec19 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/system.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/system.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_MACH_SYSTEM_H | ||
10 | #define __ASM_MACH_SYSTEM_H | ||
11 | |||
12 | static inline void arch_idle(void) | ||
13 | { | ||
14 | cpu_do_idle(); | ||
15 | } | ||
16 | |||
17 | static inline void arch_reset(char mode) | ||
18 | { | ||
19 | cpu_reset(0); | ||
20 | } | ||
21 | #endif /* __ASM_MACH_SYSTEM_H */ | ||
diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h new file mode 100644 index 000000000000..6cebbd0ca8f4 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/timex.h | |||
@@ -0,0 +1,9 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/timex.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #define CLOCK_TICK_RATE 3250000 | ||
diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h new file mode 100644 index 000000000000..c93d5fa5865c --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/uncompress.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-mmp/include/mach/uncompress.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/serial_reg.h> | ||
10 | #include <mach/addr-map.h> | ||
11 | |||
12 | #define UART1_BASE (APB_PHYS_BASE + 0x36000) | ||
13 | #define UART2_BASE (APB_PHYS_BASE + 0x17000) | ||
14 | #define UART3_BASE (APB_PHYS_BASE + 0x18000) | ||
15 | |||
16 | static inline void putc(char c) | ||
17 | { | ||
18 | volatile unsigned long *UART = (unsigned long *)UART2_BASE; | ||
19 | |||
20 | /* UART enabled? */ | ||
21 | if (!(UART[UART_IER] & UART_IER_UUE)) | ||
22 | return; | ||
23 | |||
24 | while (!(UART[UART_LSR] & UART_LSR_THRE)) | ||
25 | barrier(); | ||
26 | |||
27 | UART[UART_TX] = c; | ||
28 | } | ||
29 | |||
30 | /* | ||
31 | * This does not append a newline | ||
32 | */ | ||
33 | static inline void flush(void) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * nothing to do | ||
39 | */ | ||
40 | #define arch_decomp_setup() | ||
41 | #define arch_decomp_wdog() | ||
diff --git a/arch/arm/mach-mmp/include/mach/vmalloc.h b/arch/arm/mach-mmp/include/mach/vmalloc.h new file mode 100644 index 000000000000..b60ccaf9fee7 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/vmalloc.h | |||
@@ -0,0 +1,5 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/include/mach/vmalloc.h | ||
3 | */ | ||
4 | |||
5 | #define VMALLOC_END 0xfe000000 | ||
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c new file mode 100644 index 000000000000..52ff2f065eba --- /dev/null +++ b/arch/arm/mach-mmp/irq.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/irq.c | ||
3 | * | ||
4 | * Generic IRQ handling, GPIO IRQ demultiplexing, etc. | ||
5 | * | ||
6 | * Author: Bin Yang <bin.yang@marvell.com> | ||
7 | * Created: Sep 30, 2008 | ||
8 | * Copyright: Marvell International Ltd. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <mach/regs-icu.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | |||
23 | #define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ) | ||
24 | |||
25 | #define PRIORITY_DEFAULT 0x1 | ||
26 | #define PRIORITY_NONE 0x0 /* means IRQ disabled */ | ||
27 | |||
28 | static void icu_mask_irq(unsigned int irq) | ||
29 | { | ||
30 | __raw_writel(PRIORITY_NONE, ICU_INT_CONF(irq)); | ||
31 | } | ||
32 | |||
33 | static void icu_unmask_irq(unsigned int irq) | ||
34 | { | ||
35 | __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(irq)); | ||
36 | } | ||
37 | |||
38 | static struct irq_chip icu_irq_chip = { | ||
39 | .name = "icu_irq", | ||
40 | .ack = icu_mask_irq, | ||
41 | .mask = icu_mask_irq, | ||
42 | .unmask = icu_unmask_irq, | ||
43 | }; | ||
44 | |||
45 | void __init icu_init_irq(void) | ||
46 | { | ||
47 | int irq; | ||
48 | |||
49 | for (irq = 0; irq < 64; irq++) { | ||
50 | icu_mask_irq(irq); | ||
51 | set_irq_chip(irq, &icu_irq_chip); | ||
52 | set_irq_handler(irq, handle_level_irq); | ||
53 | set_irq_flags(irq, IRQF_VALID); | ||
54 | } | ||
55 | } | ||
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c new file mode 100644 index 000000000000..1935c7545117 --- /dev/null +++ b/arch/arm/mach-mmp/pxa168.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/pxa168.c | ||
3 | * | ||
4 | * Code specific to PXA168 | ||
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 | #include <linux/list.h> | ||
15 | #include <linux/clk.h> | ||
16 | |||
17 | #include <asm/mach/time.h> | ||
18 | #include <mach/addr-map.h> | ||
19 | #include <mach/cputype.h> | ||
20 | #include <mach/regs-apbc.h> | ||
21 | #include <mach/irqs.h> | ||
22 | #include <mach/dma.h> | ||
23 | #include <mach/devices.h> | ||
24 | |||
25 | #include "common.h" | ||
26 | #include "clock.h" | ||
27 | |||
28 | void __init pxa168_init_irq(void) | ||
29 | { | ||
30 | icu_init_irq(); | ||
31 | } | ||
32 | |||
33 | /* APB peripheral clocks */ | ||
34 | static APBC_CLK(uart1, PXA168_UART1, 1, 14745600); | ||
35 | static APBC_CLK(uart2, PXA168_UART2, 1, 14745600); | ||
36 | |||
37 | /* device and clock bindings */ | ||
38 | static struct clk_lookup pxa168_clkregs[] = { | ||
39 | INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL), | ||
40 | INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL), | ||
41 | }; | ||
42 | |||
43 | static int __init pxa168_init(void) | ||
44 | { | ||
45 | if (cpu_is_pxa168()) { | ||
46 | pxa_init_dma(IRQ_PXA168_DMA_INT0, 32); | ||
47 | clks_register(ARRAY_AND_SIZE(pxa168_clkregs)); | ||
48 | } | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | postcore_initcall(pxa168_init); | ||
53 | |||
54 | /* system timer - clock enabled, 3.25MHz */ | ||
55 | #define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3)) | ||
56 | |||
57 | static void __init pxa168_timer_init(void) | ||
58 | { | ||
59 | /* this is early, we have to initialize the CCU registers by | ||
60 | * ourselves instead of using clk_* API. Clock rate is defined | ||
61 | * by APBC_TIMERS_CLK_RST (3.25MHz) and enabled free-running | ||
62 | */ | ||
63 | __raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA168_TIMERS); | ||
64 | |||
65 | /* 3.25MHz, bus/functional clock enabled, release reset */ | ||
66 | __raw_writel(TIMER_CLK_RST, APBC_PXA168_TIMERS); | ||
67 | |||
68 | timer_init(IRQ_PXA168_TIMER1); | ||
69 | } | ||
70 | |||
71 | struct sys_timer pxa168_timer = { | ||
72 | .init = pxa168_timer_init, | ||
73 | }; | ||
74 | |||
75 | /* on-chip devices */ | ||
76 | PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22); | ||
77 | PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24); | ||
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c new file mode 100644 index 000000000000..b03a6eda7419 --- /dev/null +++ b/arch/arm/mach-mmp/time.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-mmp/time.c | ||
3 | * | ||
4 | * Support for clocksource and clockevents | ||
5 | * | ||
6 | * Copyright (C) 2008 Marvell International Ltd. | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * 2008-04-11: Jason Chagas <Jason.chagas@marvell.com> | ||
10 | * 2008-10-08: Bin Yang <bin.yang@marvell.com> | ||
11 | * | ||
12 | * The timers module actually includes three timers, each timer with upto | ||
13 | * three match comparators. Timer #0 is used here in free-running mode as | ||
14 | * the clock source, and match comparator #1 used as clock event device. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License version 2 as | ||
18 | * published by the Free Software Foundation. | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/clockchips.h> | ||
25 | |||
26 | #include <linux/io.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/cnt32_to_63.h> | ||
30 | |||
31 | #include <mach/addr-map.h> | ||
32 | #include <mach/regs-timers.h> | ||
33 | #include <mach/irqs.h> | ||
34 | |||
35 | #include "clock.h" | ||
36 | |||
37 | #define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE | ||
38 | |||
39 | #define MAX_DELTA (0xfffffffe) | ||
40 | #define MIN_DELTA (16) | ||
41 | |||
42 | #define TCR2NS_SCALE_FACTOR 10 | ||
43 | |||
44 | static unsigned long tcr2ns_scale; | ||
45 | |||
46 | static void __init set_tcr2ns_scale(unsigned long tcr_rate) | ||
47 | { | ||
48 | unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR; | ||
49 | do_div(v, tcr_rate); | ||
50 | tcr2ns_scale = v; | ||
51 | /* | ||
52 | * We want an even value to automatically clear the top bit | ||
53 | * returned by cnt32_to_63() without an additional run time | ||
54 | * instruction. So if the LSB is 1 then round it up. | ||
55 | */ | ||
56 | if (tcr2ns_scale & 1) | ||
57 | tcr2ns_scale++; | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * FIXME: the timer needs some delay to stablize the counter capture | ||
62 | */ | ||
63 | static inline uint32_t timer_read(void) | ||
64 | { | ||
65 | int delay = 100; | ||
66 | |||
67 | __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0)); | ||
68 | |||
69 | while (delay--) | ||
70 | cpu_relax(); | ||
71 | |||
72 | return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); | ||
73 | } | ||
74 | |||
75 | unsigned long long sched_clock(void) | ||
76 | { | ||
77 | unsigned long long v = cnt32_to_63(timer_read()); | ||
78 | return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR; | ||
79 | } | ||
80 | |||
81 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | ||
82 | { | ||
83 | struct clock_event_device *c = dev_id; | ||
84 | |||
85 | /* disable and clear pending interrupt status */ | ||
86 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); | ||
87 | __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0)); | ||
88 | c->event_handler(c); | ||
89 | return IRQ_HANDLED; | ||
90 | } | ||
91 | |||
92 | static int timer_set_next_event(unsigned long delta, | ||
93 | struct clock_event_device *dev) | ||
94 | { | ||
95 | unsigned long flags, next; | ||
96 | |||
97 | local_irq_save(flags); | ||
98 | |||
99 | /* clear pending interrupt status and enable */ | ||
100 | __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); | ||
101 | __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); | ||
102 | |||
103 | next = timer_read() + delta; | ||
104 | __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); | ||
105 | |||
106 | local_irq_restore(flags); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void timer_set_mode(enum clock_event_mode mode, | ||
111 | struct clock_event_device *dev) | ||
112 | { | ||
113 | unsigned long flags; | ||
114 | |||
115 | local_irq_save(flags); | ||
116 | switch (mode) { | ||
117 | case CLOCK_EVT_MODE_ONESHOT: | ||
118 | case CLOCK_EVT_MODE_UNUSED: | ||
119 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
120 | /* disable the matching interrupt */ | ||
121 | __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0)); | ||
122 | break; | ||
123 | case CLOCK_EVT_MODE_RESUME: | ||
124 | case CLOCK_EVT_MODE_PERIODIC: | ||
125 | break; | ||
126 | } | ||
127 | local_irq_restore(flags); | ||
128 | } | ||
129 | |||
130 | static struct clock_event_device ckevt = { | ||
131 | .name = "clockevent", | ||
132 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
133 | .shift = 32, | ||
134 | .rating = 200, | ||
135 | .set_next_event = timer_set_next_event, | ||
136 | .set_mode = timer_set_mode, | ||
137 | }; | ||
138 | |||
139 | static cycle_t clksrc_read(void) | ||
140 | { | ||
141 | return timer_read(); | ||
142 | } | ||
143 | |||
144 | static struct clocksource cksrc = { | ||
145 | .name = "clocksource", | ||
146 | .shift = 20, | ||
147 | .rating = 200, | ||
148 | .read = clksrc_read, | ||
149 | .mask = CLOCKSOURCE_MASK(32), | ||
150 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
151 | }; | ||
152 | |||
153 | static void __init timer_config(void) | ||
154 | { | ||
155 | uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); | ||
156 | uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER); | ||
157 | uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR); | ||
158 | |||
159 | __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ | ||
160 | |||
161 | ccr &= TMR_CCR_CS_0(0x3); | ||
162 | __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); | ||
163 | |||
164 | /* free-running mode */ | ||
165 | __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR); | ||
166 | |||
167 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */ | ||
168 | __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ | ||
169 | __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); | ||
170 | |||
171 | /* enable timer counter */ | ||
172 | __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER); | ||
173 | } | ||
174 | |||
175 | static struct irqaction timer_irq = { | ||
176 | .name = "timer", | ||
177 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
178 | .handler = timer_interrupt, | ||
179 | .dev_id = &ckevt, | ||
180 | }; | ||
181 | |||
182 | void __init timer_init(int irq) | ||
183 | { | ||
184 | timer_config(); | ||
185 | |||
186 | set_tcr2ns_scale(CLOCK_TICK_RATE); | ||
187 | |||
188 | ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); | ||
189 | ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); | ||
190 | ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt); | ||
191 | ckevt.cpumask = cpumask_of(0); | ||
192 | |||
193 | cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift); | ||
194 | |||
195 | setup_irq(irq, &timer_irq); | ||
196 | |||
197 | clocksource_register(&cksrc); | ||
198 | clockevents_register_device(&ckevt); | ||
199 | } | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index d490f3773c01..64086f4f5fcc 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -340,6 +340,17 @@ config CPU_XSC3 | |||
340 | select CPU_TLB_V4WBI if MMU | 340 | select CPU_TLB_V4WBI if MMU |
341 | select IO_36 | 341 | select IO_36 |
342 | 342 | ||
343 | # Marvell PJ1 (Mohawk) | ||
344 | config CPU_MOHAWK | ||
345 | bool | ||
346 | select CPU_32v5 | ||
347 | select CPU_ABRT_EV5T | ||
348 | select CPU_PABRT_NOIFAR | ||
349 | select CPU_CACHE_VIVT | ||
350 | select CPU_CP15_MMU | ||
351 | select CPU_TLB_V4WBI if MMU | ||
352 | select CPU_COPY_V4WB if MMU | ||
353 | |||
343 | # Feroceon | 354 | # Feroceon |
344 | config CPU_FEROCEON | 355 | config CPU_FEROCEON |
345 | bool | 356 | bool |
@@ -569,7 +580,7 @@ comment "Processor Features" | |||
569 | 580 | ||
570 | config ARM_THUMB | 581 | config ARM_THUMB |
571 | bool "Support Thumb user binaries" | 582 | bool "Support Thumb user binaries" |
572 | depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON | 583 | depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V7 || CPU_FEROCEON |
573 | default y | 584 | default y |
574 | help | 585 | help |
575 | Say Y if you want to include kernel support for running user space | 586 | Say Y if you want to include kernel support for running user space |
@@ -653,7 +664,7 @@ config CPU_CACHE_ROUND_ROBIN | |||
653 | 664 | ||
654 | config CPU_BPREDICT_DISABLE | 665 | config CPU_BPREDICT_DISABLE |
655 | bool "Disable branch prediction" | 666 | bool "Disable branch prediction" |
656 | depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 | 667 | depends on CPU_ARM1020 || CPU_V6 || CPU_MOHAWK || CPU_XSC3 || CPU_V7 |
657 | help | 668 | help |
658 | Say Y here to disable branch prediction. If unsure, say N. | 669 | Say Y here to disable branch prediction. If unsure, say N. |
659 | 670 | ||
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 480f78a3611a..64149d9e55a5 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -70,6 +70,7 @@ obj-$(CONFIG_CPU_SA110) += proc-sa110.o | |||
70 | obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o | 70 | obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o |
71 | obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o | 71 | obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o |
72 | obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o | 72 | obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o |
73 | obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk.o | ||
73 | obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o | 74 | obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o |
74 | obj-$(CONFIG_CPU_V6) += proc-v6.o | 75 | obj-$(CONFIG_CPU_V6) += proc-v6.o |
75 | obj-$(CONFIG_CPU_V7) += proc-v7.o | 76 | obj-$(CONFIG_CPU_V7) += proc-v7.o |
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S new file mode 100644 index 000000000000..540f5078496b --- /dev/null +++ b/arch/arm/mm/proc-mohawk.S | |||
@@ -0,0 +1,416 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core | ||
3 | * | ||
4 | * PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core. | ||
5 | * | ||
6 | * Heavily based on proc-arm926.S and proc-xsc3.S | ||
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 as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/linkage.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <asm/assembler.h> | ||
26 | #include <asm/hwcap.h> | ||
27 | #include <asm/pgtable-hwdef.h> | ||
28 | #include <asm/pgtable.h> | ||
29 | #include <asm/page.h> | ||
30 | #include <asm/ptrace.h> | ||
31 | #include "proc-macros.S" | ||
32 | |||
33 | /* | ||
34 | * This is the maximum size of an area which will be flushed. If the | ||
35 | * area is larger than this, then we flush the whole cache. | ||
36 | */ | ||
37 | #define CACHE_DLIMIT 32768 | ||
38 | |||
39 | /* | ||
40 | * The cache line size of the L1 D cache. | ||
41 | */ | ||
42 | #define CACHE_DLINESIZE 32 | ||
43 | |||
44 | /* | ||
45 | * cpu_mohawk_proc_init() | ||
46 | */ | ||
47 | ENTRY(cpu_mohawk_proc_init) | ||
48 | mov pc, lr | ||
49 | |||
50 | /* | ||
51 | * cpu_mohawk_proc_fin() | ||
52 | */ | ||
53 | ENTRY(cpu_mohawk_proc_fin) | ||
54 | stmfd sp!, {lr} | ||
55 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE | ||
56 | msr cpsr_c, ip | ||
57 | bl mohawk_flush_kern_cache_all | ||
58 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register | ||
59 | bic r0, r0, #0x1800 @ ...iz........... | ||
60 | bic r0, r0, #0x0006 @ .............ca. | ||
61 | mcr p15, 0, r0, c1, c0, 0 @ disable caches | ||
62 | ldmfd sp!, {pc} | ||
63 | |||
64 | /* | ||
65 | * cpu_mohawk_reset(loc) | ||
66 | * | ||
67 | * Perform a soft reset of the system. Put the CPU into the | ||
68 | * same state as it would be if it had been reset, and branch | ||
69 | * to what would be the reset vector. | ||
70 | * | ||
71 | * loc: location to jump to for soft reset | ||
72 | * | ||
73 | * (same as arm926) | ||
74 | */ | ||
75 | .align 5 | ||
76 | ENTRY(cpu_mohawk_reset) | ||
77 | mov ip, #0 | ||
78 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches | ||
79 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | ||
80 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | ||
81 | mrc p15, 0, ip, c1, c0, 0 @ ctrl register | ||
82 | bic ip, ip, #0x0007 @ .............cam | ||
83 | bic ip, ip, #0x1100 @ ...i...s........ | ||
84 | mcr p15, 0, ip, c1, c0, 0 @ ctrl register | ||
85 | mov pc, r0 | ||
86 | |||
87 | /* | ||
88 | * cpu_mohawk_do_idle() | ||
89 | * | ||
90 | * Called with IRQs disabled | ||
91 | */ | ||
92 | .align 5 | ||
93 | ENTRY(cpu_mohawk_do_idle) | ||
94 | mov r0, #0 | ||
95 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
96 | mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt | ||
97 | mov pc, lr | ||
98 | |||
99 | /* | ||
100 | * flush_user_cache_all() | ||
101 | * | ||
102 | * Clean and invalidate all cache entries in a particular | ||
103 | * address space. | ||
104 | */ | ||
105 | ENTRY(mohawk_flush_user_cache_all) | ||
106 | /* FALLTHROUGH */ | ||
107 | |||
108 | /* | ||
109 | * flush_kern_cache_all() | ||
110 | * | ||
111 | * Clean and invalidate the entire cache. | ||
112 | */ | ||
113 | ENTRY(mohawk_flush_kern_cache_all) | ||
114 | mov r2, #VM_EXEC | ||
115 | mov ip, #0 | ||
116 | __flush_whole_cache: | ||
117 | mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache | ||
118 | tst r2, #VM_EXEC | ||
119 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
120 | mcrne p15, 0, ip, c7, c10, 0 @ drain write buffer | ||
121 | mov pc, lr | ||
122 | |||
123 | /* | ||
124 | * flush_user_cache_range(start, end, flags) | ||
125 | * | ||
126 | * Clean and invalidate a range of cache entries in the | ||
127 | * specified address range. | ||
128 | * | ||
129 | * - start - start address (inclusive) | ||
130 | * - end - end address (exclusive) | ||
131 | * - flags - vm_flags describing address space | ||
132 | * | ||
133 | * (same as arm926) | ||
134 | */ | ||
135 | ENTRY(mohawk_flush_user_cache_range) | ||
136 | mov ip, #0 | ||
137 | sub r3, r1, r0 @ calculate total size | ||
138 | cmp r3, #CACHE_DLIMIT | ||
139 | bgt __flush_whole_cache | ||
140 | 1: tst r2, #VM_EXEC | ||
141 | mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry | ||
142 | mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry | ||
143 | add r0, r0, #CACHE_DLINESIZE | ||
144 | mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry | ||
145 | mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry | ||
146 | add r0, r0, #CACHE_DLINESIZE | ||
147 | cmp r0, r1 | ||
148 | blo 1b | ||
149 | tst r2, #VM_EXEC | ||
150 | mcrne p15, 0, ip, c7, c10, 4 @ drain WB | ||
151 | mov pc, lr | ||
152 | |||
153 | /* | ||
154 | * coherent_kern_range(start, end) | ||
155 | * | ||
156 | * Ensure coherency between the Icache and the Dcache in the | ||
157 | * region described by start, end. If you have non-snooping | ||
158 | * Harvard caches, you need to implement this function. | ||
159 | * | ||
160 | * - start - virtual start address | ||
161 | * - end - virtual end address | ||
162 | */ | ||
163 | ENTRY(mohawk_coherent_kern_range) | ||
164 | /* FALLTHROUGH */ | ||
165 | |||
166 | /* | ||
167 | * coherent_user_range(start, end) | ||
168 | * | ||
169 | * Ensure coherency between the Icache and the Dcache in the | ||
170 | * region described by start, end. If you have non-snooping | ||
171 | * Harvard caches, you need to implement this function. | ||
172 | * | ||
173 | * - start - virtual start address | ||
174 | * - end - virtual end address | ||
175 | * | ||
176 | * (same as arm926) | ||
177 | */ | ||
178 | ENTRY(mohawk_coherent_user_range) | ||
179 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
180 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
181 | mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry | ||
182 | add r0, r0, #CACHE_DLINESIZE | ||
183 | cmp r0, r1 | ||
184 | blo 1b | ||
185 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
186 | mov pc, lr | ||
187 | |||
188 | /* | ||
189 | * flush_kern_dcache_page(void *page) | ||
190 | * | ||
191 | * Ensure no D cache aliasing occurs, either with itself or | ||
192 | * the I cache | ||
193 | * | ||
194 | * - addr - page aligned address | ||
195 | */ | ||
196 | ENTRY(mohawk_flush_kern_dcache_page) | ||
197 | add r1, r0, #PAGE_SZ | ||
198 | 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry | ||
199 | add r0, r0, #CACHE_DLINESIZE | ||
200 | cmp r0, r1 | ||
201 | blo 1b | ||
202 | mov r0, #0 | ||
203 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
204 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
205 | mov pc, lr | ||
206 | |||
207 | /* | ||
208 | * dma_inv_range(start, end) | ||
209 | * | ||
210 | * Invalidate (discard) the specified virtual address range. | ||
211 | * May not write back any entries. If 'start' or 'end' | ||
212 | * are not cache line aligned, those lines must be written | ||
213 | * back. | ||
214 | * | ||
215 | * - start - virtual start address | ||
216 | * - end - virtual end address | ||
217 | * | ||
218 | * (same as v4wb) | ||
219 | */ | ||
220 | ENTRY(mohawk_dma_inv_range) | ||
221 | tst r0, #CACHE_DLINESIZE - 1 | ||
222 | mcrne p15, 0, r0, c7, c10, 1 @ clean D entry | ||
223 | tst r1, #CACHE_DLINESIZE - 1 | ||
224 | mcrne p15, 0, r1, c7, c10, 1 @ clean D entry | ||
225 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
226 | 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry | ||
227 | add r0, r0, #CACHE_DLINESIZE | ||
228 | cmp r0, r1 | ||
229 | blo 1b | ||
230 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
231 | mov pc, lr | ||
232 | |||
233 | /* | ||
234 | * dma_clean_range(start, end) | ||
235 | * | ||
236 | * Clean the specified virtual address range. | ||
237 | * | ||
238 | * - start - virtual start address | ||
239 | * - end - virtual end address | ||
240 | * | ||
241 | * (same as v4wb) | ||
242 | */ | ||
243 | ENTRY(mohawk_dma_clean_range) | ||
244 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
245 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
246 | add r0, r0, #CACHE_DLINESIZE | ||
247 | cmp r0, r1 | ||
248 | blo 1b | ||
249 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
250 | mov pc, lr | ||
251 | |||
252 | /* | ||
253 | * dma_flush_range(start, end) | ||
254 | * | ||
255 | * Clean and invalidate the specified virtual address range. | ||
256 | * | ||
257 | * - start - virtual start address | ||
258 | * - end - virtual end address | ||
259 | */ | ||
260 | ENTRY(mohawk_dma_flush_range) | ||
261 | bic r0, r0, #CACHE_DLINESIZE - 1 | ||
262 | 1: | ||
263 | mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry | ||
264 | add r0, r0, #CACHE_DLINESIZE | ||
265 | cmp r0, r1 | ||
266 | blo 1b | ||
267 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
268 | mov pc, lr | ||
269 | |||
270 | ENTRY(mohawk_cache_fns) | ||
271 | .long mohawk_flush_kern_cache_all | ||
272 | .long mohawk_flush_user_cache_all | ||
273 | .long mohawk_flush_user_cache_range | ||
274 | .long mohawk_coherent_kern_range | ||
275 | .long mohawk_coherent_user_range | ||
276 | .long mohawk_flush_kern_dcache_page | ||
277 | .long mohawk_dma_inv_range | ||
278 | .long mohawk_dma_clean_range | ||
279 | .long mohawk_dma_flush_range | ||
280 | |||
281 | ENTRY(cpu_mohawk_dcache_clean_area) | ||
282 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
283 | add r0, r0, #CACHE_DLINESIZE | ||
284 | subs r1, r1, #CACHE_DLINESIZE | ||
285 | bhi 1b | ||
286 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
287 | mov pc, lr | ||
288 | |||
289 | /* | ||
290 | * cpu_mohawk_switch_mm(pgd) | ||
291 | * | ||
292 | * Set the translation base pointer to be as described by pgd. | ||
293 | * | ||
294 | * pgd: new page tables | ||
295 | */ | ||
296 | .align 5 | ||
297 | ENTRY(cpu_mohawk_switch_mm) | ||
298 | mov ip, #0 | ||
299 | mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache | ||
300 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
301 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | ||
302 | orr r0, r0, #0x18 @ cache the page table in L2 | ||
303 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | ||
304 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | ||
305 | mov pc, lr | ||
306 | |||
307 | /* | ||
308 | * cpu_mohawk_set_pte_ext(ptep, pte, ext) | ||
309 | * | ||
310 | * Set a PTE and flush it out | ||
311 | */ | ||
312 | .align 5 | ||
313 | ENTRY(cpu_mohawk_set_pte_ext) | ||
314 | armv3_set_pte_ext | ||
315 | mov r0, r0 | ||
316 | mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
317 | mcr p15, 0, r0, c7, c10, 4 @ drain WB | ||
318 | mov pc, lr | ||
319 | |||
320 | __INIT | ||
321 | |||
322 | .type __mohawk_setup, #function | ||
323 | __mohawk_setup: | ||
324 | mov r0, #0 | ||
325 | mcr p15, 0, r0, c7, c7 @ invalidate I,D caches | ||
326 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | ||
327 | mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs | ||
328 | orr r4, r4, #0x18 @ cache the page table in L2 | ||
329 | mcr p15, 0, r4, c2, c0, 0 @ load page table pointer | ||
330 | |||
331 | mov r0, #0 @ don't allow CP access | ||
332 | mcr p15, 0, r0, c15, c1, 0 @ write CP access register | ||
333 | |||
334 | adr r5, mohawk_crval | ||
335 | ldmia r5, {r5, r6} | ||
336 | mrc p15, 0, r0, c1, c0 @ get control register | ||
337 | bic r0, r0, r5 | ||
338 | orr r0, r0, r6 | ||
339 | mov pc, lr | ||
340 | |||
341 | .size __mohawk_setup, . - __mohawk_setup | ||
342 | |||
343 | /* | ||
344 | * R | ||
345 | * .RVI ZFRS BLDP WCAM | ||
346 | * .011 1001 ..00 0101 | ||
347 | * | ||
348 | */ | ||
349 | .type mohawk_crval, #object | ||
350 | mohawk_crval: | ||
351 | crval clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134 | ||
352 | |||
353 | __INITDATA | ||
354 | |||
355 | /* | ||
356 | * Purpose : Function pointers used to access above functions - all calls | ||
357 | * come through these | ||
358 | */ | ||
359 | .type mohawk_processor_functions, #object | ||
360 | mohawk_processor_functions: | ||
361 | .word v5t_early_abort | ||
362 | .word pabort_noifar | ||
363 | .word cpu_mohawk_proc_init | ||
364 | .word cpu_mohawk_proc_fin | ||
365 | .word cpu_mohawk_reset | ||
366 | .word cpu_mohawk_do_idle | ||
367 | .word cpu_mohawk_dcache_clean_area | ||
368 | .word cpu_mohawk_switch_mm | ||
369 | .word cpu_mohawk_set_pte_ext | ||
370 | .size mohawk_processor_functions, . - mohawk_processor_functions | ||
371 | |||
372 | .section ".rodata" | ||
373 | |||
374 | .type cpu_arch_name, #object | ||
375 | cpu_arch_name: | ||
376 | .asciz "armv5te" | ||
377 | .size cpu_arch_name, . - cpu_arch_name | ||
378 | |||
379 | .type cpu_elf_name, #object | ||
380 | cpu_elf_name: | ||
381 | .asciz "v5" | ||
382 | .size cpu_elf_name, . - cpu_elf_name | ||
383 | |||
384 | .type cpu_mohawk_name, #object | ||
385 | cpu_mohawk_name: | ||
386 | .asciz "Marvell 88SV331x" | ||
387 | .size cpu_mohawk_name, . - cpu_mohawk_name | ||
388 | |||
389 | .align | ||
390 | |||
391 | .section ".proc.info.init", #alloc, #execinstr | ||
392 | |||
393 | .type __88sv331x_proc_info,#object | ||
394 | __88sv331x_proc_info: | ||
395 | .long 0x56158000 @ Marvell 88SV331x (MOHAWK) | ||
396 | .long 0xfffff000 | ||
397 | .long PMD_TYPE_SECT | \ | ||
398 | PMD_SECT_BUFFERABLE | \ | ||
399 | PMD_SECT_CACHEABLE | \ | ||
400 | PMD_BIT4 | \ | ||
401 | PMD_SECT_AP_WRITE | \ | ||
402 | PMD_SECT_AP_READ | ||
403 | .long PMD_TYPE_SECT | \ | ||
404 | PMD_BIT4 | \ | ||
405 | PMD_SECT_AP_WRITE | \ | ||
406 | PMD_SECT_AP_READ | ||
407 | b __mohawk_setup | ||
408 | .long cpu_arch_name | ||
409 | .long cpu_elf_name | ||
410 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | ||
411 | .long cpu_mohawk_name | ||
412 | .long mohawk_processor_functions | ||
413 | .long v4wbi_tlb_fns | ||
414 | .long v4wb_user_fns | ||
415 | .long mohawk_cache_fns | ||
416 | .size __88sv331x_proc_info, . - __88sv331x_proc_info | ||